On Github NicholasBoll / scheming-presentation
by Nicholas Boll
Scheming = require('Scheming') User = Scheming.create 'User', name : type : String required : true email : type : String, required : true validate : (val) -> if val.match('@') return true else return 'An email address must have an @ symbol!' birthday : Date password : type : String setter : (val) -> return md5(val) Group = Scheming.create 'Group', name : String dateCreated : {type : Date, default : -> Date.now()} users : [User] jane = new User email : 'jane.gmail.com' birthday : '9/14/86' password : 'p@$$w0rd!' console.log Person.validate jane # {name : 'Field is required.', email: 'An email address must have an @ symbol!'} jane.name = 'jane' jane.email = 'jane@gmail.com' console.log Person.validate jane # null
Car = Schema.create make : String model : String Person = Schema.create name : String car : Car mark = new Person {name : 'mark'} # Explicit construction and assignment # At the time of assignment, civic is already an instance of Car # so the Car constructor will not be invoked a second time civic = new Car {make : 'honda', model : 'civic'} mark.car = civic # Implicit construction # At the time of assignment, the value is a plain object. Therefore # the object is passed to the Car constructor (or in strict mode, # an error is thrown) mark.car = {make : 'toyota', model : 'corolla'} mark.car instanceof Car # true
Person = Scheming.create name : type : String validate : [ -> return "Error number one" -> throw new Error "Error number two" -> return true -> return false ] bill = new Person() errors = Person.validate bill # returns null, because bill object does not have a name defined, and name is not required bill.name = 'bill' errors = Person.validate bill # {name : ["Error number one", "Error number two", "Validation error occurred."]}
Person = Scheming.create 'Person', name : String age : Number mother : type: 'Schema:Person' default: {} # create implicit model - otherwise will default to undefined friends : ['Schema:Person'] lisa = new Person() # Sync changes are rolled up lisa.name = 'a' lisa.name = 'b' lisa.name = 'lisa' # Async change resolution lisa.watch 'name', (newVal, oldVal) -> # this listener is called once newVal == 'lisa' oldVal == undefined lisa.mother.name = 'jane' # Deep watch lisa.watch 'mother', (newVal, oldVal) -> newVal.name == 'jane' oldVal.name == undefined