Comparing version 0.4.2-alpha to 0.4.4
{ | ||
"name": "imvvm", | ||
"version": "0.4.2-alpha", | ||
"version": "0.4.4", | ||
"homepage": "https://github.com/entrendipity/imvvm", | ||
@@ -5,0 +5,0 @@ "authors": [ |
@@ -6,6 +6,5 @@ var fs = require('fs'); | ||
var browserify = require('browserify'); | ||
var b = browserify(); | ||
var b = browserify('./main.js'); | ||
var writer = fs.createWriteStream(path.normalize('dist/imvvm.js')); | ||
b.add('./main.js'); | ||
b.bundle({standalone:'IMVVM'}).pipe(writer); | ||
@@ -12,0 +11,0 @@ |
@@ -154,4 +154,4 @@ !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.IMVVM=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
thisAppState = new ApplicationDataContext(nextState, prevState, disableUndo); | ||
if(!!thisAppState.validateState && !rollback && !reprocessing) { | ||
var validationObj = thisAppState.validateState(thisAppState.state, thisAppState.previousState); | ||
if(!!thisAppState.getValidState && !rollback && !reprocessing) { | ||
var validationObj = thisAppState.getValidState(thisAppState.state, thisAppState.previousState); | ||
var validationKeys = Object.keys(validationObj); | ||
@@ -181,3 +181,3 @@ for (var keyIdx = validationKeys.length - 1; keyIdx >= 0; keyIdx--) { | ||
var applicationDataContext = new ApplicationDataContext({}, {}, disableUndo); | ||
domain = applicationDataContext.dataContexts(); | ||
domain = applicationDataContext.getDomainDataContext(); | ||
for(var dataContext in domain){ | ||
@@ -438,5 +438,5 @@ if(domain.hasOwnProperty(dataContext)){ | ||
//runs everytime | ||
if(desc.originalSpec.validateState){ | ||
if(desc.originalSpec.getValidState){ | ||
nextState = extend(nextState, | ||
desc.originalSpec.validateState.call(model, nextState, prevState)); | ||
desc.originalSpec.getValidState.call(model, nextState, prevState)); | ||
} | ||
@@ -543,5 +543,5 @@ | ||
//runs everytime | ||
if(desc.originalSpec.validateState){ | ||
if(desc.originalSpec.getValidState){ | ||
nextState = extend(nextState, | ||
desc.originalSpec.validateState.call(model, nextState, prevState)); | ||
desc.originalSpec.getValidState.call(model, nextState, prevState)); | ||
} | ||
@@ -642,3 +642,3 @@ | ||
if('calculated' in this.originalSpec[key]){ | ||
//default enumerable to true | ||
//We want to preserve the calculated flag on originalSpec | ||
descriptor[key] = utils.extend(this.originalSpec[key]); | ||
@@ -649,4 +649,10 @@ descriptor[key].enumerable = !this.originalSpec[key].calculated; | ||
} else if(!('enumerable' in this.originalSpec[key])){ | ||
//default enumerable to true | ||
this.originalSpec[key].enumerable = true; | ||
//No need to preserve the pseudo flag on originalSpec | ||
if('pseudo' in this.originalSpec[key]){ | ||
this.originalSpec[key].enumerable = !this.originalSpec[key].pseudo; | ||
delete this.originalSpec[key].pseudo; | ||
} else { | ||
//default enumerable to true | ||
this.originalSpec[key].enumerable = true; | ||
} | ||
descriptor[key] = this.originalSpec[key]; | ||
@@ -653,0 +659,0 @@ } else { |
@@ -1,1 +0,1 @@ | ||
!function(b){if("object"==typeof exports){module.exports=b()}else{if("function"==typeof define&&define.amd){define(b)}else{var a;"undefined"!=typeof window?a=window:"undefined"!=typeof global?a=global:"undefined"!=typeof self&&(a=self),a.IMVVM=b()}}}(function(){var d,b,a;return(function c(f,k,h){function g(n,l){if(!k[n]){if(!f[n]){var i=typeof require=="function"&&require;if(!l&&i){return i(n,!0)}if(e){return e(n,!0)}throw new Error("Cannot find module '"+n+"'")}var m=k[n]={exports:{}};f[n][0].call(m.exports,function(o){var p=f[n][1][o];return g(p?p:o)},m,m.exports,c,f,k,h)}return k[n].exports}var e=typeof require=="function"&&require;for(var j=0;j<h.length;j++){g(h[j])}return g})({1:[function(h,g,f){var e=h("./src/imvvm.js");g.exports=e},{"./src/imvvm.js":3}],2:[function(h,g,f){var e=h("./utils");var i=e.extend;f.getInitialState=function(k,p,u,y){if(typeof u!=="function"){throw new TypeError()}var x,w={},j={},v,n={},q,t=false;y===void (0)?false:y;var o=function(C,G,E){var H=false,F,B;G=G||{};if(C===void (0)){B=true;C={}}var D=function(J){var L={},K,I;if("dependsOn" in J){J.dependsOn.forEach(function(M){I={};K=M.property.split(".");K.forEach(function(O,N){if(N===0){I=C[O]}else{I=I?I[O]:void (0)}});if("alias" in M){L[M.alias]=I}else{L[K.join("$")]=I}})}return L};for(var A in q){if(q.hasOwnProperty(A)){F=D(q[A]);if(B){C[A]=new j[A](C[A],F,G[A]).getInitialState()}else{C[A]=new j[A](C[A],F,G[A])}if(E){if(H&&E.subscribers.indexOf(A)!==-1){F=D(q[E.name]);C[E.name]=new j[E.name](C[E.name],F,G[E.name])}H=H?H:A===E.name}}}return C};var m=function(C,E,M,I){var P={},L={},O=void (0),J,H,N,K=false;I===void (0)?false:I;if(!I&&(E===void (0)||E===null||Object.keys(E).length===0)){return}var G=!!E?Object.getPrototypeOf(E).constructor.classType==="DomainModel":false;if(G){P=i(E);L=E.previousState;K=true}else{if(C in n){J=Object.keys(E);H=J.length;N={};for(var F=0;F<H;F++){if(n[C][J[F]]){N[n[C][J[F]]]=true}}O={};O.name=C;O.subscribers=Object.keys(N);O=!!O.subscribers.length?O:void (0)}if(C!==k){P[C]=E;P=i(w.state,P)}else{if(I){P=i(o(),E)}else{P=i(w.state,E)}}L=t?w.previousState:w;P=o(P,w.state,O)}L=L||{};Object.freeze(L);w=new x(P,L,y);if(!!w.validateState&&!K&&!t){var B=w.validateState(w.state,w.previousState);var A=Object.keys(B);for(var D=A.length-1;D>=0;D--){if(Object.prototype.toString.call(B[A[D]])!=="[object Object]"&&Object.prototype.toString.call(B[A[D]])!=="[object Array]"&&B[A[D]]!==w.state[A[D]]){t=true;w.setState(i(w.state,B));t=false;break}}}if(!t){Object.freeze(w);Object.freeze(w.state);u(w,C,M);return w}};x=p.call(this,m.bind(this,k));var z=new x({},{},y);q=z.dataContexts();for(var l in q){if(q.hasOwnProperty(l)){j[l]=q[l].viewModel.call(this,m.bind(this,l));if("dependsOn" in q[l]){for(var r=0,s=q[l].dependsOn.length;r<s;r++){v=q[l].dependsOn[r].property.split(".");if(v.length>1){n[v[0]]=n[v[0]]||{};n[v[0]][v[1]]=n[v[0]][v[1]]||[];if(n[v[0]][v[1]].indexOf(l)===-1){n[v[0]][v[1]].push(l)}}}}}}return z.getInitialState()}},{"./utils":8}],3:[function(f,g,j){var k=f("./imvvmModel");var p=f("./imvvmViewModel");var i=f("./imvvmDomainModel");var r=f("./mixin");var q=f("./utils");var n=q.extend;var m=q.mixInto;var l=function(){};var h=function(){};var o=function(){};m(l,k.Mixin);m(h,p.Mixin);m(o,i.Mixin);var e={createClass:function(u,v,t){var y=function(){};y.prototype=new u();y.prototype.constructor=y;var x=y;var w=function(z){var A=new x();return A.construct.apply(w,arguments)};w.componentConstructor=y;y.ConvenienceConstructor=w;w.originalSpec=t;w.type=y;y.prototype.type=y;w.classType=v;y.prototype.classType=v;return w}};var s={createModel:e.createClass.bind(this,l,"Model"),createViewModel:e.createClass.bind(this,h,"ViewModel"),createDomainModel:e.createClass.bind(this,o,"DomainModel"),mixin:r};g.exports=s},{"./imvvmDomainModel":4,"./imvvmModel":5,"./imvvmViewModel":6,"./mixin":7,"./utils":8}],4:[function(j,h,f){var e=j("./utils");var k=e.extend;var g=e.getDescriptor;var i={Mixin:{construct:function(n){var o=g.call(this);o.proto.setState=n;var m=function(p,q){return o.proto.setState(p,q,true)};var l=function(t,v,p){var w;var u;t=t||{};v=v||{};if(!("getInitialState" in o.proto)){o.proto.getInitialState=function(){return m()}}else{w=o.proto.getInitialState;o.proto.getInitialState=function(){return m(w.call(this))}}var r=Object.create(o.proto,o.descriptor);Object.defineProperty(r,"state",{configurable:true,enumerable:false,writable:true,value:t});t=k(t,r);if(!!o.originalSpec.getInitialCalculatedState){for(var s=o.calculatedFields.length-1;s>=0;s--){if(!(o.calculatedFields[s] in t)||t[o.calculatedFields[s]]===void (0)){u={};u[o.calculatedFields[s]]=o.originalSpec.getInitialCalculatedState.call(r,t,v)[o.calculatedFields[s]];if(u[o.calculatedFields[s]]!==void (0)){t=k(t,u)}}}}if(!p&&!!Object.keys(v).length){Object.defineProperty(t,"previousState",{configurable:false,enumerable:false,writable:false,value:v})}Object.defineProperty(t,"state",{configurable:false,enumerable:false,writable:false,value:k(t)});for(var q in o.descriptor){if(o.descriptor.hasOwnProperty(q)){Object.defineProperty(t,q,o.descriptor[q])}}t.__proto__=r.__proto__;return t};return l}}};h.exports=i},{"./utils":8}],5:[function(i,h,f){var e=i("./utils");var k=e.extend;var g=e.getDescriptor;var j={Mixin:{construct:function(m){var n=g.call(this);var l=function(s,u,o){var p=Object.create(n.proto,n.descriptor);var v=arguments.length;var r=typeof Array.prototype.slice.call(arguments,-1)[0]==="boolean";var t;if(v===0){s={};u={};o=true}else{if(v===1){if(r){o=s;s={};u={}}else{u=s;o=true}}else{if(v===2){if(r){o=u;u=s}else{o=true}}}}s=("state" in s)?s.state:s;u=("state" in u)?u.state:u;Object.defineProperty(p,"state",{configurable:true,enumerable:false,writable:true,value:s});s=k(s,p);if(!!n.originalSpec.getInitialCalculatedState){for(var q=n.calculatedFields.length-1;q>=0;q--){if(!(n.calculatedFields[q] in s)||s[n.calculatedFields[q]]===void (0)){t={};t[n.calculatedFields[q]]=n.originalSpec.getInitialCalculatedState.call(p,s,u)[n.calculatedFields[q]];if(t[n.calculatedFields[q]]!==void (0)){s=k(s,t)}}}}if(n.originalSpec.validateState){s=k(s,n.originalSpec.validateState.call(p,s,u))}if(o){Object.defineProperty(p,"context",{configurable:true,enumerable:true,set:function(w){this.setState=function(x,y){return m.bind(w).call(w,k(this.state,x),this.state,y)}.bind(this);delete this.context}})}Object.defineProperty(p,"state",{configurable:false,enumerable:false,writable:false,value:s});Object.keys(p).forEach(function(w){if(Object.prototype.toString.call(this[w])==="[object Object]"||Object.prototype.toString.call(this[w])==="[object Array]"){Object.freeze(this[w])}}.bind(p));if(!o){Object.freeze(p)}return p};return l}}};h.exports=j},{"./utils":8}],6:[function(j,i,g){var f=j("./utils");var k=f.extend;var h=f.getDescriptor;var e={Mixin:{construct:function(m){var n=h.call(this);n.proto.setState=m;var l=function(q,r,u){var v;var t;q=k(q,r);u=u||{};u=("state" in u)?u.state:u;if(!("getInitialState" in n.proto)){n.proto.getInitialState=function(){return l()}}else{v=n.proto.getInitialState;n.proto.getInitialState=function(){return l(v.call(this))}}var o=Object.create(n.proto,n.descriptor);Object.defineProperty(o,"state",{configurable:true,enumerable:false,writable:true,value:q});q=k(q,o);if(!!n.originalSpec.getInitialCalculatedState){for(var p=n.calculatedFields.length-1;p>=0;p--){if(!(n.calculatedFields[p] in q)||q[n.calculatedFields[p]]===void (0)){t={};t[n.calculatedFields[p]]=n.originalSpec.getInitialCalculatedState.call(o,q,u)[n.calculatedFields[p]];if(t[n.calculatedFields[p]]!==void (0)){q=k(q,t)}}}}if(n.originalSpec.validateState){q=k(q,n.originalSpec.validateState.call(o,q,u))}Object.defineProperty(o,"state",{configurable:false,enumerable:false,writable:false,value:q});Object.keys(o).forEach(function(w){if(Object.prototype.toString.call(this[w])==="[object Object]"&&("context" in this[w])){this[w].context=this;Object.freeze(this[w])}else{if(Object.prototype.toString.call(this[w])==="[object Array]"){Object.freeze(this[w])}}}.bind(o));for(var s in r){if(r.hasOwnProperty(s)&&s[0]!=="_"){Object.defineProperty(o,s,{configurable:false,enumerable:false,writable:false,value:r[s]})}}Object.freeze(q);return Object.freeze(o)};return l}}};i.exports=e},{"./utils":8}],7:[function(j,i,h){var f=j("./core");var e="__IMVVM__";var g={stateChangedHandler:function(k,l,m){this.setState({applicationDataContext:k},function(){if(typeof m==="function"){if(this.state===null||!("applicationDataContext" in this.state)){m(void (0))}else{if(l in this.state.applicationDataContext){m(this.state.applicationDataContext[l])}else{if(l===e){m(this.state.applicationDataContext)}else{m(void (0))}}}}}.bind(this))},getInitialState:function(){var k=f.getInitialState(e,this.props.domainModel,this.stateChangedHandler,this.props.disableUndo);return{applicationDataContext:k}}};i.exports=g},{"./core":2}],8:[function(h,g,f){var e={getDescriptor:function(){var l={};var k=this.prototype;var i=[];for(var j in this.originalSpec){if(this.originalSpec.hasOwnProperty(j)){if("get" in this.originalSpec[j]||"set" in this.originalSpec[j]){if("calculated" in this.originalSpec[j]){l[j]=e.extend(this.originalSpec[j]);l[j].enumerable=!this.originalSpec[j].calculated;delete l[j].calculated;i.push(j)}else{if(!("enumerable" in this.originalSpec[j])){this.originalSpec[j].enumerable=true;l[j]=this.originalSpec[j]}else{l[j]=this.originalSpec[j]}}}else{k[j]=this.originalSpec[j]}}}if(!("extend" in k)){k.extend=e.extend}return{descriptor:l,proto:k,originalSpec:this.originalSpec||{},calculatedFields:i}},extend:function(){var j={};for(var l=0;l<arguments.length;l++){var m=arguments[l];for(var k in m){if(m.hasOwnProperty(k)){j[k]=m[k]}}}return j},mixInto:function(j,k){var i;for(i in k){if(!k.hasOwnProperty(i)){continue}j.prototype[i]=k[i]}}};g.exports=e},{}]},{},[1])(1)}); | ||
!function(b){if("object"==typeof exports){module.exports=b()}else{if("function"==typeof define&&define.amd){define(b)}else{var a;"undefined"!=typeof window?a=window:"undefined"!=typeof global?a=global:"undefined"!=typeof self&&(a=self),a.IMVVM=b()}}}(function(){var d,b,a;return(function c(f,k,h){function g(n,l){if(!k[n]){if(!f[n]){var i=typeof require=="function"&&require;if(!l&&i){return i(n,!0)}if(e){return e(n,!0)}throw new Error("Cannot find module '"+n+"'")}var m=k[n]={exports:{}};f[n][0].call(m.exports,function(o){var p=f[n][1][o];return g(p?p:o)},m,m.exports,c,f,k,h)}return k[n].exports}var e=typeof require=="function"&&require;for(var j=0;j<h.length;j++){g(h[j])}return g})({1:[function(h,g,f){var e=h("./src/imvvm.js");g.exports=e},{"./src/imvvm.js":3}],2:[function(h,g,f){var e=h("./utils");var i=e.extend;f.getInitialState=function(k,p,u,y){if(typeof u!=="function"){throw new TypeError()}var x,w={},j={},v,n={},q,t=false;y===void (0)?false:y;var o=function(C,G,E){var H=false,F,B;G=G||{};if(C===void (0)){B=true;C={}}var D=function(J){var L={},K,I;if("dependsOn" in J){J.dependsOn.forEach(function(M){I={};K=M.property.split(".");K.forEach(function(O,N){if(N===0){I=C[O]}else{I=I?I[O]:void (0)}});if("alias" in M){L[M.alias]=I}else{L[K.join("$")]=I}})}return L};for(var A in q){if(q.hasOwnProperty(A)){F=D(q[A]);if(B){C[A]=new j[A](C[A],F,G[A]).getInitialState()}else{C[A]=new j[A](C[A],F,G[A])}if(E){if(H&&E.subscribers.indexOf(A)!==-1){F=D(q[E.name]);C[E.name]=new j[E.name](C[E.name],F,G[E.name])}H=H?H:A===E.name}}}return C};var m=function(C,E,M,I){var P={},L={},O=void (0),J,H,N,K=false;I===void (0)?false:I;if(!I&&(E===void (0)||E===null||Object.keys(E).length===0)){return}var G=!!E?Object.getPrototypeOf(E).constructor.classType==="DomainModel":false;if(G){P=i(E);L=E.previousState;K=true}else{if(C in n){J=Object.keys(E);H=J.length;N={};for(var F=0;F<H;F++){if(n[C][J[F]]){N[n[C][J[F]]]=true}}O={};O.name=C;O.subscribers=Object.keys(N);O=!!O.subscribers.length?O:void (0)}if(C!==k){P[C]=E;P=i(w.state,P)}else{if(I){P=i(o(),E)}else{P=i(w.state,E)}}L=t?w.previousState:w;P=o(P,w.state,O)}L=L||{};Object.freeze(L);w=new x(P,L,y);if(!!w.getValidState&&!K&&!t){var B=w.getValidState(w.state,w.previousState);var A=Object.keys(B);for(var D=A.length-1;D>=0;D--){if(Object.prototype.toString.call(B[A[D]])!=="[object Object]"&&Object.prototype.toString.call(B[A[D]])!=="[object Array]"&&B[A[D]]!==w.state[A[D]]){t=true;w.setState(i(w.state,B));t=false;break}}}if(!t){Object.freeze(w);Object.freeze(w.state);u(w,C,M);return w}};x=p.call(this,m.bind(this,k));var z=new x({},{},y);q=z.getDomainDataContext();for(var l in q){if(q.hasOwnProperty(l)){j[l]=q[l].viewModel.call(this,m.bind(this,l));if("dependsOn" in q[l]){for(var r=0,s=q[l].dependsOn.length;r<s;r++){v=q[l].dependsOn[r].property.split(".");if(v.length>1){n[v[0]]=n[v[0]]||{};n[v[0]][v[1]]=n[v[0]][v[1]]||[];if(n[v[0]][v[1]].indexOf(l)===-1){n[v[0]][v[1]].push(l)}}}}}}return z.getInitialState()}},{"./utils":8}],3:[function(f,g,j){var k=f("./imvvmModel");var p=f("./imvvmViewModel");var i=f("./imvvmDomainModel");var r=f("./mixin");var q=f("./utils");var n=q.extend;var m=q.mixInto;var l=function(){};var h=function(){};var o=function(){};m(l,k.Mixin);m(h,p.Mixin);m(o,i.Mixin);var e={createClass:function(u,v,t){var y=function(){};y.prototype=new u();y.prototype.constructor=y;var x=y;var w=function(z){var A=new x();return A.construct.apply(w,arguments)};w.componentConstructor=y;y.ConvenienceConstructor=w;w.originalSpec=t;w.type=y;y.prototype.type=y;w.classType=v;y.prototype.classType=v;return w}};var s={createModel:e.createClass.bind(this,l,"Model"),createViewModel:e.createClass.bind(this,h,"ViewModel"),createDomainModel:e.createClass.bind(this,o,"DomainModel"),mixin:r};g.exports=s},{"./imvvmDomainModel":4,"./imvvmModel":5,"./imvvmViewModel":6,"./mixin":7,"./utils":8}],4:[function(j,h,f){var e=j("./utils");var k=e.extend;var g=e.getDescriptor;var i={Mixin:{construct:function(n){var o=g.call(this);o.proto.setState=n;var m=function(p,q){return o.proto.setState(p,q,true)};var l=function(t,v,p){var w;var u;t=t||{};v=v||{};if(!("getInitialState" in o.proto)){o.proto.getInitialState=function(){return m()}}else{w=o.proto.getInitialState;o.proto.getInitialState=function(){return m(w.call(this))}}var r=Object.create(o.proto,o.descriptor);Object.defineProperty(r,"state",{configurable:true,enumerable:false,writable:true,value:t});t=k(t,r);if(!!o.originalSpec.getInitialCalculatedState){for(var s=o.calculatedFields.length-1;s>=0;s--){if(!(o.calculatedFields[s] in t)||t[o.calculatedFields[s]]===void (0)){u={};u[o.calculatedFields[s]]=o.originalSpec.getInitialCalculatedState.call(r,t,v)[o.calculatedFields[s]];if(u[o.calculatedFields[s]]!==void (0)){t=k(t,u)}}}}if(!p&&!!Object.keys(v).length){Object.defineProperty(t,"previousState",{configurable:false,enumerable:false,writable:false,value:v})}Object.defineProperty(t,"state",{configurable:false,enumerable:false,writable:false,value:k(t)});for(var q in o.descriptor){if(o.descriptor.hasOwnProperty(q)){Object.defineProperty(t,q,o.descriptor[q])}}t.__proto__=r.__proto__;return t};return l}}};h.exports=i},{"./utils":8}],5:[function(i,h,f){var e=i("./utils");var k=e.extend;var g=e.getDescriptor;var j={Mixin:{construct:function(m){var n=g.call(this);var l=function(s,u,o){var p=Object.create(n.proto,n.descriptor);var v=arguments.length;var r=typeof Array.prototype.slice.call(arguments,-1)[0]==="boolean";var t;if(v===0){s={};u={};o=true}else{if(v===1){if(r){o=s;s={};u={}}else{u=s;o=true}}else{if(v===2){if(r){o=u;u=s}else{o=true}}}}s=("state" in s)?s.state:s;u=("state" in u)?u.state:u;Object.defineProperty(p,"state",{configurable:true,enumerable:false,writable:true,value:s});s=k(s,p);if(!!n.originalSpec.getInitialCalculatedState){for(var q=n.calculatedFields.length-1;q>=0;q--){if(!(n.calculatedFields[q] in s)||s[n.calculatedFields[q]]===void (0)){t={};t[n.calculatedFields[q]]=n.originalSpec.getInitialCalculatedState.call(p,s,u)[n.calculatedFields[q]];if(t[n.calculatedFields[q]]!==void (0)){s=k(s,t)}}}}if(n.originalSpec.getValidState){s=k(s,n.originalSpec.getValidState.call(p,s,u))}if(o){Object.defineProperty(p,"context",{configurable:true,enumerable:true,set:function(w){this.setState=function(x,y){return m.bind(w).call(w,k(this.state,x),this.state,y)}.bind(this);delete this.context}})}Object.defineProperty(p,"state",{configurable:false,enumerable:false,writable:false,value:s});Object.keys(p).forEach(function(w){if(Object.prototype.toString.call(this[w])==="[object Object]"||Object.prototype.toString.call(this[w])==="[object Array]"){Object.freeze(this[w])}}.bind(p));if(!o){Object.freeze(p)}return p};return l}}};h.exports=j},{"./utils":8}],6:[function(j,i,g){var f=j("./utils");var k=f.extend;var h=f.getDescriptor;var e={Mixin:{construct:function(m){var n=h.call(this);n.proto.setState=m;var l=function(q,r,u){var v;var t;q=k(q,r);u=u||{};u=("state" in u)?u.state:u;if(!("getInitialState" in n.proto)){n.proto.getInitialState=function(){return l()}}else{v=n.proto.getInitialState;n.proto.getInitialState=function(){return l(v.call(this))}}var o=Object.create(n.proto,n.descriptor);Object.defineProperty(o,"state",{configurable:true,enumerable:false,writable:true,value:q});q=k(q,o);if(!!n.originalSpec.getInitialCalculatedState){for(var p=n.calculatedFields.length-1;p>=0;p--){if(!(n.calculatedFields[p] in q)||q[n.calculatedFields[p]]===void (0)){t={};t[n.calculatedFields[p]]=n.originalSpec.getInitialCalculatedState.call(o,q,u)[n.calculatedFields[p]];if(t[n.calculatedFields[p]]!==void (0)){q=k(q,t)}}}}if(n.originalSpec.getValidState){q=k(q,n.originalSpec.getValidState.call(o,q,u))}Object.defineProperty(o,"state",{configurable:false,enumerable:false,writable:false,value:q});Object.keys(o).forEach(function(w){if(Object.prototype.toString.call(this[w])==="[object Object]"&&("context" in this[w])){this[w].context=this;Object.freeze(this[w])}else{if(Object.prototype.toString.call(this[w])==="[object Array]"){Object.freeze(this[w])}}}.bind(o));for(var s in r){if(r.hasOwnProperty(s)&&s[0]!=="_"){Object.defineProperty(o,s,{configurable:false,enumerable:false,writable:false,value:r[s]})}}Object.freeze(q);return Object.freeze(o)};return l}}};i.exports=e},{"./utils":8}],7:[function(j,i,h){var f=j("./core");var e="__IMVVM__";var g={stateChangedHandler:function(k,l,m){this.setState({applicationDataContext:k},function(){if(typeof m==="function"){if(this.state===null||!("applicationDataContext" in this.state)){m(void (0))}else{if(l in this.state.applicationDataContext){m(this.state.applicationDataContext[l])}else{if(l===e){m(this.state.applicationDataContext)}else{m(void (0))}}}}}.bind(this))},getInitialState:function(){var k=f.getInitialState(e,this.props.domainModel,this.stateChangedHandler,this.props.disableUndo);return{applicationDataContext:k}}};i.exports=g},{"./core":2}],8:[function(h,g,f){var e={getDescriptor:function(){var l={};var k=this.prototype;var i=[];for(var j in this.originalSpec){if(this.originalSpec.hasOwnProperty(j)){if("get" in this.originalSpec[j]||"set" in this.originalSpec[j]){if("calculated" in this.originalSpec[j]){l[j]=e.extend(this.originalSpec[j]);l[j].enumerable=!this.originalSpec[j].calculated;delete l[j].calculated;i.push(j)}else{if(!("enumerable" in this.originalSpec[j])){if("pseudo" in this.originalSpec[j]){this.originalSpec[j].enumerable=!this.originalSpec[j].pseudo;delete this.originalSpec[j].pseudo}else{this.originalSpec[j].enumerable=true}l[j]=this.originalSpec[j]}else{l[j]=this.originalSpec[j]}}}else{k[j]=this.originalSpec[j]}}}if(!("extend" in k)){k.extend=e.extend}return{descriptor:l,proto:k,originalSpec:this.originalSpec||{},calculatedFields:i}},extend:function(){var j={};for(var l=0;l<arguments.length;l++){var m=arguments[l];for(var k in m){if(m.hasOwnProperty(k)){j[k]=m[k]}}}return j},mixInto:function(j,k){var i;for(i in k){if(!k.hasOwnProperty(i)){continue}j.prototype[i]=k[i]}}};g.exports=e},{}]},{},[1])(1)}); |
@@ -63,3 +63,3 @@ /*jshint unused: vars */ | ||
//and alias with a preceding underscore i.e. alias: _busy | ||
dataContexts: function(){ | ||
getDomainDataContext: function(){ | ||
return { | ||
@@ -66,0 +66,0 @@ hobbies: { |
@@ -12,3 +12,2 @@ /** | ||
//initArgs is Optional - passed to AppViewModel init | ||
//noUndo is optional - default is false | ||
@@ -15,0 +14,0 @@ React.renderComponent(<ApplicationView |
@@ -75,5 +75,3 @@ /*jshint unused: false */ | ||
fullName: { | ||
enumerable: false, //calculated fields should set enumerable to false | ||
//calculated: true, //Only set this if you use getInitialCalculatedState | ||
//otherwise set enumerable to false - one or the other | ||
pseudo: true, | ||
get: function(){ | ||
@@ -80,0 +78,0 @@ if(this.lastName === void(0)){ |
@@ -35,3 +35,3 @@ /*jshint unused: false */ | ||
hobbies: { | ||
enumerable: false, //false because its not calculated but is supplied externally | ||
pseudo: true, //true because its not calculated but is supplied externally | ||
get: function(){ | ||
@@ -50,3 +50,3 @@ return this.state._selectedPerson.hobbies; | ||
busyText: { | ||
enumerable: false, //false because its not calculated but is supplied externally | ||
pseudo: true, //true because its not calculated but is supplied externally | ||
get: function(){ | ||
@@ -53,0 +53,0 @@ return this.state._busy ? 'Im Busy! Go away...' : 'Not doing too much.'; |
@@ -68,6 +68,6 @@ /*jshint unused: false */ | ||
personStateChangedHandler: function(nextState, prevState/*, callback*/){ | ||
personStateChangeHandler: function(nextState, prevState/*, callback*/){ | ||
var persons = {}; | ||
persons.collection = this.collection.map(function(person){ | ||
if(person.id === prevState.id){ | ||
if(person.id === nextState.id){ | ||
persons.selected = this.Person(nextState, person); | ||
@@ -82,3 +82,3 @@ return persons.selected; | ||
Person: function(){ | ||
return new PersonModel(this.personStateChangedHandler).apply(this, arguments); | ||
return new PersonModel(this.personStateChangeHandler).apply(this, arguments); | ||
}, | ||
@@ -85,0 +85,0 @@ |
@@ -25,3 +25,2 @@ /** | ||
render: function() { | ||
var app = this.props.appContext; | ||
var current = this.props.appContext.persons.selected; | ||
@@ -28,0 +27,0 @@ |
{ | ||
"name": "imvvm", | ||
"description": "Immutable MVVM for React", | ||
"version": "0.4.2-alpha", | ||
"version": "0.4.4", | ||
"keywords": [ | ||
@@ -6,0 +6,0 @@ "imvvm", |
480
README.md
@@ -5,4 +5,484 @@ IMVVM | ||
Immutable MVVM for React | ||
## Introduction | ||
## Usage | ||
IMVVM can be loaded as: | ||
- standalone. `IMVVM` is exposed as a global variable | ||
```javscript | ||
<script src="imvvm.min.js"></script> | ||
``` | ||
- a Node.js module | ||
``` | ||
$ npm install imvvm | ||
``` | ||
- a Bower module | ||
``` | ||
$ bower install imvvm | ||
``` | ||
- a RequireJS module | ||
``` | ||
require(['./imvvm.min.js'], function (IMVVM) { | ||
// Do something with IMVVM | ||
}); | ||
``` | ||
## Getting Started | ||
### Create a Model | ||
```javascript | ||
var PersonModel = IMVVM.createModel({ | ||
uuid: function () { | ||
var i, random; | ||
var uuid = ''; | ||
for (i = 0; i < 32; i++) { | ||
random = Math.random() * 16 | 0; | ||
if (i === 8 || i === 12 || i === 16 || i === 20) { | ||
uuid += '-'; | ||
} | ||
uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)) | ||
.toString(16); | ||
} | ||
return uuid; | ||
}, | ||
id: { | ||
get: function(){ | ||
return this.state.id ? this.state.id : this.uuid(); | ||
} | ||
}, | ||
name: { | ||
get: function(){ | ||
return this.state.firstName; | ||
}, | ||
set: function(newValue){ | ||
this.setState({'name': newValue}); | ||
} | ||
}, | ||
dob: { | ||
get: function(){ | ||
return this.state.dob; | ||
}, | ||
set: function(newValue){ | ||
this.setState({'dob': newValue}); | ||
} | ||
}, | ||
gender: { | ||
get: function(){ | ||
return this.state.gender; | ||
}, | ||
set: function(newValue){ | ||
this.setState({'gender': newValue}); | ||
} | ||
}, | ||
}); | ||
``` | ||
### Create a ViewModel | ||
```javascript | ||
var PersonsViewModel = IMVVM.createViewModel({ | ||
select: function(id){ | ||
var nextState = {}; | ||
nextState.collection = this.collection.map(function(person){ | ||
if(person.id === id){ | ||
nextState.selected = this.Person(person); | ||
return nextState.selected; | ||
} | ||
return person; | ||
}.bind(this)); | ||
this.setState(nextState); | ||
}, | ||
addPerson: function(value){ | ||
var nextState = {}; | ||
if(value && value.length > 0){ | ||
nextState.selected = this.Person({ | ||
name: value | ||
}); | ||
nextState.collection = this.collection.slice(0); | ||
nextState.collection = nextState.collection.concat(nextState.selected); | ||
this.setState(nextState); | ||
} | ||
}, | ||
deletePerson: function(uid){ | ||
var nextState = {}; | ||
nextState.collection = this.collection.filter(function(person){ | ||
return person.id !== uid; | ||
}); | ||
nextState.selected = void(0); | ||
if(nextState.collection.length > 0){ | ||
if (this.selected.id === uid){ | ||
nextState.selected = this.Person(nextState.collection[0]); | ||
} else { | ||
nextState.selected = this.Person(this.selected); | ||
} | ||
} | ||
this.setState(nextState); | ||
}, | ||
getInitialState: function(){ | ||
var nextState = {}; | ||
nextState.collection = DataService.getData().map(function(person, idx){ | ||
if (idx === 0){ | ||
nextState.selected = this.Person(person); | ||
return nextState.selected; | ||
} | ||
return this.Person(person, false); | ||
}.bind(this)); | ||
return nextState; | ||
}, | ||
personStateChangedHandler: function(nextState, prevState){ | ||
var persons = {}; | ||
persons.collection = this.collection.map(function(person){ | ||
if(person.id === nextState.id){ | ||
persons.selected = this.Person(nextState, person); | ||
return persons.selected; | ||
} | ||
return person; | ||
}.bind(this)); | ||
this.setState(persons); | ||
}, | ||
Person: function(){ | ||
return new PersonModel(this.personStateChangedHandler).apply(this, arguments); | ||
}, | ||
collection: { | ||
get: function(){ | ||
return this.state.collection; | ||
}, | ||
}, | ||
selected: { | ||
get: function() { | ||
return this.state.selected; | ||
} | ||
}, | ||
}); | ||
``` | ||
### Create a DomainModel | ||
```javascript | ||
var DomainModel = IMVVM.createDomainModel({ | ||
getInitialState: function(){ | ||
return { | ||
online: true | ||
}; | ||
}, | ||
undo: function(){ | ||
this.setState(this.previousState); | ||
}, | ||
online: { | ||
get: function(){ | ||
return this.state.online; | ||
}, | ||
set: function(newValue){ | ||
this.setState({'online': newValue }); | ||
} | ||
}, | ||
getDomainDataContext: function(){ | ||
return { | ||
persons: { | ||
viewModel: PersonsViewModel, | ||
dependsOn: [{property: 'online', alias: 'imOnline'}] | ||
} | ||
}; | ||
} | ||
}); | ||
``` | ||
### Hook up the View | ||
```javascript | ||
var ApplicationView = React.createClass({ | ||
mixins: [IMVVM.mixin], | ||
render: function(){ | ||
return ( | ||
<div> | ||
<NavBarView appContext={this.state.applicationDataContext} /> | ||
<SideBarView appContext={this.state.applicationDataContext} /> | ||
<DetailsView appContext={this.state.applicationDataContext} /> | ||
</div> | ||
); | ||
} | ||
}); | ||
``` | ||
### Render the View | ||
```javascript | ||
React.renderComponent(<ApplicationView domainModel={DomainModel}/>, document.getElementById('container')); | ||
``` | ||
__FormView example__ | ||
```javascript | ||
var FormView = React.createClass({ | ||
updateName: function(e){ | ||
this.props.appContext.persons.selected.name = e.target.value; | ||
}, | ||
updateGender: function(e){ | ||
this.props.appContext.persons.selected.gender = e.target.value; | ||
}, | ||
updateDOB: function(e){ | ||
this.props.appContext.persons.selected.dob = e.target.value; | ||
}, | ||
render: function() { | ||
var current = this.props.appContext.persons.selected; | ||
return ( | ||
<div key={current.id}> | ||
<form className="form-horizontal" role="form"> | ||
<div className="form-group"> | ||
<label className="col-md-2 control-label">Name</label> | ||
<div className="col-md-3"> | ||
<input className="form-control" type="text" value={current.name} | ||
onChange={this.updateName} /> | ||
</div> | ||
</div> | ||
<div className="form-group"> | ||
<label className="col-md-2 control-label">Gender</label> | ||
<div className="col-md-3"> | ||
<div className="radio"> | ||
<label> | ||
<input type="radio" onChange={this.updateGender} value="male" | ||
checked={current.gender === 'male'} /> | ||
Male | ||
</label> | ||
</div> | ||
<div className="radio"> | ||
<label> | ||
<input type="radio" onChange={this.updateGender} value="female" | ||
checked={current.gender === 'female'} /> | ||
Female | ||
</label> | ||
</div> | ||
</div> | ||
</div> | ||
<div className="form-group"> | ||
<label className="col-md-2 control-label">Birthday</label> | ||
<div className="col-md-3"> | ||
<input className="form-control" type="text" | ||
placeholder="yyyy-mm-dd" | ||
value={current.dob} | ||
onChange={this.updateDOB} /> | ||
</div> | ||
</div> | ||
</form> | ||
</div> | ||
); | ||
} | ||
}); | ||
``` | ||
##Running the example application | ||
The example application is a good starting place when figuring out how things work. So to get it running, navigate to the `./example` directory and run the following commands. | ||
``` | ||
$ npm install | ||
$ bower install | ||
$ grunt serve | ||
``` | ||
##API | ||
###Class | ||
####Constructors | ||
___ | ||
#####function createDomainModel(object specification) | ||
Creates a DomainModel object. | ||
*parameters* | ||
__specification__ - see [Specification](#specification) | ||
___ | ||
#####function createViewModel(object specification) | ||
Creates a ViewModel object. | ||
*parameters* | ||
__specification__ - see [Specification](#specification) | ||
___ | ||
#####function createModel(object specification) | ||
Creates a Model object. | ||
*parameters* | ||
__specification__ - see [Specification](#specification) | ||
###Instance | ||
####Functions | ||
___ | ||
#####void setState(object nextState[, function callback]) | ||
Transition Data Context to the next state. | ||
*parameters* | ||
__nextState__ | ||
__callback__ | ||
_Available in:_ DomainModel, ViewModel, Model | ||
___ | ||
#####object extend(object currentState[, object... nextState]) | ||
Creates a shallow copy of currentState. Adds/replaces properties with properties of subsequent objects. | ||
*parameters* | ||
__currentState__ | ||
__nextState__ | ||
_Available in:_ DomainModel, ViewModel, Model | ||
####Properties | ||
___ | ||
#####state | ||
_Available in:_ DomainModel, ViewModel, Model | ||
___ | ||
#####previousState | ||
_Available in:_ DomainModel | ||
###Specification | ||
####Hooks | ||
___ | ||
#####function getDomainDataContext() | ||
_Available in:_ DomainModel | ||
_Optional:_ false | ||
___ | ||
#####object getInitialState() | ||
_Available in:_ DomainModel, ViewModel | ||
_Optional:_ true | ||
___ | ||
#####object getInitialCalculatedState(object nextState, object previousState) | ||
*arguments* | ||
__nextState__ | ||
__previousState__ | ||
_Available in:_ DomainModel, ViewModel, Model | ||
_Optional:_ true | ||
___ | ||
#####object getValidState(object nextState, object previousState) | ||
*arguments* | ||
__nextState__ | ||
__previousState__ | ||
_Available in:_ DomainModel, ViewModel, Model | ||
_Optional:_ true | ||
####Field Descriptor | ||
___ | ||
#####\* get() | ||
#####void set(\* newValue) | ||
#####pseudo:boolean | ||
#####calculated:boolean | ||
_Available in:_ DomainModel, ViewModel, Model | ||
####DependsOn Properties | ||
___ | ||
***Public*** | ||
This will be made available to the View from this Data Context | ||
***Private*** | ||
Hidden from View from this Data Context | ||
_Available in:_ ViewModel | ||
####Model State Change Handlers | ||
___ | ||
#####void ModelStateChangeHandler(object nextState,object previousState[, function callback]) | ||
*arguments* | ||
__nextState__ | ||
__previousState__ | ||
__callback__ | ||
```javascript | ||
personStateChangeHandler: function(nextState, prevState){ | ||
var persons = {}; | ||
persons.collection = this.collection.map(function(person){ | ||
if(person.id === nextState.id){ | ||
persons.selected = this.Person(nextState, person); | ||
return persons.selected; | ||
} | ||
return person; | ||
}.bind(this)); | ||
this.setState(persons); | ||
} | ||
``` | ||
_Available in:_ ViewModel | ||
####Model Factory Functions | ||
___ | ||
_Definition_ | ||
#####function ModelFactory(){ return new ModelClass(this.ModelStateChangeHandler).apply(this, arguments); } | ||
_Usage_ | ||
#####object ModelFactory([object nextState, object previousState, boolean withContext]) | ||
#####object ModelFactory([object nextState, boolean withContext]) | ||
_Available in:_ ViewModel | ||
###Mixin | ||
####mixin | ||
___ | ||
mixins: [IMVVM.mixin], | ||
React.renderComponent(<ApplicationView | ||
domainModel={DomainModel} | ||
disableUndo={false} />, | ||
document.getElementById('container')); | ||
this.state.applicationDataContext | ||
## Browser Support | ||
Most ECMAScript 5 compliant browsers. | ||
__IE8 and below are not supported__ | ||
## Author | ||
Entrendipity - [Follow @entrendipity](https://twitter.com/intent/follow?screen_name=entrendipity) | ||
@@ -9,0 +489,0 @@ Frank Panetta - [Follow @fattenap](https://twitter.com/intent/follow?screen_name=fattenap) |
@@ -173,3 +173,3 @@ | ||
var applicationDataContext = new ApplicationDataContext({}, {}, disableUndo); | ||
domain = applicationDataContext.dataContexts(); | ||
domain = applicationDataContext.getDomainDataContext(); | ||
for(var dataContext in domain){ | ||
@@ -176,0 +176,0 @@ if(domain.hasOwnProperty(dataContext)){ |
@@ -14,3 +14,3 @@ | ||
if('calculated' in this.originalSpec[key]){ | ||
//default enumerable to true | ||
//We want to preserve the calculated flag on originalSpec | ||
descriptor[key] = utils.extend(this.originalSpec[key]); | ||
@@ -21,4 +21,10 @@ descriptor[key].enumerable = !this.originalSpec[key].calculated; | ||
} else if(!('enumerable' in this.originalSpec[key])){ | ||
//default enumerable to true | ||
this.originalSpec[key].enumerable = true; | ||
//No need to preserve the pseudo flag on originalSpec | ||
if('pseudo' in this.originalSpec[key]){ | ||
this.originalSpec[key].enumerable = !this.originalSpec[key].pseudo; | ||
delete this.originalSpec[key].pseudo; | ||
} else { | ||
//default enumerable to true | ||
this.originalSpec[key].enumerable = true; | ||
} | ||
descriptor[key] = this.originalSpec[key]; | ||
@@ -25,0 +31,0 @@ } else { |
148939
2369
499