Permalink
Browse files

0.3beta2 release

  • Loading branch information...
Owen Barnes
Owen Barnes committed Apr 10, 2012
1 parent 12de108 commit b6d39884e9fa8e9d65e443638f044fe74056df45
Showing with 774 additions and 701 deletions.
  1. +34 −0 HISTORY.md
  2. +1 −1 Makefile
  3. +7 −7 README.md
  4. +0 −2 TODO.md
  5. +6 −1 bin/socketstream
  6. +14 −0 check_version.js
  7. +26 −12 doc/guide/en/template_engine_wrappers.md
  8. +98 −17 lib/cli/generate.js
  9. +23 −22 lib/client/asset.js
  10. +3 −3 lib/client/http.js
  11. +48 −28 lib/client/index.js
  12. +3 −3 lib/client/live_reload.js
  13. +11 −10 lib/client/pack.js
  14. +6 −6 lib/client/serve/dev.js
  15. +10 −11 lib/client/serve/ondemand.js
  16. +4 −4 lib/client/system/index.js
  17. +9 −7 lib/client/template_engine.js
  18. +16 −17 lib/client/view.js
  19. +3 −5 lib/http/index.js
  20. +3 −3 lib/request/index.js
  21. +7 −9 lib/request/middleware/index.js
  22. +1 −1 lib/request/middleware/internal.js
  23. +8 −10 lib/request/responders/events/index.js
  24. +2 −2 lib/request/responders/rpc/handler.js
  25. +5 −9 lib/request/responders/rpc/index.js
  26. +10 −10 lib/socketstream.js
  27. +0 −42 lib/utils/copy.js
  28. +1 −1 lib/websocket/index.js
  29. +2 −2 lib/websocket/transports/socketio/client.min.js
  30. +2 −2 lib/websocket/transports/socketio/index.js
  31. 0 new_project/client/code/app/{demo.coffee → app.demo.coffee}
  32. 0 new_project/client/code/app/{demo.js → app.demo.js}
  33. +3 −0 new_project/client/code/app/app.minimal.coffee
  34. +3 −0 new_project/client/code/app/app.minimal.js
  35. +2 −2 new_project/client/code/app/entry.coffee
  36. +4 −4 new_project/client/code/app/entry.js
  37. +0 −241 new_project/client/code/libs/hogan-template.js
  38. 0 new_project/client/css/{app.styl → app.demo.styl}
  39. +7 −0 new_project/client/css/app.minimal.styl
  40. +0 −3 new_project/client/css/demo.styl
  41. +4 −0 new_project/client/templates/chat/message.html
  42. +24 −0 new_project/client/views/app.demo.html
  43. 0 new_project/client/views/{app.jade → app.demo.jade}
  44. +11 −0 new_project/client/views/app.minimal.html
  45. +8 −0 new_project/client/views/app.minimal.jade
  46. +7 −7 package.json
  47. +181 −17 src/cli/generate.coffee
  48. +18 −16 src/client/asset.coffee
  49. +3 −3 src/client/http.coffee
  50. +37 −20 src/client/index.coffee
  51. +3 −3 src/client/live_reload.coffee
  52. +9 −7 src/client/pack.coffee
  53. +5 −4 src/client/serve/dev.coffee
  54. +7 −7 src/client/serve/ondemand.coffee
  55. +4 −4 src/client/system/index.coffee
  56. +7 −6 src/client/template_engine.coffee
  57. +14 −13 src/client/view.coffee
  58. +5 −7 src/http/index.coffee
  59. +8 −8 src/request/index.coffee
  60. +7 −6 src/request/middleware/index.coffee
  61. +1 −1 src/request/middleware/internal.coffee
  62. +7 −10 src/request/responders/events/index.coffee
  63. +2 −2 src/request/responders/rpc/handler.coffee
  64. +5 −10 src/request/responders/rpc/index.coffee
  65. +10 −10 src/socketstream.js
  66. +0 −38 src/utils/copy.coffee
  67. +1 −1 src/websocket/index.coffee
  68. +2 −2 src/websocket/transports/socketio/client.min.js
  69. +2 −2 src/websocket/transports/socketio/index.coffee
