-
transport layer
-
transaction layer
-
encapsulated configuration layer (aka Resource/DataSource)
-
Transport layer
Goals: encapsulate one method of pipelining data with as little code and as few requirements as possible.
var nativeObject = Y.io.<transport>(source, callback(err, response) {
/* 'this' is appropriate object */
});
...optionally support context override as third arg to transport function, and pass appropriate object as third arg to callback
###Examples
var scriptNode = Y.io.script(url, function (err, response) {
/* 'this' is the <script>? */
});
var xhrObj = Y.io.xhr(url, function (err, response) {
/* 'this' is the XHR object?
*/ });
var func = Y.io.func(this.someMethod, function (err, resp) {
/* 'this' is ??? */ },
this); // override context?
- xhr
- xdr
- form (iframe?)
- script
- link
- flash?
- socket
- function/func
- array
- object -- see schema for usefulness
- more...
- Transactions
Goals: create encapsulation of lifecycle wrapping transport, standardize API abstraction over transport layer, add events for consistent transaction lifecycle stages plus any stages that are appropriate per transport, support post-response processing
var transaction = Y.io(source, {
transport: <transport name>,
type: <post-processor name>,
on: {
// or start, end?
send: callback(e) { /* 'this' and e.transaction are the transaction */ },
response: callback(e) { /* same, plus e.response is the transport response */ },
}
after?
context?
args?
});
var transaction = Y.io(source, callback(e) { /* e.response */ } [, context?]);
var transaction = Y.io(source, { config, but without on: {...} }, callback(e) { /* e.response */ } [, context?]);
var transaction = Y.io(source, <type>, callback(e) { /* e.response */ });
Other configuration attributes/properties interpreted by the transport/type modules or generic feature modules/plugins, such as:
method: ('get', 'post', 'put', 'delete', 'head')
multipart: true || separatorString?
sync: false
headers: { 'content-type': 'application/json' }
queuing: true
polling: true || msInterval || { more config? }
disabledFields: false
native: true
- for xdr transportdata: ...
- form data or maybe form Node or idtimeout: ms
schema
- e.g.
schema: {
resultListLocator: 'records.here',
resultFields: [ ... ]
output: ('array', 'arraylist', ModelList, MyArrayListSubclass, more?)
}
on: {
success: callback(e) { ... },
failure: callback(e) { ... }
}
Y.io will default transport based on a test function on each transport, and/or set by the 'type' configuration.
CAVEAT: transport test-based defaulting could create confusion for JSONP vs XHR
var useAsDefault = Y.io.script.test(source, config); // => true/false/likelihood rating
var transaction Y.io('/service', function (e) {
/* xhr transport passes test, is used */
});
// types can default transport
var transaction = Y.io('http://servi.ce/foo', { type: 'jsonp' }, function (e) {
/* 'script' transport defaulted */
});
// types and transports can be incompatible
var boom = Y.io(source, { transport: 'link', type: 'jsonp' }, ...); // boom === null
- Encapsulated configuration
Goals: Create transaction factories with configured defaults.
Use same/similar API signature to Y.io().
NAMING DISCUSSION: Y.DataSource, Y.Resource, Y.io.Resource, other?
var resourceA = new Y.DataSource(url/data, { ... });
var transaction = resourceA.send(extra/data, {
/* config overrides, plus transaction level... */
on: { ... }
}, contextOverride?);
// Transaction object points back to originating resource
transaction.resource; // => resourceA
// Post-creation subscription possible
transaction.on('success', fn);
transaction.after('end', fn);
// Transport-specific API decoration?
transaction.abort();
- (bonus!) Widget extension API
Goals: normalize API for data layer configuration of Widgets (and others?)
Mirror the DataSource/IO API, but with 'source' property in configuration object taking the place of the leading url/source argument. Widget attribute should be 'data' (debatable).
var table = new Y.DataTable({
data: {
source: url,
type: 'jsonp',
schema: {
resultListLocator: 'records',
...
}
},
columns: [ ... ]
});
table.load( <sig args for dataSourceInstance.send( ... )> );
var chart = new Y.Chart({
data: {
source: url,
type: 'jsonp',
schema: {
resultListLocator: 'records',
...
}
},
type: 'pie'
});
chart.load( <sig args for dataSourceInstance.send( ... )> );
A sidetrack that I also wanted to capture in a comment is a possibility of a server-side module to respond and process client-side data requests. For instance: xhr level 2 requests are tricky when used across domains, because they require a specific initial OPTIONS response. We could potentially create a server-side only YUI module that will facilitate responding to a variety of requests. This may be included in io with some sort of an additional io-server module. A very rough idea.