Date post: | 22-Nov-2014 |
Category: |
Engineering |
Upload: | nomocas |
View: | 166 times |
Download: | 2 times |
oĹĻõõàįŦõĩĹh�ĻĻ�ĩĹĒĩõºĩTççËî»Ĺp
TŇĻÇõĩĹ�ĹºËàà�įĹvõõçTîį
v 0.13.1
ÇĻĻĒį�ĸĸºËĻÇŇhęvõèĸ���ĒÙį
deepMƖ
GHHSMƖ7 Generic Design Tools
FRUĠ�� generic design solutionsGHHSMƖ�IUDPHZRUś���7DUJHWƖ
design :objects, functions, classes, async and concurrent run time, transformations, roles,resources,constraints, isomorphism,modularity,...
views
controllers and directives
DOM
restful
homogeneous collections
RQL
JSON-Schema & ...
CRUD, range, RPC, bulk
routes
dynamic routing
sub controllers
IOC on map
LVRPRUSKLFƖ�� write once, run everywhere
...
shell
CLI tools
sh/sshnodejs process
autobahn
Thin Server
restful services
statics files
login/session pattern
browser
Browser App
deep-link
login/session pattern
HQYLURQQHPHQWƖ�� where to run ?
...
GHHSMƖ�IUDPHZRUś
Isomorphic : Environnement independent libs
deepjs core tools : design
deep-restful homogeneous restful collectionsdeep-views views & directivesdeep-routes dynamic routingdeep-jquery (dom) dom manipulation (jquery/cheerio)deep-marked markdown with macros + clients (nodejs + jq-ajax)deep-swig swigjs template clients (nodejs + jq-ajax)
/LEUDULHƖ
you create with this (and more...)
you use with this (and more...)
Nodejs specific libs
autobahnjs restful thin server : middlewares (expressjs) + routesdeep-shell sh & ssh chains and clideep-nodejs nodejs related tools (restful fs, ...)deep-mongo restful mongodb clientdeep-elastic restful elastic-search client, index, layered queries...
Browser specific libs
deep-browser browser app environnementdeep-local-storage restful local storage storedeep-jquery (ajax) restful ajax clients (json, html, xml)
Misc
deep-air Adobe air adapted browser env.deep-node-webkit node-webkit mixed browser/nodejs env.
To finally do what ?
fits well for :
GHHSMƖ IUDPHZRUś
VLQJOĠ�SDJĠ�DSS���UHVWĽŝ�DSŋ- views structure and resources + routes mapping
- templating- restful stores : JSON-Schema, constraints and API
- roles and context design- login decoration pattern
and/or
ZRUNHUƖ6LQJOĠ�3DJĠ�DSS
��Ţ9&��5HVWĽŝ�êLŨ�6HUYHU
��0RGHŝ��Restful/HTTP/JSON
. service oriented
3DXVĠ%UHDWKĠ�ö�OLWWOĠ�ELƜ�
)RUJHƜ�DUFKLWHFWXUĠ�
êLQś�FRGĠ�GHVLJŨ�
KRZ�WŬ�PDNĠ�WKLQJƖ��
- iterable friendly- async friendly
- concurrency friendly- transformations friendly
- roles friendly- highly modular
- reusable- ...
7 JHQHULĊ�GHVLJŨ�WRROƖ�IDPLOOLHƖGHHSMƖFRUĠ
OD\HUƖ inheritance & specialisation : objects on objects
deep({ /* ... */ }).bottom(model1, ...).up(aspect1, “json::/my/file”, ...).flatten().done(...)...
TXHULHƖ (fuzzy) ask before use : jquery paradigm for code
deep({ /* ... */ }).query(“./(foo.*)?bar=gt=4/zoo”).up(...).run(...).map().done(...)...
VKHHWƖ super aspects & transformations rules : css paradigm for code
deep({ /* ... */ }).sheet({ “dq::./foo”:deep.sheet.bottom(...).map(...)... }).done(...)...land
scap
e pr
ogra
mm
ing
FKDLQƖ (async) run time management : super promises
deep.when(...).toState(”myVar”).fs(”../folder”).from(”myFile.json”)...log()...
SURWRFROƖ asbtract resource locator : resource says...
deep(”products.range(10,19)::?my_rql_query”).map(”swig::/my/templ.htm”).done(...)...
FRQWġƜ gift for concurrency : simply ask
deep.contextualise({ req:request )})....done(function(s){ deep.context(”req”).write(s); })...
RFŢ object capability manager : object’s nature depends on observer
deep.modes({ roles:”admin” }).rest(”myStore”).put(”my new title”, “id/title”).done(...)...
ODQGVFDSĠ�RULHQWHĘ�SURJUDPPLQŁ����
whole app, module,
config,datas,
classes,controllers,
routes map,aspects,
transformations,elastic search queries,
whole 3D scene,...
models,other landscapes,
...
specialisations,aspects,transformations,other landscapes,...
up & bottom, objects on objects, queriable joint points,deep merge, compositions for functions, colliders for datas,
transformations-in-place
deep({ /* ... */ }).bottom(model1, ...).query(“./(foo.*)?bar=gt=4/zoo”).up(aspect1, “js::/my/file”, ...).flatten().done(...)...
methods, primitives, array, subobjects
myBool :myBool :myVar : hello
src
{
} myVar : hello
target
{
}
truetrue
target
{
}
up
No collision :
myVar : hello
src
{
}myVar : hello
target
{
}myVar : true
target
{
}
up
With collision :
upspecialisation
ODQGVFDSĠ�RULHQWHĘ�SURJUDPPLQŁ������default up & bottom rules : when collision, what is above is kept
myVar : hello
src
{
}myVar : hello
target
{
}true
true
target
{
}
bottom
No collision :
myVar : hello
src
{
}
target
{
}myVar : truemyVar : true
target
{
}
bottom
With collision :
ERWWRŢinheritance
myBool :myBool :
deep({ a:true }).bottom({ a:false, b:false }).up({ b:true, c:true }, { d:false }).log(); // { a:true, b:true, c:true, d:false }
ODQGVFDSĠ�RULHQWHĘ�SURJUDPPLQŁ������
{ arr:[”peer”, ”citrus”], arr2:[ { id:”e1”, title:”hello” }, { id:”e2”, title:”world” } ],
subobj:{ foo: false, foobar: 12 },
myFunc: function(){ /*...*/ },
zoo: ”landscape forever”}
{ arr:[”peer”, ”citrus”, ”apple” ], arr2:[ { id:”e1”, title:”hello” }, { id:”e2”, title:”deepjs” }, { id:”e3”, title:”tools” } ],
subobj:{ foo: true, foobar: 12, bar: false }, myFunc: Function,
zoo: ”landscapeForever”}
{ arr:[”apple”, ”peer”], arr2:[ { id:”e2”, title:”deepjs” }, { id:”e3”, title:”tools” } ],
subobj:{ foo: true, bar: false },
myFunc: deep.compose .after(function(r){ /*...*/ }) .around(function(old){ /*...*/ }),
zoo: deep.collider.changeCase(”camel”)}
src target targetup
natural deep merge & fine grained merge tools
objects (including arrays) are (recursively) merged.
arrays merge try to be smart.
primitives properties (tree leafs) collisions follow default rule : above is kept.
compositions allow fine grained functions merge (after, before, around, fail and custom API + chainable).
colliders allow fine grained merge and/or “while-collision” logics (chainable).
ODQGVFDSĠ�RULHQWHĘ�SURJUDPPLQŁ�(4/5)when queries give control
deep-query, Resource Query Language, traversal, ...
deep({ /* ... */ }).query(”./(foo.*)?bar=gt=4/zoo”).up(...).run(...).query(...).map()...
queries allow jquery style logics
var mySheet= { “dq::/my/query” : deep.sheet.up(...).map(...).query(...)..., “dq::/my/other/query” : deep.sheet.bottom(...).sheet(...)..., //...};
deep( { /*...*/ } ).sheet( mySheet ).done(...);
sheets are super aspects and/or transformations units (css style)
ODQGVFDSĠ�RULHQWHĘ�SURJUDPPLQŁ�(5/5)in-object landscapes declaration : backgrounds & foregrounds
var myOtherObject = {
_backgrounds:[ ... ], //...
};
var myObj = {
_backgrounds:[ myOtherObj, ”json::/a/json/src” ],
//...
subobj:{
_foregrounds:[ ”js::/a/js/src”, mySheet ],
//...
sub_subobj:{
_backgrounds:[ ”this::../my_brother” ],
_foregrounds:[ anObject ],
//...
}
}
};
deep.flatten( myObj ).done(...);
backgrounds & foregrounds are applied from root to leaf, at any depth
applied resources could also contains backgrounds & foregrounds (recursive)
backgrounds & foregrounds are consumed : they are removed at flatten
they could contains objects or sheets references, resources locators, or queries for inner inheritance
SURPLVĠƐƖ�FRQWġƜ���FRQFXUUHQFƯ�JLļglocal namespace for contextualised globals
request reception
request endasync call
user 1 context
user 2 context
user 3 context
- nodejs request - dom manipulator ($) - session
- session
-...
-...
-...
- nodejs request - dom manipulator ($) - OCM modes
- nodejs request - dom manipulator ($)
User 1request
User 2request
User 3request
server timeContext association for each (concurrent) request.
Typical context’s content : dom global manipulator (jquery ref ), catched route, current session, modes (environnements flags (prod/dev/...), roles (admin, user, public, ...), ...), server request, ...
- No more arguments cascading (as middleware pattern does)- No more globals- Allow real isomorphism : concurrent env or not = same code (think about dom or login or route mngt)
deep.contextualise({ req:request, $:cheerio.init() )})....done(function(s){ deep.context(”req”).write(s); })...
SURWRFROƖ���DNö�DĄWUDFƜ�UHVRXUFĠ�ORFDWRU
deep.protocols.myProtoc = {
get : function(request, options)
{
return ”default with : ” + request;
},
myFunc : function(arg1, arg2, request, options)
{
return “custom with : ” + arg1 + ”,” + arg2 + ” : ” + request;
}
};
Define your protocol controller in deep.protocols namespace :
deep( “myProtoc::anything” ).done(...)...;
// => default with : anything
Then, from anywhere,
by default : it uses the get method from the protocol controller :
deep( “myProtoc.myFunc(12,hello)::anything” ).log()...;
// => custom with : 12,hello : anything
and you could access custom methods with classical dot notation :
deepjs natives protocols : js, instance, eval, dq, this
Protocols from deepjs libs : dom, json, html, swig, marked, ...
Protocols management tools are OCM aware.
RFŢ���REMHFƜ�FDSDELOLWƯ�PDQDJHUobject’s nature depends on context
prod :
dev :
admin :
user :
public :
Define a pool of layers1.var myOCManager = deep.ocm(
methods, primitives, array, subobjects
);
Make it sensible to particular “flags” (called modes)
2.myOCManager.sensibleTo(”env”, ”roles”);
Set modes depending on your needs3.deep.Modes({
env:”prod”,
roles:”public”
});
Ask your manager current combination depending on current modes :(combinations are compiled/merged only once)
4.
var my_combination = myOCManager();
deep.modes({ env:”dev”, roles:”admin” }).restful(”myProtoc”).put(”my new title”, “object_id/title”).done(...)...
Modes could be contextualised, and ocm could be placed in protocols to obtain dependency injection :example with ocm restful store placed in protocols and used through chained restful mediator API.
LVRPRUSKLFƖZULWĠ�RQFĠ��UXŨ�HYHU\ZKHUĠ
UHVWĽŝ�KRPRJHQHRXƖ�FROOHFWLRQƖOne for all
one language to query them all : Resource Query Language (RQL)deep.restful(”myStore”).get(”?or(amount=gt=5,title=in=(hello,world))”).done(...)...
deep.restful(”myStore”).put(”my new title”, “id/title”).del(”item_id”).done(...)...one API to C(R)UD them all : post, put, patch, del (HTTP/Restful verbs)
deep.restful(”myStore”).rpc(”my_procedure”, [12, true], ”item_id”).done(...)...fine grained action with JSON-RPC
deep(”myStore.range(10,19)::?my_rql_query”).done(...)...Pure HTTP range paging hidden behind homogeneous range object
deep.restful(”myStore”)...Promise based chained mediator
API
JSON-Schema validation
JSON-Schema dynamic constraints declaration : owner, private, readonly, ...
JSON-Schema transformers declaration : sanitize, change case, ...
JSON-Schema links for ORM (embryonnar)
OCM friendly
Constraints
deep.collection, deep.mongo, deep.jquery.json/html/xml, deep.elastic, deep.jstorage, ...Implemented in :
RFŢ��UHVWĽŝ�VWRUĠ�EƯ�ġDPSOĠWhere all deepjs tools converge
deep.ocm({
dev: deep.Collection({
collection: deep.Shared([{ id:"e1", title:"My product", amount:24 }])
}),
prod: deep.Mongo({
url:"...",
collectionName:"products"
}),
admin: {
schema: {
properties: {
title: { type:"string", required:true },
amount: { type:"number", required:true }
}
}
},
user: {
_backgrounds: ["this::../admin", deep.Disallow("del", "rpc", “post”)],
schema: {
properties: {
amount: { readOnly:true }
}
},
put: deep.compose.after(function(obj){
// do something custom after original put
})
},
"public": {
_backgrounds: ["this::../user", deep.AllowOnly("get", "range")]
}
}, {
sensibleTo: ["env","roles"],
protocol: "products"
});
//...
deep.modes({ env: "dev", roles: "user" })
.restful( "products" )
.put( "My new title.", "/e1/title" )
.get( "?amount=gt=5" )
.done( /*... */ )
.elog();
YLHZƖ���IURŢ�PLQLPDOLVWLĊ�WŬ�ĽOŝ�FRQWUROOHĘlayered & concurrent friendly views controller
var ctrl = deep.View({
how:”<div>hello world</div>”,
where:”dom.htmlOf::#my_selector”
});
ctrl.refresh().done(...)...;
PLQLPDOLVWLĊvar ctrl = deep.View({
init : function(){ /* bind listeners */ },
what : {
products : ”products.range(0,9)::?amount=gt=5”,
profile : ”profile::?userId={ context.session.user.id }”
},
how : ”marked::/path/to/my/markdown/template”,
where : ”dom.appendTo::#my_selector”,
done : function(renderObject){ /* custom behaviours */ },
fail : function(error){ /* any refresh error */ },
clean : function(){ /* unbind listeners */ }
});
ctrl.refresh().done(...)....;
ĽOŝ�FRQWUROOHĘ
URXWHƖ���GHHSOƯ�VWUXFWXUHĘ�G\QDPLĊ�URXWLQŁlayered & concurrent friendly routes IOC controller
var map = { home: deep.View({ navigation: false, route: "/$", how: "<div/>" }), layers: { route: "/layers", subs: { overview: deep.View({ route: "./$", how: "docs::/pages/layers/overview.html" }), up_bottom: deep.View({ route: "./up-bottom", how: "docs::/pages/layers/up-bottom.html" }), compositions: deep.View({ route: "./compositions", how: "docs::/pages/layers/compositions.html" }), ... } }, ...};
WŬ�EĠ�FRQWLQXHĘ���
deepMƖ
oĹçT��ĹŕËĻÈĹàõŔ� }TŇĻÇõĩĹ�ĹºËàà�įĹvõõçTîį
Many thanks to Kris Zyp, from dojo foundation, who is the man behind JSON-Schema, RQL and persvr/pintura.I’ve been really inspired by his great work on compositions, promises, context, thin server, OCM and homogeneous restful management.Without him, deepjs would still be just good ideas.
Also, many thanks to my friend Philippe Delabye that has followed me while I was rewriting everything permanently. Thanks for his patience and for hours of discussions and help that he has provided since 3 years.
Last but not least, huge thanks to my love, Pomme, my marvelous son, Ivan, and my friends whom support and encourage me all this time.
GHHSMƖ���FRQFHSWƖ�DQĘ�GHĴQLWLRQƖ����
Any object designed to be merged (deeply) with others. It could be active (sheets) or passive (js values, objects, array, ...).It could be model, specialisation, transformation, datas, config, prototype, function,...
A bunch of layers attached/applied (deeply) together.
Event that happend when two properties from two layers being merged share the same path (from root merge point)
A function that perfom custom logics when collided with values.
A particular type of collider that allow fine grained functions merging (after, before, around, ...)
A simple DSL aimed to query js objects structures. A query is composed of a succession of steps (move - select - filter).e.g. : ./(foo.*)?or(amount=gt=5,year=2014)/barFilters are expressed in RQL (see below).
Active layer that could be seen as Transformations units or super aspect. Inspired from style sheet (CSS), it’s defined as a simple object, where root’s properties : - keys give queries (as selectors) to select sub-structures from any object - values give transformations sequences to apply on selected sub-structures
fact to inherit from or be specialised by any local query result.A local query result is some structure selected in the whole object where the one that is being specialised is attached. e.g. the brother, the oncle, the cousin, etc.
OD\HU
ODQGVFDSĠ
FROOLVLRŨ
FROOLGHU
FRPSŮLWLRŨ
GHHS�TXHUƯ
VKHHƜ
LQWHUQDŝ�LQKHULWDQFĠ
GHHSMƖ���FRQFHSWƖ�DQĘ�GHĴQLWLRQƖ����
The art of designing things with layers and queries. Kind of super-aspect oriented programming.
(AOP) A style of programming that attempts to abstract out features common to many parts of the code beyond simple functional modules and therebyimprove the quality of software. (http://wwwtrese.cs.utwente.nl/aop-ecoop99/)
Abstract Resource Locator. Simple tool to define resource controller and to use it by specifying them in front of resource string pointer.e.g. “products.range(0,10)::?amount=gt=5”
(...) encapsulate the processes involved in obtaining a service with a strong abstractionlayer. (...) uses a central registry known as the "service locator", which on request returns the information necessary to perform a certain task.(http://en.wikipedia.org/wiki/Service_locator_pattern)
An injection is the passing of a dependency (a service) to a dependent object (a client). The service is made part of the client's state. Passing the service to the client, rather than allowing a client to build or find the service, is the fundamental requirement of the pattern.(http://en.wikipedia.org/wiki/Dependency_injection)
The object capability model is an approach to security that utilizes object references as the primary means of controlling access and providing authority. (http://en.wikipedia.org/wiki/Object-capability_model)
ODQGVFDSĠ�RULHQWHĘ�SURJUDPPLQŁ
DVSHFƜ�RULHQWHĘ�SURJUDPPLQŁ
SURWRFROƖ
VHUYLFĠ�ORFDWRU
GHSHQGHQFƯ�LQMHFWLRŨ
RFŢ
GHHSMƖ���FRQFHSWƖ�DQĘ�GHĴQLWLRQƖ����
Program composition that supports building object-oriented systems as compositions of subjects, extending systems by composing them with new subjects, and integrating systems by composing them with one another (http://research.ibm.com/sop/)
Allows loose coupling between classes by being the only class that has detailedknowledge of their methods - (http://shichuan.github.io/javascript-patterns/#code-reuse-patterns)
Pattern for sequencing async successes and error with promise.(http://sitr.us/2012/07/31/promise-pipelines-in-javascript.html)
concurrent computing is a form of modular programming, namely factoring an overall computation into subcomputations that may be executed concurrently.(http://en.wikipedia.org/wiki/Concurrent_computing)
The model-driven architecture approach defines system functionality using a platform-independent model (PIM) using an appropriate domain-specific language (DSL). Then, given a platform model( ...), the PIM is translated to one or more platform-specific models (PSMs) that computers can run. This requires mappings and transformations and should be modeled too.(http://en.wikipedia.org/wiki/Model-driven_architecture)
Said about complex objects than can be runned, without change, server side orbrowser side.
VXEMHFƜ�RULHQWHĘ�SURJUDPPLQŁ
PHGLDWRU
SURPLVĠ�SLSHOLQLQŁ
FRQFXUUHQƜ�SURJUDPPLQŁ
PRGHŝ�GULYHŨ�DUFKLWHFWXUĠ
LVRPRUSKLVŢ
GHHSMƖ���FRQFHSWƖ�DQĘ�GHĴQLWLRQƖ����
In computer programming, homoiconicity (...) is a property of some programminglanguages in which the program structure is similar to its syntax, and therefore the program's internal representation can be inferred by reading the text's layout.(http://en.wikipedia.org/wiki/Homoiconicity)
Express that complexity has been delegate to client. Server only manage data model.(more info with single page app below)
A single-page application (SPA), also known as single-page interface (SPI), is a web application or web site that fits on a single web page with the goal of providing a more fluid user experience akin to a desktop application.(http://en.wikipedia.org/wiki/Single-page_application)
Inversion of control (IoC) describes a design in which custom-written portions of a computer program receive the flow of control from a generic, reusable library.(http://en.wikipedia.org/wiki/Inversion_of_control)
Representational state transfer (REST) is an abstraction of the architecture of the World Wide Web; more precisely, REST is an architectural style consisting of a coordinated set of architectural constraints applied to components, connectors, and data elements, within a distributed hypermedia system.(http://en.wikipedia.org/wiki/Representational_state_transfer)
Resource Query Language (RQL) is a query language designed for use in URIs with object style data structures.(https://github.com/persvr/rql)
KRPRLFRQLFLWƯ
WKLŨ�VHUYHU
VLQJOĠ�SDJĠ�DSSOLFDWLRŨ
LRĊ
UHVWĽŝ
UTŝ