View
@@ -1,3 +1,37 @@
+0.3 beta2 / 2012-04-10
+======================
+
+##### Improved New App Creation
+
+* Now creates plain HTML, CSS and Javascript files by default
+* Pass `-j` for Jade and `-c` for CoffeeScript if preferred
+* Pass `-m` for Minimal Install (no chat demo)
+* Pass `-r` to include Console Server / REPL
+* Plain CSS/Stylus/Less options coming soon
+* `package.json` and `app.js` now dynamically created based upon the modules you choose
+
+
+##### Template Engine improvements
+
+* Breaking change to Template Engine module format
+* Template Engine external modules can now deliver client-side code
+* Hence the Hogan client-side library has been removed from the core and now included within `ss-hogan` 0.1.3
+* `ss-coffeekup` and `ss-clientjade` have also be updated. Please `sudo npm update` to get the latest module
+* Template Engine API documentation updated and unlikely to change again
+
+
+##### Other
+
+* The names of all client-side dirs can now be optionally changed to improve compatibility with 3rd party frameworks. E.g. `ss.client.set({dirs: {code: '/client/code', static: '/public'}})`
+* Added support for hosting packaged assets files on a CDN. To use: `ss.client.packAssets({cdn: {js: "http://my.cdn.com/my.js", css: "http://my.cdn.com/my.css"}})`
+* Internal Request Middleware now loads even if there is no `/server/middleware` directory present
+* Bit of internal refactoring. Be sure to update `ss-console` to 0.1.1
+* Upgraded Socket.IO to 0.9.5
+
+Note: Several minor tweaks and improvements will be pushed to master before 0.3.0 is released and published to NPM later this month
+
+
+
0.3 beta1 / 2012-03-26
======================
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,7 @@
# SocketStream
-Latest release: 0.3.0beta1 ([view changelog](https://github.com/socketstream/socketstream/blob/master/HISTORY.md))
+Latest release: 0.3.0beta2 ([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)
@@ -21,7 +21,7 @@ Whether you're building a group chat app, multiplayer game or trading platform,
We follow a few guiding principals to keep the framework lean, modular and extensible whilst ensuring your app can easily integrate with other great Node.js modules such as [Express.js](http://expressjs.com), [Everyauth](https://github.com/bnoguchi/everyauth) and [thousands](http://search.npmjs.org) more.
-SocketStream 0.3 is in full-time development, rapidly progressing thanks to frequent contributions from a [growing community](http://groups.google.com/group/socketstream) of developers. Now the 0.3 API is pretty much stable, there will one one further beta releases to refine features and improve existing code before we push 0.3.0 to NPM. Demos and more documentation coming soon.
+SocketStream 0.3 is in full-time development, rapidly progressing thanks to frequent contributions from a [growing community](http://groups.google.com/group/socketstream) of developers. Now the 0.3 API is pretty much stable there will be frequent updates to master before 0.3.0 is pushed to NPM later in April. Demos and more documentation coming soon.
@@ -31,8 +31,8 @@ SocketStream 0.3 is in full-time development, rapidly progressing thanks to freq
* Designed for large apps - excellent code organization, modularity and extensibility. Not a black box framework
* True bi-directional communication using websockets (or [Socket.IO 0.9](http://socket.io) fallbacks). No more slow, messy AJAX!
-* Write all code in [CoffeeScript](http://jashkenas.github.com/coffee-script/) or JavaScript - your choice
-* Works great with [Express.js](http://expressjs.com) and other Connect-based frameworks!
+* Write all code in JavaScript or [CoffeeScript](http://jashkenas.github.com/coffee-script/) - your choice
+* Works well alongside [Express.js](http://expressjs.com) and other Connect-based frameworks
* 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
@@ -103,7 +103,6 @@ If all goes well you'll see the SocketStream banner coming up, then you're ready
http://localhost:3000
-
### What can I create with it?
SocketStream is a perfect fit for all manner of modern applications which require realtime data (chat, stock trading, location monitoring, analytics, etc). It's also a great platform for building realtime HTML5 games. However, right now it would make a poor choice for a blog or other content-rich site which requires unique URLs for search engine optimization.
@@ -205,6 +204,7 @@ We've made a start on documentation for 0.3. Right now the following sections ha
Install the excellent 'nodemon' module with `sudo npm install -g nodemon` then start your app with `nodemon app.js`. A `.nodemonignore` file has already been created for you with the optimal settings. This feature is very useful when developing your app.
+
##### How can I configure Socket.IO?
Like so:
@@ -248,7 +248,7 @@ Pass any config as the second argument to either of the above commands as so:
SocketStream 0.3 makes a big assumption in order to maximize speed and reduce code complexity: All incoming connections with the same session should be routed to the same server (also known as Sticky Sessions). The session details are stored in memory and then optionally saved to Redis to preserve the session should the node fail.
-Front end scaling can be achieved using a combination of different websocket transports (such as the bundled Pusher Pipe) and optional features we intend to introduce in the future.
+Front end scaling can be achieved using a combination of different websocket transports (such as the forthcoming Pusher Pipe module) and optional features we intend to introduce in the future.
Back end scaling has yet to be properly documented, but we're keen to continue looking into ways to use ZeroMQ and also Hook IO. We will make sure back end scaling is as easy and flexible as possible, but it will no longer be a feature of the framework itself.
@@ -279,7 +279,7 @@ Creator and lead developer: Owen Barnes.
Special thanks to Paul Jensen for contributing code, ideas and testing early prototypes. Big thanks also to Addy Osmani for help with everything JavaScript related, Alan Milford for the excellent SocketRacer.com demo (which will be running on SocketStream 0.3 soon!), and Craig Jordan Muir for designing the awesome new SocketStream logo.
-Thanks also to the many who have contributed code to 0.1 and 0.2. We plan to properly feature contributors on our website in the near future.
+Thanks also to the many who have contributed code and ideas. We plan to properly feature contributors on our website in the near future.
### Credits
View
@@ -1,9 +1,7 @@
TODO
====
-* Make 'socketstream new' install recommended stack of optional modules by default, but add a minimal install option
* Websocket responders need to take a config object. It should also be able to send config to client-side code (
-* SocketStream should pass its version number and other meta info to wrapper modules
#### WORK TO DO ONCE 0.3.0 IS RELEASED
View
@@ -6,8 +6,13 @@ var ss = require('../')
program
.usage('new <name_of_your_project>')
.version(ss.version)
- .option('-j, --javascript', 'use Javascript (default)')
+ .option('-m, --minimal', 'minimal install (no chat demo)')
.option('-c, --coffee', 'use CoffeeScript')
+ .option('-j, --jade', 'use Jade for Views')
+ // To be implemented...
+ //.option('-s, --stylus', 'use Stylus for CSS')
+ //.option('-l, --less', 'use Less for CSS')
+ .option('-r, --repl', 'include Console Server / REPL')
.parse(process.argv);
require(__dirname + '/../lib/cli').process(program);
View
@@ -30,4 +30,18 @@ if (pathlib.existsSync('client/code/modules')) {
"then generate a new project to see the new format.\n\n" +
"This message will go away when /client/code/modules has been renamed to\nsomething else (we suggest 'app') so we know you've upgraded your code" + bar);
throw new Error("Please update your /client/code with the latest changes (see above)");
+}
+
+// Ensure two hogan-template.js files are not served together
+var hoganFile = 'client/code/libs/hogan-template.js';
+if (pathlib.existsSync(hoganFile)) {
+ require('fs').unlinkSync(hoganFile);
+ console.log(bar +
+ "Thanks for upgrading to the latest SocketStream 0.3 beta.\n\n" +
+ "SocketStream now allows Template Engine modules to deliver client-side code.\n\n" +
+ "We've deleted " + hoganFile + " from your project as it is\n" +
+ "no longer required. Please ensure you have ss-hogan 0.1.3 installed by running:\n\n" +
+ " sudo npm update" + bar);
+ throw new Error("Please run 'sudo npm update'");
+
}
@@ -5,41 +5,55 @@ Writing your own template engine wrapper is easy. For this quick tutorial we'll
You can see the file structure for a template engine wrapper in the [ss-hogan repository]([ss-hogan](https://github.com/socketstream/ss-hogan)). Let's look at the key file, `engine.js`:
```javascript
-/* lib/engine.js */
+/* engine.js */
+
+// Hogan Template Engine wrapper for SocketStream 0.3
-var hogan = require('hogan');
+var fs = require('fs'),
+ path = require('path'),
+ hogan = require('hogan.js');
-exports.init = function(root, config) {
+exports.init = function(ss, config) {
- // Set global/window variable used to access templates from the browser
- var namespace = config && config.namespace || 'HT'
+ // Send Hogan VM to the client
+ var clientCode = fs.readFileSync(path.join(__dirname, 'client.js'), 'utf8');
+ ss.client.send('lib', 'hogan-template', clientCode);
return {
name: 'Hogan',
// Opening code to use when a Hogan template is called for the first time
prefix: function() {
- return '<script type="text/javascript">if(!window.' + namespace + '){window.' + namespace + ' = {};}';
+ return '<script type="text/javascript">(function(){var ht=Hogan.Template,t=require(\'socketstream\').tmpl;'
},
// Closing code once all Hogan templates have been written into the <script> tag
suffix: function() {
- return '</script>';
+ return '}).call(this);</script>';
},
- // Compile template into a function and attach to window.<namespace>
+ // Compile template into a function and attach it to ss.tmpl
process: function(template, path, id) {
- var compiledTemplate = hogan.compile(template, {asString: true});
+ var compiledTemplate;
+
+ try {
+ compiledTemplate = hogan.compile(template, {asString: true});
+ } catch (e) {
+ var message = '! Error compiling the ' + path + ' template into Hogan';
+ console.log(String.prototype.hasOwnProperty('red') && message.red || message);
+ throw new Error(e);
+ compiledTemplate = '<p>Error</p>';
+ }
- return 'window.' + namespace + '[\'' + id + '\'] = new Hogan.Template(' + compiledTemplate + ');';
+ return 't[\'' + id + '\']=new ht(' + compiledTemplate + ');';
}
}
}
```
-Here `prefix` and `suffix` are called one time each. In between those calls, `process` gets called for every file this template engine handles.
+Here `prefix` and `suffix` are called once each. In between those calls, `process` gets called for every file this template engine handles.
In this example, the wrapper is compiling templates on the server side, then passing the compiled templates to the client. The `prefix` and `suffix` functions wrap the compiled templates inside a `<script>` tag, so that the templates are ready to use when the page loads.
@@ -85,4 +99,4 @@ When building your own template wrapper be sure to consider the following points
Try to pick the best trade off between performance and overall bytes sent to the client, bearing in mind it's not uncommon for a large app to have 50 or more templates.
-If a client-side VM is needed to render the template (as is normally the case), be sure document this in your modules README file and provide a link. In the future we will make it possible to automatically send any client-side dependencies to the browser. Stay tuned.
+If a client-side VM is needed to render the template (as is normally the case) you should include the client code within your module and tell SocketStream to server it using the `ss.client.send()` command (see Hogan example above).
View
@@ -1,4 +1,4 @@
-var copy, dir_mode, fs, log, makeRootDirectory, path, util;
+var dir_mode, fs, log, makeRootDirectory, path, success, util;
log = console.log;
@@ -10,41 +10,122 @@ path = require('path');
util = require('util');
-copy = require('../utils/copy');
-
dir_mode = 0755;
exports.generate = function(program) {
- var copyOptions, name, source;
+ var appjs, codeExtension, cp, mkdir, mods, name, pacakgejs, selectedFormatters, source, viewExtension, write;
name = program.args[1];
if (name === void 0) {
return console.log("Please provide a name for your application: $> socketstream new <MyAppName>");
}
if (makeRootDirectory(name)) {
+ program.stylus = true;
source = path.join(__dirname, '/../../new_project');
- copyOptions = {
- exclude: {
- inPaths: ['/client/code/app', '/server/middleware', '/server/rpc'],
- extensions: [program.coffee && '.js' || '.coffee']
- }
+ codeExtension = program.coffee && 'coffee' || 'js';
+ viewExtension = program.jade && 'jade' || 'html';
+ selectedFormatters = [];
+ ['coffee', 'jade', 'less', 'stylus'].forEach(function(formatter) {
+ if (program[formatter]) return selectedFormatters.push(formatter);
+ });
+ mkdir = function(dir) {
+ return fs.mkdirSync(path.join(name, dir), dir_mode);
+ };
+ cp = function(src, dest) {
+ var destination, read, write;
+ destination = path.join(name, dest || src);
+ read = fs.createReadStream(path.join(source, src));
+ write = fs.createWriteStream(destination);
+ return util.pump(read, write);
+ };
+ write = function(fileName, content) {
+ return fs.writeFileSync(path.join(name, fileName), content, 'utf8');
};
- copy.recursiveCopy(source, name, copyOptions);
+ mkdir('/client');
+ mkdir('/client/code');
+ mkdir('/client/code/app');
+ mkdir('/client/code/libs');
+ mkdir('/client/views');
+ mkdir('/client/css');
+ mkdir('/client/css/libs');
+ mkdir('/client/templates');
+ mkdir('/client/static');
+ mkdir('/client/static/images');
+ mkdir('/server');
+ mkdir('/server/rpc');
+ mkdir('/server/middleware');
+ cp('/.gitignore');
+ cp('/.nodemonignore');
+ cp('/README.md');
+ cp('/client/static/favicon.ico');
+ cp('/client/code/libs/jquery.min.js');
+ cp("/client/code/app/entry." + codeExtension);
+ if (program.minimal) {
+ cp("/client/views/app.minimal." + viewExtension, "/client/views/app." + viewExtension);
+ cp("/client/code/app/app.minimal." + codeExtension, "/client/code/app/app." + codeExtension);
+ cp("/client/css/app.minimal.styl", "/client/css/app.styl");
+ } else {
+ cp('/client/static/images/logo.png');
+ cp("/client/code/app/app.demo." + codeExtension, "/client/code/app/app." + codeExtension);
+ cp("/server/middleware/example." + codeExtension);
+ cp("/server/rpc/demo." + codeExtension);
+ cp('/client/css/libs/reset.css');
+ cp("/client/css/app.demo.styl", "/client/css/app.styl");
+ cp('/client/css/demo.styl');
+ cp('/client/css/helpers.styl');
+ mkdir('/client/templates/chat');
+ cp("/client/templates/chat/message." + viewExtension);
+ cp("/client/views/app.demo." + viewExtension, "/client/views/app." + viewExtension);
+ }
+ appjs = "// My SocketStream app\n\nvar http = require('http')\n , ss = require('socketstream');\n\n// Define a single-page client\nss.client.define('main', {\n view: 'app." + viewExtension + "',\n css: ['libs', 'app.styl'],\n code: ['libs', 'app'],\n tmpl: '*'\n});\n\n// Serve this client on the root URL\nss.http.route('/', function(req, res){\n res.serveClient('main');\n})\n";
+ if (selectedFormatters.length > 0) appjs += "\n// Code Formatters\n";
+ selectedFormatters.forEach(function(name) {
+ return appjs += "ss.client.formatters.add(require('ss-" + name + "'));\n";
+ });
+ appjs += "\n// Use server-side compiled Hogan (Mustache) templates. Others engines available\nss.client.templateEngine.use(require('ss-hogan'));\n\n// Minimize and pack assets if you type: SS_ENV=production node app.js\nif (ss.env == 'production') ss.client.packAssets();\n\n// Start web server\nvar server = http.Server(ss.http.middleware);\nserver.listen(3000);\n";
+ if (program.repl) {
+ appjs += "\n// Start Console Server (REPL)\n// To install client: sudo npm install -g ss-console\n// To connect: ss-console <optional_host_or_port>\nvar consoleServer = require('ss-console').init(ss);\nconsoleServer.listen(5000);\n";
+ }
+ 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";
+ mods = selectedFormatters.concat(['hogan']);
+ if (program.repl) mods.push('console');
+ mods.forEach(function(name, i) {
+ if (i !== 0) pacakgejs += ",\n";
+ return pacakgejs += " \"ss-" + name + "\": \"0.1.x\"";
+ });
+ pacakgejs += "\n }\n}";
+ write('/package.json', pacakgejs);
log(("Success! Created app '" + name + "' with:").yellow);
- log("".green, "Our recommended stack of optional modules", "(minimal install option coming soon)".grey);
+ if (program.minimal) {
+ success("Minimal install (no demo)");
+ } else {
+ success("Basic chat demo", "(-m for minimal install)");
+ }
if (program.coffee) {
- log("".green, "CoffeeScript example code", "(-j if you prefer Javascript)".grey);
+ success("CoffeeScript example code");
+ } else {
+ success("Javascript example code", "(-c if you prefer CoffeeScript)");
+ }
+ if (program.jade) {
+ success("Jade for views");
} else {
- log("".green, "Javascript example code", "(-c if you prefer CoffeeScript)".grey);
+ success("Plain HTML for views", "(-j if you prefer Jade)");
}
+ if (program.repl) success("Console Server / REPL");
log("Next, run the following commands:".yellow);
- log(" cd " + name);
- log(" sudo npm install");
- log(" npm link socketstream", " (just until 0.3 is published to npm)".grey);
+ log(" cd " + name);
+ log(" sudo npm install");
+ log(" npm link socketstream", " (just until 0.3 is published to npm)".grey);
log("To start your app:".yellow);
- return log(" node app.js");
+ return log(" node app.js");
}
};
+success = function(name, alternative) {
+ return log("".green, name, (alternative || '').grey);
+};
+
makeRootDirectory = function(name) {
try {
fs.mkdirSync(name, dir_mode);
Oops, something went wrong.

0 comments on commit b6d3988

Please sign in to comment.