-
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: falseheaders: { 'content-type': 'application/json' }queuing: truepolling: true || msInterval || { more config? }disabledFields: falsenative: true- for xdr transportdata: ...- form data or maybe form Node or idtimeout: msschema- 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( ... )> );
Some random thoughts:
TransactionclassY.io<transport>()should return theTransactioninstance which wraps the native XHR objectTransactionshould just keep a list of callbacks since it will be bundled withGetwhich is in the core YUI file.DataSourcecan be used when you need anEventTargetand more abstractionTransactionshould have the same methods that are added toY.iosoY.io.css(foo).script(bar)makes sense (with promises one would run after the other completes).Widget