Permalink
Browse files

0.3 RC2 release

  • Loading branch information...
1 parent ef297a9 commit 26aa3670692db5caac146dd3562f8077a9d30f4c Owen Barnes committed May 4, 2012
Showing with 246 additions and 192 deletions.
  1. +15 −0 HISTORY.md
  2. +1 −1 Makefile
  3. +25 −8 README.md
  4. +8 −1 doc/guide/en/authentication.md
  5. +1 −1 lib/cli/generate.js
  6. +18 −23 lib/client/asset.js
  7. +3 −3 lib/client/http.js
  8. +6 −9 lib/client/index.js
  9. +4 −10 lib/client/live_reload.js
  10. +7 −7 lib/client/pack.js
  11. +2 −2 lib/client/serve/dev.js
  12. +3 −3 lib/client/serve/ondemand.js
  13. +3 −3 lib/client/system/index.js
  14. +16 −9 lib/client/system/modules/socketstream.js
  15. +4 −4 lib/client/view.js
  16. +4 −0 lib/client/wrap.js
  17. +1 −1 lib/request/index.js
  18. +5 −2 lib/socketstream.js
  19. +2 −2 lib/websocket/index.js
  20. +3 −3 lib/websocket/transport.js
  21. +8 −4 lib/websocket/transports/socketio/index.js
  22. +9 −10 lib/websocket/transports/socketio/wrapper.js
  23. +0 −1 new_project/client/css/app.demo.styl
  24. +1 −1 package.json
  25. +0 −1 src/cli/generate.coffee
  26. +14 −21 src/client/asset.coffee
  27. +3 −3 src/client/http.coffee
  28. +6 −9 src/client/index.coffee
  29. +6 −4 src/client/live_reload.coffee
  30. +7 −7 src/client/pack.coffee
  31. +2 −2 src/client/serve/dev.coffee
  32. +3 −3 src/client/serve/ondemand.coffee
  33. +1 −1 src/client/serve/utils.coffee
  34. +2 −2 src/client/system/index.coffee
  35. +13 −6 src/client/system/modules/socketstream.coffee
  36. +4 −4 src/client/view.coffee
  37. +4 −0 src/client/wrap.coffee
  38. +1 −1 src/request/index.coffee
  39. +5 −2 src/socketstream.js
  40. +2 −2 src/websocket/index.coffee
  41. +3 −3 src/websocket/transport.coffee
  42. +14 −4 src/websocket/transports/socketio/index.coffee
  43. +7 −9 src/websocket/transports/socketio/wrapper.coffee
