-
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( ... )> );
Some random thoughts:
Transaction
classY.io<transport>()
should return theTransaction
instance which wraps the native XHR objectTransaction
should just keep a list of callbacks since it will be bundled withGet
which is in the core YUI file.DataSource
can be used when you need anEventTarget
and more abstractionTransaction
should have the same methods that are added toY.io
soY.io.css(foo).script(bar)
makes sense (with promises one would run after the other completes).Widget