12 |
13 | ├── test ├── results │ └── .gitkeep ├── fixtures │ ├── files │ │ ├── random.js │ │ ├── view.html │ │ ├── view.jade │ │ ├── template.html │ │ ├── foo │ │ │ └── template2.html │ │ ├── template.foo │ │ └── template.const │ ├── project │ │ ├── more │ │ │ └── a │ │ │ │ ├── a.js │ │ │ │ ├── a.css │ │ │ │ └── a.html │ │ ├── client │ │ │ ├── abc │ │ │ │ ├── index.js │ │ │ │ ├── index.a │ │ │ │ ├── style.css │ │ │ │ ├── abc.html │ │ │ │ ├── ss.html │ │ │ │ ├── expected-with-abc-constants.html │ │ │ │ └── expected.html │ │ │ ├── code │ │ │ │ ├── main.js │ │ │ │ ├── extras │ │ │ │ │ ├── e1.js │ │ │ │ │ └── e2.js │ │ │ │ ├── kickoff │ │ │ │ │ └── entry.js │ │ │ │ ├── modules │ │ │ │ │ └── message.coffee │ │ │ │ └── main │ │ │ │ │ └── demo.coffee │ │ │ ├── workers │ │ │ │ └── pi.js │ │ │ ├── templates │ │ │ │ ├── main.html │ │ │ │ ├── abc │ │ │ │ │ ├── 1.html │ │ │ │ │ └── 2.html │ │ │ │ ├── 1.html │ │ │ │ └── chat │ │ │ │ │ └── message.jade │ │ │ ├── views │ │ │ │ ├── main2.html │ │ │ │ ├── 1.jade │ │ │ │ └── main.jade │ │ │ ├── static │ │ │ │ ├── assets │ │ │ │ │ └── info.txt │ │ │ │ ├── favicon.ico │ │ │ │ └── images │ │ │ │ │ ├── logo.png │ │ │ │ │ └── admin.jpg │ │ │ └── css │ │ │ │ ├── main.styl │ │ │ │ ├── helpers.styl │ │ │ │ ├── demo.styl │ │ │ │ └── libs │ │ │ │ └── reset.css │ │ ├── README │ │ ├── .gitignore │ │ ├── console.js │ │ ├── node_modules │ │ │ ├── socketstream-addon │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ │ ├── object-assign │ │ │ │ ├── index.js │ │ │ │ ├── license │ │ │ │ ├── readme.md │ │ │ │ └── package.json │ │ │ └── mock-socket │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ ├── server │ │ │ ├── middleware │ │ │ │ └── example.js │ │ │ └── rpc │ │ │ │ └── demo.js │ │ ├── package.json │ │ └── app.js │ ├── readDirSync │ │ ├── index.js │ │ ├── dir1 │ │ │ └── .gitkeep │ │ ├── dir2 │ │ │ └── index.html │ │ └── dir3 │ │ │ ├── .gitkeep │ │ │ ├── dir3.1 │ │ │ └── .gitkeep │ │ │ ├── dir3.2 │ │ │ ├── .gitkeep │ │ │ └── dir3.2.1 │ │ │ │ └── test.js │ │ │ └── dir3.3 │ │ │ ├── test.css │ │ │ ├── dir3.3.1 │ │ │ └── .gitkeep │ │ │ ├── dir3.3.2 │ │ │ └── test.csv │ │ │ └── dir3.3.3 │ │ │ └── test.sh │ ├── stubs │ │ ├── formatter_const.js │ │ ├── template_engine.js │ │ └── formatter_html.js │ ├── helpers │ │ └── function.js │ ├── socketstream.js │ └── index.js ├── e2e │ └── readme.md ├── unit │ ├── session │ │ └── cookie.test.js │ ├── client │ │ ├── servePacked.test.js │ │ ├── clientIssue.test.js │ │ ├── http.test.js │ │ ├── abcClient.js │ │ ├── template_engines │ │ │ ├── ember.test.js │ │ │ └── default.test.js │ │ ├── formatters │ │ │ ├── css.test.js │ │ │ ├── html.test.js │ │ │ └── javascript.test.js │ │ ├── bundler │ │ │ └── custom.test.js │ │ └── asset.test.js │ ├── websocket │ │ └── transports │ │ │ └── engineio │ │ │ └── wrapper.test.js │ ├── test │ │ └── test-socketstream.test.js │ ├── utils │ │ ├── log.test.js │ │ ├── unique_set.test.js │ │ └── require.test.js │ ├── cli │ │ └── index.test.js │ ├── tasks │ │ └── index.test.js │ └── request │ │ └── index.test.js └── helpers │ ├── utils.js │ ├── logHook.js │ └── uncache.js ├── new_project ├── server │ ├── rpc │ │ ├── .gitkeep │ │ ├── demo.coffee │ │ └── demo.js │ └── middleware │ │ ├── .gitkeep │ │ ├── example.coffee │ │ └── example.js ├── client │ ├── templates │ │ ├── .gitkeep │ │ └── chat │ │ │ ├── message.jade │ │ │ └── message.html │ ├── code │ │ └── app │ │ │ ├── app.minimal.coffee │ │ │ ├── app.minimal.js │ │ │ ├── entry.coffee │ │ │ ├── entry.js │ │ │ ├── app.demo.coffee │ │ │ └── app.demo.js │ ├── static │ │ ├── favicon.ico │ │ └── images │ │ │ └── logo.png │ ├── css │ │ ├── app.minimal.styl │ │ ├── app.minimal.less │ │ ├── app.minimal.css │ │ ├── libs │ │ │ └── reset.css │ │ ├── app.demo.styl │ │ ├── app.demo.css │ │ └── app.demo.less │ └── views │ │ ├── app.minimal.jade │ │ ├── app.minimal.html │ │ ├── app.demo.jade │ │ └── app.demo.html ├── README.md ├── scm_ignore_file └── node_monitor_ignore_file ├── .npmignore ├── .hound.yml ├── docs ├── font │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── partials │ ├── api │ │ ├── bundler.html │ │ ├── utils.html │ │ ├── ss.server.server.html │ │ ├── ss.html │ │ ├── events.html │ │ ├── ss.version.html │ │ ├── client.html │ │ ├── ss.env.html │ │ ├── ss.root.html │ │ ├── start.html │ │ ├── set.html │ │ ├── client.task.html │ │ ├── ss.add.html │ │ ├── client.define.html │ │ ├── client.formatters.formatters.html │ │ └── ss.client.client.html │ ├── demos │ │ └── index.html │ └── tutorials │ │ ├── http_middleware.html │ │ ├── hot_to_test.html │ │ ├── how_to_write_css.html │ │ ├── modules.html │ │ ├── client_side_development.html │ │ ├── url_scheme.html │ │ ├── start_targets.html │ │ ├── serving_http_resources.html │ │ ├── choosing_protocol.html │ │ ├── client_side_constants.html │ │ ├── loading_assets_on_demand.html │ │ └── web_workers.html └── css │ ├── animations.css │ └── prettify.css ├── src └── docs │ ├── tutorials │ ├── ko │ │ ├── loading_assets_on_demand.md │ │ └── live_reload.md │ ├── en │ │ ├── http_middleware.ngdoc │ │ ├── hot_to_test.ngdoc │ │ ├── how_to_write_css.ngdoc │ │ ├── modules.ngdoc │ │ ├── client_side_development.ngdoc │ │ ├── url_scheme.ngdoc │ │ ├── start_targets.ngdoc │ │ ├── serving_http_resources.ngdoc │ │ ├── choosing_protocol.ngdoc │ │ ├── how_to_write_a_formatter.ngdoc │ │ ├── live_reload.ngdoc │ │ ├── client_side_constants.ngdoc │ │ ├── loading_assets_on_demand.ngdoc │ │ └── web_workers.ngdoc │ └── index.ngdoc │ ├── site │ └── header.html │ └── demos │ └── index.ngdoc ├── index.js ├── .gitignore ├── lib ├── websocket │ ├── subscriptions.js │ ├── transports │ │ └── engineio │ │ │ └── .jshintrc │ ├── transport.js │ ├── event_dispatcher.js │ └── index.js ├── client │ ├── template_engines │ │ ├── ember.js │ │ ├── angular.js │ │ └── default.js │ ├── formatters │ │ ├── css.js │ │ ├── javascript.js │ │ ├── map.js │ │ ├── html.js │ │ ├── jade.js │ │ └── sass.js │ ├── view.js │ ├── bundler │ │ └── production.js │ └── formatters.js ├── publish │ ├── transports │ │ ├── internal.js │ │ └── redis.js │ └── transport.js ├── cli │ └── index.js ├── request │ ├── middleware │ │ ├── index.js │ │ └── internal.js │ ├── responders │ │ ├── events │ │ │ ├── index.js │ │ │ └── client.js │ │ └── rpc │ │ │ └── client.js │ └── index.js ├── tasks │ └── live_reload.js ├── session │ ├── store.js │ └── channels.js └── utils │ └── misc.js ├── .gitconfig ├── .travis.yml ├── .editorconfig ├── gulp.js ├── bin └── socketstream ├── .jshintignore ├── .javascript.json ├── express.js ├── misc └── changelog.tpl.md ├── LICENSE └── .jshintrc /test/results/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /new_project/server/rpc/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/files/random.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/files/view.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/files/view.jade: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/project/more/a/a.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /new_project/client/templates/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /new_project/server/middleware/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/project/more/a/a.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir1/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir2/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/dir3.1/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/dir3.2/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/dir3.3/test.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/project/client/abc/index.js: -------------------------------------------------------------------------------- 1 | // test 2 | -------------------------------------------------------------------------------- /test/fixtures/project/client/code/main.js: -------------------------------------------------------------------------------- 1 | // main 2 | -------------------------------------------------------------------------------- /new_project/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to your new realtime app -------------------------------------------------------------------------------- /test/fixtures/files/template.html: -------------------------------------------------------------------------------- 1 |
{{ content }}
2 | -------------------------------------------------------------------------------- /test/fixtures/project/client/workers/pi.js: -------------------------------------------------------------------------------- 1 | // calc pi 2 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/dir3.2/dir3.2.1/test.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/dir3.3/dir3.3.1/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/dir3.3/dir3.3.2/test.csv: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/readDirSync/dir3/dir3.3/dir3.3.3/test.sh: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/files/foo/template2.html: -------------------------------------------------------------------------------- 1 | {{ content }} 2 | -------------------------------------------------------------------------------- /test/fixtures/files/template.foo: -------------------------------------------------------------------------------- 1 | Random template content. 2 | -------------------------------------------------------------------------------- /test/fixtures/project/README: -------------------------------------------------------------------------------- 1 | # Welcome to your new realtime app -------------------------------------------------------------------------------- /test/fixtures/project/client/abc/index.a: -------------------------------------------------------------------------------- 1 | 2 | // index.a 3 | -------------------------------------------------------------------------------- /test/fixtures/project/client/code/extras/e1.js: -------------------------------------------------------------------------------- 1 | var e1 = 1; 2 | -------------------------------------------------------------------------------- /test/fixtures/project/client/code/extras/e2.js: -------------------------------------------------------------------------------- 1 | var e2 = 2; 2 | -------------------------------------------------------------------------------- /test/fixtures/files/template.const: -------------------------------------------------------------------------------- 1 | Some more random content. 2 | -------------------------------------------------------------------------------- /test/fixtures/project/client/templates/main.html: -------------------------------------------------------------------------------- 1 |ABC
4 | 5 | -------------------------------------------------------------------------------- /new_project/scm_ignore_file: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | node_modules 4 | dump.rdb 5 | npm-debug.log 6 | tmp 7 | client/static/assets 8 | -------------------------------------------------------------------------------- /new_project/client/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangnie/socketstream/develop/new_project/client/static/favicon.ico -------------------------------------------------------------------------------- /new_project/client/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangnie/socketstream/develop/new_project/client/static/images/logo.png -------------------------------------------------------------------------------- /test/fixtures/project/client/abc/ss.html: -------------------------------------------------------------------------------- 1 | 2 |ABC
4 | 5 | -------------------------------------------------------------------------------- /new_project/client/templates/chat/message.html: -------------------------------------------------------------------------------- 1 |2 | {{time}} 3 | 4 |
5 | -------------------------------------------------------------------------------- /new_project/client/css/app.minimal.styl: -------------------------------------------------------------------------------- 1 | // Example Stylus file 2 | 3 | body, html 4 | min-height 100% 5 | 6 | body 7 | font normal 1em sans-serif 8 | -------------------------------------------------------------------------------- /src/docs/tutorials/ko/loading_assets_on_demand.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangnie/socketstream/develop/src/docs/tutorials/ko/loading_assets_on_demand.md -------------------------------------------------------------------------------- /test/fixtures/project/client/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangnie/socketstream/develop/test/fixtures/project/client/static/favicon.ico -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // Initial entry point. Decides which directory of code to load 2 | 3 | // Load SocketStream core 4 | module.exports = require('./lib/socketstream.js'); -------------------------------------------------------------------------------- /test/fixtures/project/client/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangnie/socketstream/develop/test/fixtures/project/client/static/images/logo.png -------------------------------------------------------------------------------- /src/docs/site/header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/project/client/static/images/admin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangnie/socketstream/develop/test/fixtures/project/client/static/images/admin.jpg -------------------------------------------------------------------------------- /new_project/client/css/app.minimal.less: -------------------------------------------------------------------------------- 1 | // Example Less file 2 | 3 | body, html { 4 | min-height: 100%; 5 | } 6 | 7 | body { 8 | font: normal 1em sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /new_project/client/css/app.minimal.css: -------------------------------------------------------------------------------- 1 | // Example CSS file 2 | 3 | body, 4 | html { 5 | min-height: 100%; 6 | } 7 | 8 | body { 9 | font: normal 1em sans-serif; 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | coverage 3 | /node_modules 4 | dump.rdb 5 | npm-debug.log 6 | *.tgz 7 | /docs.js 8 | test/fixtures/project/client/static/assets/abc 9 | .idea 10 | .settings 11 | -------------------------------------------------------------------------------- /test/fixtures/project/client/abc/expected-with-abc-constants.html: -------------------------------------------------------------------------------- 1 | 2 |ABC
5 | 6 | -------------------------------------------------------------------------------- /new_project/client/views/app.minimal.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en") 3 | head 4 | meta(charset="utf-8") 5 | != SocketStream 6 | title Welcome 7 | body 8 | p Welcome to your new realtime app! -------------------------------------------------------------------------------- /test/fixtures/project/client/abc/expected.html: -------------------------------------------------------------------------------- 1 | 2 |ABC
5 | 6 | -------------------------------------------------------------------------------- /test/unit/session/cookie.test.js: -------------------------------------------------------------------------------- 1 | var cookieParser = require('cookie-parser'), 2 | fixtures = require('../../fixtures'), 3 | ss = fixtures.socketstreamProject(); 4 | 5 | describe('session', function() { 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /src/docs/demos/index.ngdoc: -------------------------------------------------------------------------------- 1 | @ngdoc overview 2 | @name index 3 | @description 4 | 5 | # Demos 6 | 7 | - http://demo.socketstream.org/ - official project's demo 8 | - http://dashku.com - Realtime dashboards and widgets with HTML, CSS, and Javascript. -------------------------------------------------------------------------------- /new_project/client/views/app.minimal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |Welcome to your new realtime app!
10 | 11 | -------------------------------------------------------------------------------- /new_project/server/middleware/example.coffee: -------------------------------------------------------------------------------- 1 | # Example request middleware 2 | 3 | # Only let a request through if the session has been authenticated 4 | exports.authenticated = -> 5 | (req, res, next) -> 6 | if req.session && req.session.userId? 7 | next() 8 | else 9 | res(false) 10 | -------------------------------------------------------------------------------- /new_project/node_monitor_ignore_file: -------------------------------------------------------------------------------- 1 | # Ignore file for Nodemon: https://github.com/remy/nodemon 2 | # Install with 'npm install -g nodemon' then start your app with 'nodemon app.js' 3 | # From then on, all changes you make to /server will cause your app to automatically restart 4 | 5 | /client/* 6 | ./README.md 7 | .git 8 | -------------------------------------------------------------------------------- /test/fixtures/project/client/code/modules/message.coffee: -------------------------------------------------------------------------------- 1 | # Example Message Module 2 | 3 | # Send a message to the server 4 | exports.send = (text, cb) -> 5 | if valid(text) 6 | ss.rpc('demo.sendMessage', text, cb) 7 | else 8 | cb(false) 9 | 10 | 11 | # Private 12 | 13 | valid = (text) -> 14 | text && text.length > 0 -------------------------------------------------------------------------------- /test/unit/client/servePacked.test.js: -------------------------------------------------------------------------------- 1 | describe('packed client',function() { 2 | 3 | it('should be served when option servePacked or packAssets set'); 4 | 5 | it('should serve JS ondemand within bounds defined'); 6 | 7 | it('should serve worker JS in definitions'); 8 | 9 | it('should include libs in client'); 10 | }); 11 | -------------------------------------------------------------------------------- /test/fixtures/project/console.js: -------------------------------------------------------------------------------- 1 | // Interactive console for testing sending of events etc 2 | // TODO: Find a way to give access to Websocket Message Responders here 3 | 4 | var repl = require('repl') 5 | , ss = require('socketstream'); 6 | 7 | ss.start(); 8 | 9 | var cmd = repl.start('SocketStream > '); 10 | 11 | cmd.context.ss = ss.api; -------------------------------------------------------------------------------- /test/fixtures/project/node_modules/socketstream-addon/index.js: -------------------------------------------------------------------------------- 1 | module.exports = function(ss) { 2 | var strategy = { 3 | sessionMiddleware: sessionMiddleware, 4 | 5 | create: function() { 6 | return {}; 7 | } 8 | }; 9 | ss.session.setStrategy(strategy); 10 | 11 | function sessionMiddleware(req,res,next) { 12 | return next(); 13 | } 14 | 15 | }; -------------------------------------------------------------------------------- /test/fixtures/stubs/formatter_const.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // Plain HTML Formatter 3 | 4 | var fs; 5 | 6 | fs = require('fs'); 7 | 8 | exports.init = function() { 9 | return { 10 | extensions: ['const'], 11 | assetType: 'html', 12 | contentType: 'text/html', 13 | compile: function(path, options, cb) { 14 | return cb('CONST'); 15 | } 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /lib/websocket/subscriptions.js: -------------------------------------------------------------------------------- 1 | // Websocket ID subscriptions 2 | // -------------------------- 3 | // Stores a list of which socket IDs are subscribed to which users or channels 4 | // and delivers events accordingly 5 | 'use strict'; 6 | 7 | var UniqueSet = require('../utils/unique_set').UniqueSet; 8 | 9 | module.exports = { 10 | user: new UniqueSet, 11 | channel: new UniqueSet 12 | }; 13 | -------------------------------------------------------------------------------- /new_project/server/middleware/example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // Example request middleware 3 | 4 | // Only let a request through if the session has been authenticated 5 | exports.authenticated = function() { 6 | return function(req, res, next) { 7 | if (req.session && (req.session.userId != null)) { 8 | return next(); 9 | } else { 10 | return res(false); 11 | } 12 | }; 13 | }; -------------------------------------------------------------------------------- /.gitconfig: -------------------------------------------------------------------------------- 1 | [color] 2 | branch = auto 3 | diff = auto 4 | status = auto 5 | [color "branch"] 6 | current = yellow reverse 7 | local = yellow 8 | remote = green 9 | [color "diff"] 10 | meta = yellow bold 11 | frag = magenta bold 12 | old = red bold 13 | new = green bold 14 | [color "status"] 15 | added = yellow 16 | changed = green 17 | untracked = cyan 18 | -------------------------------------------------------------------------------- /test/fixtures/project/server/middleware/example.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // Example request middleware 3 | 4 | // Only let a request through if the session has been authenticated 5 | exports.authenticated = function() { 6 | return function(req, res, next) { 7 | if (req.session && (req.session.userId != null)) { 8 | return next(); 9 | } else { 10 | return res(false); 11 | } 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.12 4 | - 4 5 | - 6 6 | 7 | cache: 8 | directories: 9 | - node_modules 10 | 11 | before_install: 12 | - npm install --upgrade npm -g 13 | 14 | script: 15 | - npm run cover-test 16 | 17 | notifications: 18 | webhooks: 19 | urls: 20 | - https://webhooks.gitter.im/e/7937aa9d2e9d767d0421 21 | on_success: always 22 | on_failure: always 23 | -------------------------------------------------------------------------------- /test/fixtures/stubs/template_engine.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.init = function(name) { 4 | return { 5 | name: name, 6 | prefix: function() { 7 | return '<' + this.name + '::prefix>'; 8 | }, 9 | suffix: function() { 10 | return '<' + this.name + '::suffix>'; 11 | }, 12 | process: function(template, path, id) { 13 | return '[' + id + '::' + template + ']'; 14 | } 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /lib/client/template_engines/ember.js: -------------------------------------------------------------------------------- 1 | // Produces templates for Ember.js 2 | // Note Ember compiles these Handlebars templates one time only when you call Em.Application.create(); 3 | 'use strict'; 4 | 5 | exports.init = function() { 6 | return { 7 | name: 'Ember.js', 8 | process: function(template, path, id) { 9 | return ''; 10 | } 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/stubs/formatter_html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Plain HTML Formatter 3 | */ 4 | 5 | 'use strict'; 6 | 7 | var fs; 8 | 9 | fs = require('fs'); 10 | 11 | exports.init = function() { 12 | return { 13 | extensions: ['html'], 14 | assetType: 'html', 15 | contentType: 'text/html', 16 | compile: function(path, options, cb) { 17 | var input; 18 | input = fs.readFileSync(path, 'utf8'); 19 | return cb(input); 20 | } 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/project/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my_realtime_app", 3 | "description": "An awesome real time application", 4 | "version": "0.0.1", 5 | "author": "Mebundler
2 | Bundlers included.
7 |
2 | utils
2 | Contains utils modules for working with file system and some additional helpers
7 |server
2 | ss
3 |
4 | Server parts used while running
8 |
2 | It reflects a similar API to the client API.
6 |Internal API object which is passed to sub-modules and can be used within your app. 7 | Use with caution.
8 |To access it without it being passed var ss = require('socketstream').api;
2 | SocketStream no longer provides a stack of Connect HTTP middleware which is used internally to serve single-page clients, asset files and static files (e.g. images) in client/static.
Session handling is done in add-ons like socketstream-cookie-session.
For additional middleware follow the examples for Connect or ExpressJS.
9 |events
2 | Internal Event bus.
7 |Note: only used by the ss-console module for now. This idea will be expended upon in SocketStream 0.4
8 |'server:start' is emitted when the server starts. If in production the assets will be saved before the event.
9 |
12 |
13 | version
2 | ss
3 |
4 | client
2 | One or more clients are defined and will be served in production as a single HTML, CSS, and JS file.
8 |This is for the module returned by require('socketstream').client.
env
2 | ss
3 |
4 | ss.env8 |
| string | Execution environment type. To change set environment variable |
root
2 | ss
3 |
4 | By default the project root is the current working directory
8 |start
2 | Starts the development or production server
7 |new start(server);10 |
| Param | Type | Details |
|---|---|---|
| server | HTTPServer | Instance of the server from the http module 11 | |
2 | You can make automated test for your server code with Mocha or a similar framework.
7 |A simple test found in the demo app looks like,
8 |var ss,
9 | chai = require("chai"),
10 | expect = chai.expect;
11 |
12 | describe('Demo', function() {
13 | beforeEach(function(done) {
14 | ss = require("socketstream").start('test-socketstream',done);
15 | });
16 |
17 | describe('sendMessage', function() {
18 | it('should publish messages received', function(done) {
19 | var text = 'Hello World!';
20 | ss.rpc('demo.sendMessage', text, function(res) {
21 | expect(res).to.equal([true]);
22 | })
23 | });
24 | });
25 | });
26 |
2 | Views can be styles using plain CSS, Less, SASS or any other supported by CSS formatters.
7 |The CSS formatter is added automatically. Formatters for Less and SASS are builtin, but must
8 | be added and the core dependency added to your package.json.
npm install sass --save-dev
10 | The SASS formatter is now builtin but optional. Add the following line to your app.
11 |ss.client.formatters.add('sass');
12 | By default the includePaths option is the node_modules and the client directory.
13 | If you want to change it you can override it.
ss.client.formatters.add('sass', {
15 | includePaths: [ path.join(__dirname,'client','sass')]
16 | });
17 | set
2 | Overrides settings for root/client/server.
7 |
2 | During development the bundlers, formatters and template engines are loaded as plugins using ss.require. This allows you to not require development time code in your app.js. If you choose to build production assets beforehand, you can keep these dependencies as development dependencies and only install production dependencies.
The internal require is used to load modules that may be built in or supplied by the project. It is a function on the API passed to plugins and used internally.
10 |ss.require(id,builtinPath,defaultId) The builtin path is the relative path within socketstream
11 | where the builtin modules are found. The defaultId is the extension-less filename loaded when the main id isn't matched.
task
2 | client
3 |
4 | add
2 | ss
3 |
4 | Call from your app to safely extend the 'ss' internal API object passed through to your /server code
8 |
2 | Each view is served with a separate bundle of assets. A HTML, JS and CSS file makes up the view.
7 |The production form will,
8 |assets (configurable) directory and served under the /assets path.assets/<name>/<id>.<type>.Each of the entries that make of the bundles are served separately to the browser while developing.
15 |name part of the path.The URL pattern is http:///assets/<name>/<id>.<type>?_=<entry_path>.
Bundlers generally work within the client directory to reduce the amount of files to watch. The path 23 | of entries is normally resolved relative to the client directory.
24 |define
2 | client
3 |
4 | Define a client view to serve.
8 |ss.http.route('/my-view', function(req,res)
9 | res.serveClient('my-view');
10 | });
11 |
2 | The common URL for a view is its name at the root level, but you can choose whatever you will calling serveClient(..).
The contents of the client assets directory will be served under /assets.
When views are packed for production they are saved under the client assets directory. This will change in the future 10 | to make relative URLs work the same in development and production.
11 |At development time middleware is added to serve HTML, JS and CSS on the fly.
13 |CSS files are served under /assets/
The current on-demand fetching of JS is handled by middleware. It should be possible to do it using static files.
19 |In production it would make sense to support a path like /assets/require/...
We will have to consider whether all client code is considered completely open, or only partially. Should all client 21 | modules be exported in minified form, or only those in a whitelist.
22 |formatters
2 | client
3 |
4 | This is for the module returned by require('socketstream').client.formatters.
ABC
\n\n'); 45 | },function(err) { 46 | should(err).be.equal(undefined); 47 | }); 48 | }); 49 | 50 | describe('if header options are passed', function () { 51 | 52 | it('should replace any
2 | When SocketStream is started in runs on an Orchestrator just like the build tool Gulp.
7 |Note that this interface is experimental and may change
8 |The default target will build assets and start a web server as needed. If other named targets
10 | are specified they will be started instead.
To start your socketstream project with different build targets specify them after the server 12 | object, or instead if you do not want to run the streaming server.
13 |// Start web server
14 | var server = http.Server(ss.http.middleware);
15 | server.listen(3000);
16 |
17 | // Start SocketStream
18 | ss.start(server,'my-task','serve');
19 | The default task depends on
21 |pack-all/pack-if-needed if using packed assetslive-assets if not using packed assetslive-reload if live reload is enabled (true by default) serve-on-demandIf you want to react when things happen around tasks you can register event handlers. 29 | The tasks are managed by Orchestrator which manages tasks in Gulp.
30 |Register events on ss.api.orchestrator
31 |
2 | With Mobile phones being the new king of personal communication it is crucial for your website to work more like 7 | and application and less like a centralised portal. It is crucial to work in an online/offline world.
8 |SocketStream has until now had an event based Router. In 0.5 this is being replaced. Routing will come back in some other form in 1.0
9 |The aim is to push assets and content to edge caches and ideally directly onto the client devices. This means that the content of your 10 | application must be identified so it can be push out before it is needed, so the traditional Connect/Express model pulls you in the wrong direction.
11 |That being said the paradigm of defining REST resources is a very good one and fits into where the we is and will be going with HTTP version 2. 12 | So you should continue to define your content with URL semantics. Go ahead and base your implementation on Connect/Express middleware. 13 | We've prepared some examples for you for 14 | Express and 15 | Connect.
16 |In the future Express apps will be extended with semantics for real-time endpoints. Permissions will be span both HTTP, streaming and 17 | client side semantics.
18 |For this reason the use of middlewares are likely to change. ss.http.middleware still mostly works but is deprecated.
16 | ss.client.packAssets(); 17 |18 | As you typically would in `production` mode. 19 | 20 | 21 | ### Known issues 22 | 23 | #### VIM 24 | 25 | VIM creates a temporary file before replacing the real file. To prevent problems with Live Reload, change the write mode with: 26 |
27 | :set nowritebackup 28 |29 | 30 | #### Too many files 31 | 32 | Live Reload is built on Node's `fs.watch()` API which works differently on each operating system. For example, on Linux you'll get an `EMFILE` error if you have many files in your `client` directory. Change this limit with: 33 |
34 | sudo vi /etc/sysctl.conf 35 |36 | add the following line 37 |
38 | fs.inotify.max_user_instances = 200 # or higher if needed 39 |40 | then run 41 |
42 | sudo sysctl -p 43 |44 | If things still don't work as expected, please log an issue and be sure to mention which OS you're using. 45 | 46 | 47 | ### Options 48 | 49 | To disable Live Reload, even in development mode, put the following in your `app.js` code: 50 |
51 | ss.client.set({liveReload: false})
52 |
53 | Alternatively, you may specify the top-level directories within `/client` you wish Live Reload to observe. E.g.:
54 |
55 | ss.client.set({liveReload: ['views', 'css'])
56 |
--------------------------------------------------------------------------------
/lib/request/index.js:
--------------------------------------------------------------------------------
1 | // Request Responders
2 | // ------------------
3 | // Processes incoming requests regardless of transport (e.g. websocket, HTTP, method call from console)
4 | // Each responder can expose a number of interfaces - e.g. Websocket, Console, and will only respond to incoming
5 | // messages of it's type (e.g. 'rpc', 'events', etc)
6 | // Responders can optionally choose to use the middleware stack provided
7 | // The 'events' and 'rpc' responders are loaded by default, though even this can be overruled by calling clear()
8 | 'use strict';
9 |
10 | module.exports = function(ss) {
11 | var middleware = require('./middleware')(ss),
12 | responderCount = 0,
13 | responders = {},
14 | useDefaults = true;
15 |
16 | return {
17 | clear: function() {
18 | //jshint -W093
19 | return (useDefaults = false);
20 | },
21 | add: function(nameOrModule, config) {
22 | config = config || null;
23 | var mod = ss.require(nameOrModule, 'request/responders',function(err) {
24 | throw new Error('Unable to find the \''+err.id+'\' Request Responder internally');
25 | });
26 |
27 | try {
28 | var id = nameOrModule === 'events' && '0' || ++responderCount;
29 | //jshint -W093
30 | return (responders[id] = mod(id, config, ss));
31 | } catch (e) {
32 | var responderName = responders[id] && responders[id].name || '',
33 | err = new Error('Unable to initialize Request Responder \'' + responderName + '\'');
34 | err.stack = e.stack;
35 | throw e;
36 | }
37 | },
38 | load: function() {
39 | var middlewareStack = middleware.load();
40 | if (useDefaults) {
41 | this.add('events');
42 | this.add('rpc');
43 | }
44 | var output = {};
45 | for (var id in responders) {
46 | var responder = responders[id];
47 | output[id] = {
48 | name: responder.name,
49 | interfaces: responder.interfaces(middlewareStack)
50 | };
51 | }
52 | return output;
53 | }
54 | };
55 | };
56 |
--------------------------------------------------------------------------------
/src/docs/tutorials/en/client_side_constants.ngdoc:
--------------------------------------------------------------------------------
1 | @ngdoc overview
2 | @name Client-Side Constants
3 |
4 | @description
5 | # Client-Side Constants
6 |
7 | When you load the view in the browser, constants will be defined as global variables, so they can be
8 | accessed anywhere by their name.
9 |
10 | To define a constant add it under `consts:` in the view definition.
11 |
12 | ss.client.define('myview',{
13 | view: 'myview.html',
14 | consts: {
15 | appConfig: {
16 | facebookAppId: '1234',
17 | twitterKey: 'AAA'
18 | }
19 | }
20 | });
21 |
22 | The constants will only be loaded in the view. Other views will not be affected.
23 |
24 | You can also define a global constant using `ss.client.send`. In this case the constant will be loaded
25 | in all views. In case you have a constant in a view definition with the same name, it will be
26 | used rather than the global value.
27 |
28 | ## Locals
29 |
30 | When you write HTML and CSS you often want to use a common value which isn't defined in the source code,
31 | but rather in configuration. Version number and copyright are good examples of these, so are color values,
32 | debugging environment and level of browser support.
33 |
34 | Following convention these are called locals. They are not available as variables in the browser. That is unless
35 | your formatter expose them as such. They are however passed to the template_engines and formatters.
36 |
37 | To define a local add it under `locals:` in the view defintion.
38 |
39 | ss.client.define('myview',{
40 | view: 'myview.html',
41 | locals: {
42 | appConfig: {
43 | copyright: '1999'
44 | }
45 | }
46 | });
47 |
48 | The locals will only be passed when rendering that view. Other views will not be affected.
49 |
50 | You can also define a global local(yes, naming sucks) using `ss.client.send`. In this case the local will be
51 | used in all views. In case you have a local in a view definition with the same name, it will be
52 | used rather than the global value.
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/docs/tutorials/en/loading_assets_on_demand.ngdoc:
--------------------------------------------------------------------------------
1 | @ngdoc overview
2 | @name Loading Assets On Demand
3 |
4 | @description
5 | # Loading Assets On Demand
6 |
7 | If you're writing a small app you can safely ignore this section, as it's always better to pack all client assets into one file and send everything through together in one go if possible.
8 |
9 | But what if you're writing a large app, or an app with multiple distinct sections like iCloud.com?
10 |
11 | SocketStream allows you to load code (and other assets in the future) into your app asynchronously on demand.
12 |
13 |
14 | ### Loading Code
15 |
16 | Sadly it's not possible to directly `require()` modules which haven't been loaded as the blocking nature of the `require` function means the browser would freeze until the module has been retrieved from the server - not good.
17 |
18 | However SocketStream allows you to load additional code modules from the server asynchronously using the built-in `ss.load.code()` command. Once all the code you've requested has been loaded, we execute a callback, allowing you to `require()` the new modules as normal without any fancy syntax.
19 |
20 | To try this out, create a new directory of application modules in `/client/code`. For the sake of this example, let's call our new directory `/client/code/mail`. We'll also assume this directory has a module in it called `search.js`.
21 |
22 |
23 | // in any client-side module
24 | ss.load.code('/mail', function(){
25 |
26 | // all modules in /client/code/mail have now been loaded into
27 | // the root namespace (/) and can be required in the normal way
28 | var search = require('/search');
29 |
30 | });
31 |
32 |
33 | Note: Regardless of the directory you load, the modules inside will always be loaded into the root (/) namespace by default. If you want to mount the new modules in a different namespace, just create one or more sub-directories in the folder you're loading.
34 |
35 |
36 | ### Automatic Caching
37 |
38 | Modules are only ever retrieved from the server once. Subsequent requests for the same directory will be returned instantly without contacting the server.
--------------------------------------------------------------------------------
/test/fixtures/project/node_modules/object-assign/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "object-assign",
3 | "version": "4.0.1",
4 | "description": "ES6 Object.assign() ponyfill",
5 | "license": "MIT",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/sindresorhus/object-assign.git"
9 | },
10 | "author": {
11 | "name": "Sindre Sorhus",
12 | "email": "sindresorhus@gmail.com",
13 | "url": "http://sindresorhus.com"
14 | },
15 | "engines": {
16 | "node": ">=0.10.0"
17 | },
18 | "scripts": {
19 | "test": "xo && mocha",
20 | "bench": "matcha bench.js"
21 | },
22 | "files": [
23 | "index.js"
24 | ],
25 | "keywords": [
26 | "object",
27 | "assign",
28 | "extend",
29 | "properties",
30 | "es6",
31 | "ecmascript",
32 | "harmony",
33 | "ponyfill",
34 | "prollyfill",
35 | "polyfill",
36 | "shim",
37 | "browser"
38 | ],
39 | "devDependencies": {
40 | "lodash": "^3.10.1",
41 | "matcha": "^0.6.0",
42 | "mocha": "*",
43 | "xo": "*"
44 | },
45 | "xo": {
46 | "envs": [
47 | "node",
48 | "mocha"
49 | ]
50 | },
51 | "gitHead": "b0c40d37cbc43e89ad3326a9bad4c6b3133ba6d3",
52 | "bugs": {
53 | "url": "https://github.com/sindresorhus/object-assign/issues"
54 | },
55 | "homepage": "https://github.com/sindresorhus/object-assign#readme",
56 | "_id": "object-assign@4.0.1",
57 | "_shasum": "99504456c3598b5cad4fc59c26e8a9bb107fe0bd",
58 | "_from": "object-assign@*",
59 | "_npmVersion": "2.13.3",
60 | "_nodeVersion": "3.0.0",
61 | "_npmUser": {
62 | "name": "sindresorhus",
63 | "email": "sindresorhus@gmail.com"
64 | },
65 | "dist": {
66 | "shasum": "99504456c3598b5cad4fc59c26e8a9bb107fe0bd",
67 | "tarball": "http://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz"
68 | },
69 | "maintainers": [
70 | {
71 | "name": "sindresorhus",
72 | "email": "sindresorhus@gmail.com"
73 | }
74 | ],
75 | "directories": {},
76 | "_resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz",
77 | "readme": "ERROR: No README data found!"
78 | }
79 |
--------------------------------------------------------------------------------
/docs/partials/tutorials/choosing_protocol.html:
--------------------------------------------------------------------------------
1 | Improve this doc
2 | The state of web protocols is such that WebSockets are supported on perhaps 90% of the devices that reach your
7 | website. The first question you have to ask yourself is what to do about the last 10%. You can ignore them and
8 | configure SocketStream to only use WebSockets for streaming connections. This is an option that will be added
9 | in version 0.7 and be stable in 0.8.
Otherwise you can support 100% of devices with fallback protocols such as "engine.io" or "SockJS". They are both 11 | mature but with different approaches. SockJS tries to open a WebSocket and fall backs to various polling techniques 12 | if it cannot. Engine.io starts with polling and tries to upgrade ultimately to a WebSocket connection. So for 13 | 90% of devices SockJS will connect faster.
14 |However engine.io supports compression and binary data, so you may push more data to the client. This may not 15 | be relevant for your application, so both are good options.
16 |For streaming connections it is also important to consider Internet proxies and gateways. Many firewalls only let 17 | through HTTP and stops all other protocols. To support this you cannot use straight WebSockets as the fallback 18 | mechanisms must always be used.
19 |Over the next year HTTP version 2 will become supported in most web browsers and web servers. It allows some 20 | advanced data caching techniques that can be used to achieve Real-Time data streaming to clients over HTTP.
21 |Hopefully we will be able to extend SocketStream with the ability to stream over HTTP/2.
22 |Another interesting candidate is WebRTC which allows browsers to talk to each other. This might also be fitted 23 | into the Real-Time puzzle.
24 |
27 | // in /client/workers/pi.js
28 |
29 | self.addEventListener('message', function(e) {
30 | var cycles = e.data;
31 | postMessage("Calculating Pi using " + cycles + " cycles");
32 | var numbers = calculatePi(cycles);
33 | postMessage("Result: " + numbers);
34 | }, false);
35 |
36 | function calculatePi(cycles) {
37 | var pi = 0;
38 | var n = 1;
39 | for (var i=0; i <= cycles; i++) {
40 | pi = pi + (4/n) - (4 / (n+2));
41 | n = n + 4;
42 | }
43 | return pi;
44 | }
45 |
46 |
47 | Then, in any client-side code file, invoke the worker.
48 |
49 |
50 | // in any /client/code file
51 | var worker = ss.load.worker('/pi.js');
52 |
53 | // print output to console
54 | worker.addEventListener('message', function(e) {
55 | console.log(e.data);
56 | });
57 |
58 | // start worker with 10000000 cycles
59 | worker.postMessage(10000000);
60 |
61 |
62 | A few seconds after the task has run you should see the output in the browser's console:
63 |
64 | Calculating Pi using 10000000 cycles
65 | Result: 3.1415926485894077
66 |
67 | Experiment with running more cycles and passing different messages.
68 |
--------------------------------------------------------------------------------
/src/docs/tutorials/index.ngdoc:
--------------------------------------------------------------------------------
1 | @ngdoc overview
2 | @name index
3 | @description Documentation
4 |
5 | ##### Developing (Client-side)
6 |
7 | * [Client-side Code](http://socketstream.github.io/socketstream/docs/#/tutorials/client_side_code)
8 | * [Client-side Templates](http://socketstream.github.io/socketstream/docs/#/tutorials/client_side_templates)
9 | * [Defining multiple Single-Page Clients](http://socketstream.github.io/socketstream/docs/#/tutorials/defining_multiple_clients)
10 | * [Loading Assets On Demand](http://socketstream.github.io/socketstream/docs/#/tutorials/loading_assets_on_demand)
11 | * [Live Reload](http://socketstream.github.io/socketstream/docs/#/tutorials/live_reload)
12 | * [Web Workers](http://socketstream.github.io/socketstream/docs/#/tutorials/web_workers)
13 |
14 | ##### Developing (Server-side)
15 |
16 | * [RPC Responder](http://socketstream.github.io/socketstream/docs/#/tutorials/rpc_responder)
17 | * [Pub/Sub Events](http://socketstream.github.io/socketstream/docs/#/tutorials/pub_sub_events)
18 | * [Sessions](http://socketstream.github.io/socketstream/docs/#/tutorials/sessions)
19 | * [Request Middleware](http://socketstream.github.io/socketstream/docs/#/tutorials/request_middleware)
20 | * [HTTP Middleware](http://socketstream.github.io/socketstream/docs/#/tutorials/http_middleware)
21 | * [Authentication](http://socketstream.github.io/socketstream/docs/#/tutorials/authentication)
22 | * [Testing Your App](http://socketstream.github.io/socketstream/docs/#/tutorials/server_side_testing)
23 |
24 | ##### Best Practices
25 |
26 | * [Hosting in Production](http://socketstream.github.io/socketstream/docs/#/tutorials/production_hosting) - Packing assets, CDNs, handling exceptions
27 |
28 | ##### Extending SocketStream
29 |
30 | * [Modules](http://socketstream.github.io/socketstream/docs/#/tutorials/modules) - extending indirectly with node modules from the app.
31 | * [Writing Template Engine Wrappers](http://socketstream.github.io/socketstream/docs/#/tutorials/template_engine_wrappers) - support any of the gazillion template formats out there
32 | * [Writing Request Responders](http://socketstream.github.io/socketstream/docs/#/tutorials/writing_request_responders) - experiment with models and low-level message protocols
--------------------------------------------------------------------------------
/test/unit/client/asset.test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 |
5 | describe('client asset handler', function () {
6 |
7 |
8 |
9 | describe('#js', function () {
10 |
11 |
12 |
13 | it('should return the compressed file, if the compress option is true');
14 |
15 |
16 |
17 | it('should otherwise return the file');
18 |
19 |
20 |
21 | it('should not modify the code, if it\'s in the libs directory');
22 |
23 |
24 |
25 | it('should not add a leading slash to the path, if the file is a system module');
26 |
27 |
28 |
29 | it('should otherwise wrap the file in a module wrapper');
30 |
31 |
32 |
33 | it('should raise an error if the file is not found at the path');
34 |
35 |
36 |
37 | it('should raise an error if the file is not supported');
38 |
39 |
40 |
41 | it('should raise an error if the file is not the right type');
42 |
43 |
44 |
45 | });
46 |
47 |
48 |
49 | describe('#worker', function () {
50 |
51 |
52 |
53 | it('should return the compressed file, if the compress option is true');
54 |
55 |
56 |
57 | it('should otherwise return the file');
58 |
59 |
60 |
61 | it('should raise an error if the file is not found at the path');
62 |
63 |
64 |
65 | it('should raise an error if the file is not supported');
66 |
67 |
68 |
69 | it('should raise an error if the file is not the right type');
70 |
71 |
72 |
73 | });
74 |
75 |
76 |
77 | describe('#css', function () {
78 |
79 |
80 |
81 | it('should raise an error if the file is not found at the path');
82 |
83 |
84 |
85 | it('should raise an error if the file is not supported');
86 |
87 |
88 |
89 | it('should raise an error if the file is not the right type');
90 |
91 |
92 |
93 | });
94 |
95 |
96 |
97 | describe('#html', function () {
98 |
99 |
100 |
101 | it('should raise an error if the file is not found at the path');
102 |
103 |
104 |
105 | it('should raise an error if the file is not supported');
106 |
107 |
108 |
109 | it('should raise an error if the file is not the right type');
110 |
111 |
112 |
113 | });
114 |
115 |
116 |
117 | });
--------------------------------------------------------------------------------
/lib/session/store.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Connect - session - Store
3 | * Copyright(c) 2010 Sencha Inc.
4 | * Copyright(c) 2011 TJ Holowaychuk
5 | * MIT Licensed
6 | */
7 | 'use strict';
8 |
9 | /**
10 | * Module dependencies.
11 | */
12 |
13 | var EventEmitter = require('eventemitter2').EventEmitter2,
14 | debug = require('debug')('sessionstore'),
15 | Session = require('./session'),
16 | Cookie = require('./cookie');
17 |
18 | /**
19 | * Initialize abstract `Store`.
20 | *
21 | * @param options {Object} Store options
22 | * @api private
23 | */
24 |
25 | var Store = module.exports = function Store(){};
26 |
27 | /**
28 | * Inherit from `EventEmitter.prototype`.
29 | */
30 |
31 | Store.prototype = Object.create(EventEmitter.prototype);
32 |
33 | /**
34 | * Re-generate the given requests's session.
35 | *
36 | * @param {IncomingRequest} req
37 | * @return {Function} fn
38 | * @api public
39 | */
40 |
41 | Store.prototype.regenerate = function(req, fn){
42 | var self = this;
43 | this.destroy(req.sessionID, function(err){
44 | self.generate(req);
45 | fn(err);
46 | });
47 | };
48 |
49 | /**
50 | * Load a `Session` instance via the given `sid`
51 | * and invoke the callback `fn(err, sess)`.
52 | *
53 | * @param {String} sid
54 | * @param {Function} fn
55 | * @api public
56 | */
57 |
58 | Store.prototype.load = function(sid, fn){
59 | var self = this;
60 | this.get(sid, function(err, sess){
61 | if (err) { debug('failed to get %s',sid); return fn(err); }
62 | if (!sess) { debug('no session for %s',sid); return fn(); }
63 | var req = { sessionID: sid, sessionStore: self };
64 | sess = self.createSession(req, sess); // recreate prototypes on persisted data
65 | fn(null, sess);
66 | });
67 | };
68 |
69 | /**
70 | * Create session from JSON `sess` data.
71 | *
72 | * @param {IncomingRequest} req
73 | * @param {Object} sess
74 | * @return {Session}
75 | * @api private
76 | */
77 |
78 | Store.prototype.createSession = function(req, sess){
79 | var expires = sess.cookie.expires
80 | , orig = sess.cookie.originalMaxAge;
81 | sess.cookie = new Cookie(sess.cookie);
82 | if ('string' === typeof expires) { sess.cookie.expires = new Date(expires); }
83 | sess.cookie.originalMaxAge = orig;
84 | req.session = new Session(req, sess);
85 | return req.session;
86 | };
87 |
--------------------------------------------------------------------------------
/docs/partials/api/ss.client.client.html:
--------------------------------------------------------------------------------
1 | Improve this doc View sourceclient
2 | ss
3 |
4 | Allow other libs to send assets to the client
8 |Allow other libs to send assets to the client. add new System Library or Module
12 || Param | Type | Details |
|---|---|---|
| type | 'code','lib','module' |
|
| name | string |
|
| content | string |
|
| options | Object |
|
2 | When you load the view in the browser, constants will be defined as global variables, so they can be 7 | accessed anywhere by their name.
8 |To define a constant add it under consts: in the view definition.
ss.client.define('myview',{
10 | view: 'myview.html',
11 | consts: {
12 | appConfig: {
13 | facebookAppId: '1234',
14 | twitterKey: 'AAA'
15 | }
16 | }
17 | });
18 | The constants will only be loaded in the view. Other views will not be affected.
19 |You can also define a global constant using ss.client.send. In this case the constant will be loaded
20 | in all views. In case you have a constant in a view definition with the same name, it will be
21 | used rather than the global value.
When you write HTML and CSS you often want to use a common value which isn't defined in the source code, 24 | but rather in configuration. Version number and copyright are good examples of these, so are color values, 25 | debugging environment and level of browser support.
26 |Following convention these are called locals. They are not available as variables in the browser. That is unless 27 | your formatter expose them as such. They are however passed to the template_engines and formatters.
28 |To define a local add it under locals: in the view defintion.
ss.client.define('myview',{
30 | view: 'myview.html',
31 | locals: {
32 | appConfig: {
33 | copyright: '1999'
34 | }
35 | }
36 | });
37 | The locals will only be passed when rendering that view. Other views will not be affected.
38 |You can also define a global local(yes, naming sucks) using ss.client.send. In this case the local will be
39 | used in all views. In case you have a local in a view definition with the same name, it will be
40 | used rather than the global value.
2 | If you're writing a small app you can safely ignore this section, as it's always better to pack all client assets into one file and send everything through together in one go if possible.
7 |But what if you're writing a large app, or an app with multiple distinct sections like iCloud.com?
8 |SocketStream allows you to load code (and other assets in the future) into your app asynchronously on demand.
9 |Sadly it's not possible to directly require() modules which haven't been loaded as the blocking nature of the require function means the browser would freeze until the module has been retrieved from the server - not good.
However SocketStream allows you to load additional code modules from the server asynchronously using the built-in ss.load.code() command. Once all the code you've requested has been loaded, we execute a callback, allowing you to require() the new modules as normal without any fancy syntax.
To try this out, create a new directory of application modules in /client/code. For the sake of this example, let's call our new directory /client/code/mail. We'll also assume this directory has a module in it called search.js.
14 | // in any client-side module
15 | ss.load.code('/mail', function(){
16 |
17 | // all modules in /client/code/mail have now been loaded into
18 | // the root namespace (/) and can be required in the normal way
19 | var search = require('/search');
20 |
21 | });
22 |
23 | Note: Regardless of the directory you load, the modules inside will always be loaded into the root (/) namespace by default. If you want to mount the new modules in a different namespace, just create one or more sub-directories in the folder you're loading.
24 |Modules are only ever retrieved from the server once. Subsequent requests for the same directory will be returned instantly without contacting the server.
26 |
2 | Web Workers provide a great way for modern browsers to execute complex tasks and calculations without blocking the main thread.
7 |SocketStream makes it easy to work with Web Workers by providing transparent compilation (if you're using CoffeeScript) and automatic minification & caching when you call ss.client.packAssets()
To read more about Web Workers in general, take a look at: http://www.html5rocks.com/en/tutorials/workers/basics
9 |Web Workers live in /client/workers. We don't create this folder by default, so you'll need to do that first.
Each worker should be written as a separate .js or .coffee file (if you have the ss-coffee module installed). For this tutorial we'll be using JavaScript.
Let's create a worker which will calculate Pi using the Leibniz Formula:
14 |
15 | // in /client/workers/pi.js
16 |
17 | self.addEventListener('message', function(e) {
18 | var cycles = e.data;
19 | postMessage("Calculating Pi using " + cycles + " cycles");
20 | var numbers = calculatePi(cycles);
21 | postMessage("Result: " + numbers);
22 | }, false);
23 |
24 | function calculatePi(cycles) {
25 | var pi = 0;
26 | var n = 1;
27 | for (var i=0; i <= cycles; i++) {
28 | pi = pi + (4/n) - (4 / (n+2));
29 | n = n + 4;
30 | }
31 | return pi;
32 | }
33 |
34 | Then, in any client-side code file, invoke the worker.
35 |
36 | // in any /client/code file
37 | var worker = ss.load.worker('/pi.js');
38 |
39 | // print output to console
40 | worker.addEventListener('message', function(e) {
41 | console.log(e.data);
42 | });
43 |
44 | // start worker with 10000000 cycles
45 | worker.postMessage(10000000);
46 |
47 | A few seconds after the task has run you should see the output in the browser's console:
48 |Calculating Pi using 10000000 cycles
49 | Result: 3.1415926485894077
50 | Experiment with running more cycles and passing different messages.
51 |