View
@@ -1,3 +1,18 @@
+0.3 RC2 / 2012-05-04
+====================
+
+* New: Multiple Websocket Transports now fully supported. Switch between Socket.IO (bundled by default) and [SockJS](https://github.com/socketstream/ss-sockjs) (first alpha release) without changing any of your application code
+* New: Socket.IO client library can now be configured (see updated example in README)
+* Live Reload: Working on fixing issues whilst renaming files in VIM (see #227, thanks madscoaducom), fixed issue saving CSS + normal files together
+* Errors in formatting templates (e.g. bad `.jade`) now caught properly
+* Any missing sessions are now automatically recreated (useful when developing without using Redis)
+* New project example code now uses [Nib](http://visionmedia.github.com/nib) instead of custom Stylus helpers
+* Minor refactoring
+* Updated README with video link
+
+Note: SocketStream 0.3.0 will be officially launched later in May, along with example apps, screencasts, more documentation and improvements to [www.socketstream.org](http://www.socketstream.org). Read announcement [here](https://groups.google.com/forum/?fromgroups#!topic/socketstream/Y6OIOrJRX7w).
+
+
0.3 RC1 / 2012-04-22
====================
View
@@ -6,8 +6,8 @@ build:
rm -fr lib; node_modules/coffee-script/bin/coffee --bare -o lib -c src; cp src/*.js lib; cp src/utils/*.js lib/utils; cp src/websocket/transports/socketio/*.js lib/websocket/transports/socketio; mkdir lib/client/system/libs; cp -R src/client/system/libs/*.js lib/client/system/libs/; cp -R src/client/system/modules/*.js lib/client/system/modules/;
# Ignore files and directories prepended with 'testdata_'
+TEST_FILES=`find test/* | grep -v '^test/testdata_*'`
test:
- TEST_FILES=`find test/* | grep -v '^test/testdata_*'`
./node_modules/.bin/mocha --require should --require coffee-script $(TEST_FILES)
.PHONY: test
View
@@ -2,7 +2,8 @@
# SocketStream
-Latest release: 0.3.0 RC1 ([view changelog](https://github.com/socketstream/socketstream/blob/master/HISTORY.md))
+Latest release: 0.3.0 RC2 ([view changelog](https://github.com/socketstream/socketstream/blob/master/HISTORY.md))
+
[![build status](https://secure.travis-ci.org/socketstream/socketstream.png)](http://travis-ci.org/socketstream/socketstream)
Twitter: [@socketstream](http://twitter.com/#!/socketstream)
@@ -11,6 +12,8 @@ IRC channel: [#socketstream](http://webchat.freenode.net/?channels=socketstream)
Take a tour of all the new features at http://www.socketstream.org/tour
+**NEW** [Watch the introductory presentation](http://2011.krtconf.com/videos/owen_barnes) I gave at [KrtConf](http://krtconf.com) last November. Although the first half refers to the previous version (SocketStream 0.2), all the upcoming features I speak about (mid-way through) are now available in SocketStream 0.3.
+
### Introduction
@@ -24,6 +27,8 @@ Whilst we have chosen not to support models or reactive templating in the core,
SocketStream apps can easily be deployed to [Nodejitsu](http://nodejitsu.com), [EC2 servers](http://aws.amazon.com/ec2) or any other hosting platform supporting websockets (sadly that excludes [Heroku](http://www.heroku.com) for the moment).
+While it is still early days, our end goal is to ensure SocketStream can be used to power large-scale 'serious' web apps where scalability, flexibility and high availability are key.
+
#### Quick Facts
@@ -46,7 +51,7 @@ SocketStream 0.3.0 will be officially launched in May, along with example apps,
#### Client Side
* Works great with Chrome, Safari, Firefox 6 (and above) using native websockets
-* Compatible with older versions of Firefox and IE thanks to configurable fallback transports provided by Socket.IO
+* Compatible with older versions of Firefox and IE thanks to configurable fallback transports
* Use `require()` and `exports` in your client-side code as you would on the server
* Define multiple single-page clients by choosing the CSS, JS and client-side templates you wish to serve
* Integrated asset manager - automatically packages and [minifies](https://github.com/mishoo/UglifyJS) all client-side assets
@@ -62,7 +67,8 @@ SocketStream 0.3.0 will be officially launched in May, along with example apps,
#### Server Side
-* True bi-directional communication using websockets (or [Socket.IO 0.9](http://socket.io) fallbacks). No more slow, messy AJAX!
+* True bi-directional communication using websockets (or websocket fallbacks). No more slow, messy AJAX!
+* Modular Websocket Transports - switch between [Socket.IO](http://socket.io) (bundled by default) or [SockJS](https://github.com/socketstream/ss-sockjs) without changing your app code
* Easily share code between the client and server. Ideal for business logic and model validation (see Questions below)
* Request Middleware - enabling session access, authentication, logging, distributed requests and more
* Effortless, scalable, pub/sub baked right in - including Private Channels
@@ -73,6 +79,7 @@ SocketStream 0.3.0 will be officially launched in May, along with example apps,
#### Optional Modules (officially maintained and supported)
+* **[ss-sockjs](https://github.com/socketstream/ss-sockjs)** Use [SockJS](https://github.com/sockjs/sockjs-client) as the websocket transport instead of Socket.IO
* **[ss-console](https://github.com/socketstream/ss-console)** Connect to a live server and call RPC actions or publish events over the REPL / terminal
* Code Formatters: **[ss-coffee](https://github.com/socketstream/ss-coffee)** (CoffeeScript), **[ss-jade](https://github.com/socketstream/ss-jade)** Jade (for HTML), **[ss-stylus](https://github.com/socketstream/ss-stylus)** Stylus (for CSS), **[ss-less](https://github.com/socketstream/ss-less)** Less (for CSS)
* Client-side Template Engines: **[ss-hogan](https://github.com/socketstream/ss-hogan)** Hogan/Mustache, **[ss-coffeekup](https://github.com/socketstream/ss-coffeekup)** CoffeeKup
@@ -83,7 +90,7 @@ SocketStream 0.3.0 will be officially launched in May, along with example apps,
SocketStream automatically compresses and minifies the static HTML, CSS and client-side code your app needs and sends this through the first time a user visits your site.
-From then on all application data is sent and received via the websocket (or Socket.IO fallbacks), instantly established when the client connects and automatically re-established if broken. Normally this will be in [JSON RPC](https://github.com/socketstream/socketstream/blob/master/doc/guide/en/rpc_responder.md) format, but SocketStream 0.3 allows you to use different Request Responders depending upon the task at hand.
+From then on all application data is sent and received via the websocket (or websocket fallbacks), instantly established when the client connects and automatically re-established if broken. Normally this will be in [JSON RPC](https://github.com/socketstream/socketstream/blob/master/doc/guide/en/rpc_responder.md) format, but SocketStream 0.3 allows you to use different Request Responders depending upon the task at hand.
All this means no more connection latency, HTTP header overhead, polling, or clunky AJAX. Just true bi-directional, asynchronous, 'streaming' communication between client and server.
@@ -225,18 +232,28 @@ Install the excellent 'nodemon' module with `sudo npm install -g nodemon` then s
##### How can I configure Socket.IO?
-Like so:
+You may fully configure the Socket.IO server and client libraries like so:
```javascript
-ss.ws.transport.use('socketio', {io: function(io){
- io.set('log level', 4)
-}});
+ss.ws.transport.use('socketio', {
+ client: {
+ transports: ['websocket', 'htmlfile', 'xhr-polling', 'jsonp-polling']
+ },
+ server: function(io){
+ io.set('log level', 4)
+ }
+});
```
+
##### Where can I deploy my apps to?
SocketStream works great with [Nodejitsu.com](http://www.nodejitsu.com), as well as custom EC2 / cloud servers. Sadly [Heroku.com](http://www.heroku.com) does not currently support websockets.
+Tip: If you're deploying to Nodejitsu add the following dependency to your `package.json`:
+
+ "socketstream": "git://github.com/socketstream/socketstream.git#master"
+
##### Will it run on Windows?
@@ -87,7 +87,14 @@ And you'll see the following output:
SocketStream integrates well with popular authentication libraries such as [Everyauth](https://github.com/bnoguchi/everyauth).
-Here's an example of a full app which authenticates against Twitter's OAuth service:
+Tip: Don't be tempted to follow the docs on the Everyauth website too closely - they are mainly geared at multi-page apps and/or specific to Express.
+
+Here's an example of a full app which authenticates against Twitter's OAuth service.
+
+To get started, register your new app at https://dev.twitter.com/apps/new
+
+When testing your app supply `http://127.0.0.1:3000` as the Callback URL. Change this to the real URL when your app goes into production.
+
```javascript
// app.js
View
@@ -85,7 +85,7 @@ exports.generate = function(program) {
}
appjs += "\n// Start SocketStream\nss.start(server);";
write('/app.js', appjs);
- pacakgejs = "{\n \"name\": \"" + name + "\",\n \"description\": \"An awesome real time application\",\n \"version\": \"0.0.1\",\n \"author\": \"Me <me@mydomain.com>\",\n \"private\": true,\n \"engines\": { \"node\": \">= 0.6.0\" },\n \"dependencies\": {\n \"socketstream\": \"git://github.com/socketstream/socketstream.git#master\",\n";
+ pacakgejs = "{\n \"name\": \"" + name + "\",\n \"description\": \"An awesome real time application\",\n \"version\": \"0.0.1\",\n \"author\": \"Me <me@mydomain.com>\",\n \"private\": true,\n \"engines\": { \"node\": \">= 0.6.0\" },\n \"dependencies\": {\n";
mods = selectedFormatters.concat(['hogan']);
if (program.repl) mods.push('console');
mods.forEach(function(name, i) {
View
@@ -1,4 +1,4 @@
-var formatKb, formatters, fs, loadFile, log, minifyJS, minifyJSFile, pathlib, uglifyjs, wrapCode, wrapModule,
+var formatKb, formatters, fs, jsp, loadFile, log, minifyJSFile, pathlib, pro, uglifyjs, wrap, wrapCode,
__indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
log = console.log;
@@ -11,10 +11,16 @@ uglifyjs = require('uglify-js');
formatters = require('./formatters');
-exports.init = function(root, options) {
+wrap = require('./wrap');
+
+jsp = uglifyjs.parser;
+
+pro = uglifyjs.uglify;
+
+module.exports = function(ss, options) {
return {
js: function(path, opts, cb) {
- return loadFile(root, options.dirs.code, path, 'js', opts, function(output) {
+ return loadFile(ss.root, options.dirs.code, path, 'js', opts, function(output) {
output = wrapCode(output, path, opts.pathPrefix);
if (opts.compress && !path.indexOf('.min') >= 0) {
output = minifyJSFile(output, path);
@@ -23,24 +29,20 @@ exports.init = function(root, options) {
});
},
worker: function(path, opts, cb) {
- return loadFile(root, options.dirs.workers, path, 'js', opts, function(output) {
+ return loadFile(ss.root, options.dirs.workers, path, 'js', opts, function(output) {
if (opts.compress) output = minifyJSFile(output, path);
return cb(output);
});
},
css: function(path, opts, cb) {
- return loadFile(root, options.dirs.css, path, 'css', opts, cb);
+ return loadFile(ss.root, options.dirs.css, path, 'css', opts, cb);
},
html: function(path, opts, cb) {
- return loadFile(root, options.dirs.views, path, 'html', opts, cb);
+ return loadFile(ss.root, options.dirs.views, path, 'html', opts, cb);
}
};
};
-exports.wrapModule = wrapModule = function(modPath, code) {
- return "require.define(\"" + modPath + "\", function (require, module, exports, __dirname, __filename){\n" + code + "\n});";
-};
-
loadFile = function(root, dir, fileName, type, options, cb) {
var extension, formatter, path;
dir = pathlib.join(root, dir);
@@ -65,20 +67,13 @@ formatKb = function(size) {
};
minifyJSFile = function(originalCode, fileName) {
- var minifiedCode;
- minifiedCode = minifyJS(originalCode);
- log((" Minified " + fileName + " from " + (formatKb(originalCode.length)) + " to " + (formatKb(minifiedCode.length))).grey);
- return minifiedCode;
-};
-
-minifyJS = function(originalCode) {
- var ast, jsp, pro;
- jsp = uglifyjs.parser;
- pro = uglifyjs.uglify;
+ var ast, minifiedCode;
ast = jsp.parse(originalCode);
ast = pro.ast_mangle(ast);
ast = pro.ast_squeeze(ast);
- return pro.gen_code(ast);
+ minifiedCode = pro.gen_code(ast);
+ log((" Minified " + fileName + " from " + (formatKb(originalCode.length)) + " to " + (formatKb(minifiedCode.length))).grey);
+ return minifiedCode;
};
wrapCode = function(code, path, pathPrefix) {
@@ -87,7 +82,7 @@ wrapCode = function(code, path, pathPrefix) {
if (__indexOf.call(pathAry, 'libs') >= 0) return code;
if (__indexOf.call(pathAry, 'system') >= 0) {
modPath = pathAry[pathAry.length - 1];
- return wrapModule(modPath, code);
+ return wrap.module(modPath, code);
} else {
modPath = pathAry.slice(1).join('/');
if (pathPrefix) {
@@ -98,6 +93,6 @@ wrapCode = function(code, path, pathPrefix) {
}
modPath = path.substr(pathPrefix.length + 1);
}
- return wrapModule('/' + modPath, code);
+ return wrap.module('/' + modPath, code);
}
};
View
@@ -12,7 +12,7 @@ cache = {};
res = http.ServerResponse.prototype;
-module.exports = function(root, clients, options) {
+module.exports = function(ss, clients, options) {
res.serveClient = function(name) {
var client, fileName, self, sendHTML;
self = this;
@@ -29,12 +29,12 @@ module.exports = function(root, clients, options) {
}
if (client.pack) {
if (!cache[name]) {
- fileName = pathlib.join(root, options.dirs.assets, client.name, client.id + '.html');
+ fileName = pathlib.join(ss.root, options.dirs.assets, client.name, client.id + '.html');
cache[name] = fs.readFileSync(fileName, 'utf8');
}
return sendHTML(cache[name]);
} else {
- return view(root, client, options, sendHTML);
+ return view(ss, client, options, sendHTML);
}
};
return res.serve = res.serveClient;
View
@@ -28,11 +28,8 @@ clients = {};
module.exports = function(ss, router) {
var http;
- http = require('./http')(ss.root, clients, options);
+ http = require('./http')(ss, clients, options);
systemAssets.load();
- ss.client = {
- send: systemAssets.send
- };
return {
formatters: formatters.init(ss.root),
templateEngine: templateEngine.init(ss, options),
@@ -92,18 +89,18 @@ module.exports = function(ss, router) {
load: function(ss) {
var client, name, pack;
formatters.load();
- systemAssets.send('code', 'init', "require('/entry'); require('socketstream').connect();");
+ systemAssets.send('code', 'init', "require('/entry');");
if (packAssets) {
pack = require('./pack');
for (name in clients) {
client = clients[name];
- pack(ss.root, client, options);
+ pack(ss, client, options);
}
} else {
- require('./serve/dev')(ss.root, router, options);
- if (options.liveReload) require('./live_reload')(ss.root, options, ss);
+ require('./serve/dev')(ss, router, options);
+ if (options.liveReload) require('./live_reload')(ss, options);
}
- return require('./serve/ondemand')(ss.root, router, options);
+ return require('./serve/ondemand')(ss, router, options);
}
};
};
View
@@ -20,7 +20,7 @@ consoleMessage = {
reload: 'Client files changed. Reloading browser...'
};
-module.exports = function(root, options, ss) {
+module.exports = function(ss, options) {
var allPaths, assetsToWatch, detectNewFiles, handleFileChange, watch;
handleFileChange = function(action) {
if ((Date.now() - lastRun[action]) > 1000) {
@@ -37,7 +37,7 @@ module.exports = function(root, options, ss) {
};
options.liveReload.forEach(function(dir) {
var path, result;
- path = pathlib.join(root, options.dirs[dir]);
+ path = pathlib.join(ss.root, options.dirs[dir]);
result = fileUtils.readDirSync(path);
output.files = output.files.concat(result.files);
return output.dirs = output.dirs.concat(result.dirs);
@@ -53,15 +53,9 @@ module.exports = function(root, options, ss) {
var changeAction, extension, watcher;
extension = file.split('.')[file.split('.').length - 1];
changeAction = cssExtensions.indexOf(extension) >= 0 && 'updateCSS' || 'reload';
- return watcher = fs.watch(file, function(event, filename) {
+ return watcher = fs.watch(file, function(event) {
handleFileChange(changeAction);
- if (event === "rename") {
- watcher.close();
- return watch({
- files: [file],
- dirs: []
- });
- }
+ if (event === "rename") return watcher.close();
});
});
};
View
@@ -16,19 +16,19 @@ magicPath = require('./magic_path');
view = require('./view');
-module.exports = function(root, client, options) {
+module.exports = function(ss, client, options) {
var asset, clientDir, containerDir, packAssetSet;
- asset = require('./asset').init(root, options);
+ asset = require('./asset')(ss, options);
client.pack = true;
- containerDir = pathlib.join(root, options.dirs.assets);
+ containerDir = pathlib.join(ss.root, options.dirs.assets);
clientDir = pathlib.join(containerDir, client.name);
packAssetSet = function(assetType, paths, dir, postProcess) {
var filePaths, prefix, processFiles, writeFile;
writeFile = function(fileContents) {
var fileName;
fileName = clientDir + '/' + client.id + '.' + assetType;
fs.writeFileSync(fileName, postProcess(fileContents));
- return log(''.green, 'Packed ' + filePaths.length + ' files into ' + fileName.substr(root.length));
+ return log(''.green, 'Packed ' + filePaths.length + ' files into ' + fileName.substr(ss.root.length));
};
processFiles = function(fileContents, i) {
var file, path, _ref;
@@ -49,7 +49,7 @@ module.exports = function(root, client, options) {
};
if (paths && paths.length > 0) {
filePaths = [];
- prefix = pathlib.join(root, dir);
+ prefix = pathlib.join(ss.root, dir);
paths.forEach(function(path) {
return magicPath.files(prefix, path).forEach(function(file) {
return filePaths.push({
@@ -81,11 +81,11 @@ module.exports = function(root, client, options) {
compress: true
}) + files.join(';') + ';' + system.serve.initCode();
});
- return view(root, client, options, function(html) {
+ return view(ss, client, options, function(html) {
var fileName;
fileName = pathlib.join(clientDir, client.id + '.html');
fs.writeFileSync(fileName, html);
- return log(''.green, 'Created and cached HTML file ' + fileName.substr(root.length));
+ return log(''.green, 'Created and cached HTML file ' + fileName.substr(ss.root.length));
});
};
Oops, something went wrong.

0 comments on commit 26aa367

Please sign in to comment.