├── .gitignore ├── Gruntfile.js ├── LICENSE ├── README.md ├── TODO ├── arch.png ├── css └── react-object-inspector.css ├── dist ├── main.bundle.js └── worker.bundle.js ├── index.html ├── js ├── constants │ └── TodoFilters.js ├── dom │ ├── TodoApp.js │ ├── common │ │ ├── BusinessLayerLoader.js │ │ ├── FakeStore.js │ │ ├── ForkMe.js │ │ ├── StoreView.jsx │ │ └── initBridge.js │ ├── index.jsx │ └── todomvc-common │ │ └── index.css └── domless │ ├── AppDispatcher.js │ ├── BaseStore.js │ ├── TodoActions.js │ ├── TodoConstants.js │ ├── todoStore.js │ └── worker.js ├── package.json ├── style.css └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 19 | .grunt 20 | 21 | # node-waf configuration 22 | .lock-wscript 23 | 24 | # Compiled binary addons (http://nodejs.org/api/addons.html) 25 | build/Release 26 | 27 | # Dependency directory 28 | # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git 29 | node_modules 30 | .idea 31 | 32 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | "use strict"; 3 | grunt.initConfig({ 4 | exec: { 5 | webpack: 'webpack --watch &' 6 | }, 7 | "http-server": { 8 | dev: { 9 | root: "./", 10 | port: 8000, 11 | host: "0.0.0.0", 12 | showDir: true, 13 | autoIndex: true, 14 | runInBackground: true 15 | } 16 | }, 17 | watch: { 18 | reload: { 19 | files: ["dist/**", "index.html"], 20 | options: { 21 | livereload: true 22 | } 23 | }, 24 | css: { 25 | files: ["style.css"], 26 | options: { 27 | livereload: true 28 | } 29 | } 30 | } 31 | }); 32 | 33 | grunt.loadNpmTasks('grunt-http-server'); 34 | grunt.loadNpmTasks("grunt-contrib-watch"); 35 | grunt.loadNpmTasks('grunt-exec'); 36 | 37 | grunt.registerTask("webpackWatch", ["exec:webpack"]); 38 | grunt.registerTask("default", ["http-server", "webpackWatch", "watch"]); 39 | }; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Narendra Sisodiya 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Flux inside Web Workers 2 | 3 |  4 | 5 | # Demo 6 | 7 | [http://nsisodiya.github.io/flux-inside-web-workers](http://nsisodiya.github.io/flux-inside-web-workers) 8 | 9 | # Blog 10 | 11 | [https://medium.com/@nsisodiya/flux-inside-web-workers-cc51fb463882](https://medium.com/@nsisodiya/flux-inside-web-workers-cc51fb463882) 12 | 13 | ## Requirements 14 | 15 | ```bash 16 | npm install -g grunt-cli 17 | npm install -g webpack 18 | ``` 19 | ## Execution 20 | 21 | ```bash 22 | git clone git@github.com:nsisodiya/flux-inside-web-workers.git 23 | cd flux-inside-web-workers 24 | npm install 25 | grunt 26 | ``` 27 | ## Bridge API 28 | In this project, I am using https://github.com/nsisodiya/bl-layer-loader for BL Layer and UI Layer communication ! -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | //TODO - multiple Stores, 2 | //TODO - Add localStorage ! 3 | //TODO - have FLUX on Server side 4 | 5 | 6 | //TODO - store.off when componentdidUmount 7 | //TODO = Double Click to Edit 8 | //TODO = Routing 9 | //TODO = Test Cases ! 10 | -------------------------------------------------------------------------------- /arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nsisodiya/flux-inside-web-workers/75416aa00d33bb46fe2afed2a358a45f1b8eb7f9/arch.png -------------------------------------------------------------------------------- /css/react-object-inspector.css: -------------------------------------------------------------------------------- 1 | .ObjectInspector { 2 | font-family: Menlo, monospace; 3 | font-size: 11px; 4 | line-height: 14px; 5 | cursor: default; 6 | } 7 | 8 | .ObjectInspector-unselectable { 9 | -webkit-touch-callout: none; 10 | -webkit-user-select: none; 11 | -khtml-user-select: none; 12 | -moz-user-select: none; 13 | -ms-user-select: none; 14 | -o-user-select: none; 15 | user-select: none; 16 | } 17 | 18 | .ObjectInspector-expand-control { 19 | color: #6e6e6e; 20 | font-size: 10px; 21 | margin-right: 3px; 22 | white-space: pre; 23 | } 24 | 25 | .ObjectInspector-property { 26 | padding-top: 2px; 27 | } 28 | 29 | .ObjectInspector-object-name { 30 | color: rgb(136, 19, 145); 31 | } 32 | 33 | .ObjectInspector-object-value-null, .ObjectInspector-object-value-undefined { 34 | color: rgb(128, 128, 128); 35 | } 36 | 37 | .ObjectInspector-object-value-string { 38 | color: rgb(196, 26, 22); 39 | } 40 | 41 | .ObjectInspector-object-value-number, .ObjectInspector-object-value-boolean { 42 | color: rgb(28, 0, 207); 43 | } 44 | 45 | .ObjectInspector-object-value-function-keyword { 46 | color: rgb(170, 13, 145); 47 | font-style: italic; 48 | } 49 | 50 | .ObjectInspector-object-value-function-name { 51 | font-style: italic; 52 | } 53 | 54 | .ObjectInspector-object-preview { 55 | font-style: italic; 56 | } 57 | 58 | .ObjectInspector-property-nodes-container { 59 | padding-left: 12px 60 | } 61 | -------------------------------------------------------------------------------- /dist/worker.bundle.js: -------------------------------------------------------------------------------- 1 | /******/ (function(modules) { // webpackBootstrap 2 | /******/ // The module cache 3 | /******/ var installedModules = {}; 4 | 5 | /******/ // The require function 6 | /******/ function __webpack_require__(moduleId) { 7 | 8 | /******/ // Check if module is in cache 9 | /******/ if(installedModules[moduleId]) 10 | /******/ return installedModules[moduleId].exports; 11 | 12 | /******/ // Create a new module (and put it into the cache) 13 | /******/ var module = installedModules[moduleId] = { 14 | /******/ exports: {}, 15 | /******/ id: moduleId, 16 | /******/ loaded: false 17 | /******/ }; 18 | 19 | /******/ // Execute the module function 20 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 | 22 | /******/ // Flag the module as loaded 23 | /******/ module.loaded = true; 24 | 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | 29 | 30 | /******/ // expose the modules object (__webpack_modules__) 31 | /******/ __webpack_require__.m = modules; 32 | 33 | /******/ // expose the module cache 34 | /******/ __webpack_require__.c = installedModules; 35 | 36 | /******/ // __webpack_public_path__ 37 | /******/ __webpack_require__.p = ""; 38 | 39 | /******/ // Load entry module and return exports 40 | /******/ return __webpack_require__(0); 41 | /******/ }) 42 | /************************************************************************/ 43 | /******/ ({ 44 | 45 | /***/ 0: 46 | /***/ function(module, exports, __webpack_require__) { 47 | 48 | 'use strict'; 49 | 50 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 51 | 52 | var _blLayerLoader = __webpack_require__(161); 53 | 54 | var _blLayerLoader2 = _interopRequireDefault(_blLayerLoader); 55 | 56 | var todostore = __webpack_require__(167); 57 | var TodoActions = __webpack_require__(175); 58 | 59 | var bridge = _blLayerLoader2['default'].getBLBridge(); 60 | 61 | todostore.on('change', function () { 62 | bridge.post("/stores/TodoStore/updateState", todostore.getState()); 63 | }); 64 | 65 | bridge.on("/stores/TodoStore/getInitialState", function (payload, sendBack) { 66 | sendBack(todostore.getState()); 67 | }); 68 | 69 | //TODO , support : Syntax 70 | //bridge.on("/actions/TodoActions/:method", function (payload, sendBack, path) { 71 | // var method = path.params.method 72 | // path.url = "/actions/TodoActions/addTodo" 73 | // path.matchedUrl = "/actions/TodoActions/:method" 74 | // TodoActions[method].call(TodoActions, payload); 75 | //}); 76 | 77 | bridge.on("/actions/TodoActions/addTodo", function (payload, sendBack, path) { 78 | TodoActions.addTodo(payload); 79 | }); 80 | 81 | bridge.on("/actions/TodoActions/markComplete", function (payload, sendBack, path) { 82 | TodoActions.markComplete(payload); 83 | }); 84 | 85 | bridge.on("/actions/TodoActions/remove", function (payload, sendBack, path) { 86 | TodoActions.remove(payload); 87 | }); 88 | 89 | bridge.on("/actions/TodoActions/removeAllCompleted", function (payload, sendBack, path) { 90 | TodoActions.removeAllCompleted(); 91 | }); 92 | 93 | bridge.on("/actions/TodoActions/edit", function (payload, sendBack, path) { 94 | TodoActions.edit(payload.id, payload.text); 95 | }); 96 | 97 | bridge.on("/actions/TodoActions/markUnComplete", function (payload, sendBack, path) { 98 | TodoActions.markUnComplete(payload); 99 | }); 100 | 101 | bridge.on("/actions/TodoActions/markAllUnComplete", function (payload, sendBack, path) { 102 | TodoActions.markAllUnComplete(); 103 | }); 104 | 105 | bridge.on("/actions/TodoActions/markAllComplete", function (payload, sendBack, path) { 106 | TodoActions.markAllComplete(); 107 | }); 108 | 109 | bridge.on("/actions/TodoActions/onShow", function (payload, sendBack, path) { 110 | TodoActions.onShow(payload); 111 | }); 112 | 113 | /***/ }, 114 | 115 | /***/ 3: 116 | /***/ function(module, exports) { 117 | 118 | // shim for using process in browser 119 | 120 | 'use strict'; 121 | 122 | var process = module.exports = {}; 123 | var queue = []; 124 | var draining = false; 125 | var currentQueue; 126 | var queueIndex = -1; 127 | 128 | function cleanUpNextTick() { 129 | draining = false; 130 | if (currentQueue.length) { 131 | queue = currentQueue.concat(queue); 132 | } else { 133 | queueIndex = -1; 134 | } 135 | if (queue.length) { 136 | drainQueue(); 137 | } 138 | } 139 | 140 | function drainQueue() { 141 | if (draining) { 142 | return; 143 | } 144 | var timeout = setTimeout(cleanUpNextTick); 145 | draining = true; 146 | 147 | var len = queue.length; 148 | while (len) { 149 | currentQueue = queue; 150 | queue = []; 151 | while (++queueIndex < len) { 152 | if (currentQueue) { 153 | currentQueue[queueIndex].run(); 154 | } 155 | } 156 | queueIndex = -1; 157 | len = queue.length; 158 | } 159 | currentQueue = null; 160 | draining = false; 161 | clearTimeout(timeout); 162 | } 163 | 164 | process.nextTick = function (fun) { 165 | var args = new Array(arguments.length - 1); 166 | if (arguments.length > 1) { 167 | for (var i = 1; i < arguments.length; i++) { 168 | args[i - 1] = arguments[i]; 169 | } 170 | } 171 | queue.push(new Item(fun, args)); 172 | if (queue.length === 1 && !draining) { 173 | setTimeout(drainQueue, 0); 174 | } 175 | }; 176 | 177 | // v8 likes predictible objects 178 | function Item(fun, array) { 179 | this.fun = fun; 180 | this.array = array; 181 | } 182 | Item.prototype.run = function () { 183 | this.fun.apply(null, this.array); 184 | }; 185 | process.title = 'browser'; 186 | process.browser = true; 187 | process.env = {}; 188 | process.argv = []; 189 | process.version = ''; // empty string to avoid regexp issues 190 | process.versions = {}; 191 | 192 | function noop() {} 193 | 194 | process.on = noop; 195 | process.addListener = noop; 196 | process.once = noop; 197 | process.off = noop; 198 | process.removeListener = noop; 199 | process.removeAllListeners = noop; 200 | process.emit = noop; 201 | 202 | process.binding = function (name) { 203 | throw new Error('process.binding is not supported'); 204 | }; 205 | 206 | process.cwd = function () { 207 | return '/'; 208 | }; 209 | process.chdir = function (dir) { 210 | throw new Error('process.chdir is not supported'); 211 | }; 212 | process.umask = function () { 213 | return 0; 214 | }; 215 | 216 | /***/ }, 217 | 218 | /***/ 161: 219 | /***/ function(module, exports) { 220 | 221 | /** 222 | * Created by narendrasisodiya on 06/08/15. 223 | */ 224 | "use strict"; 225 | 226 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 227 | 228 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 229 | 230 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 231 | 232 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 233 | 234 | var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function'; 235 | 236 | var MESSAGE_TYPE = { 237 | RETURN_MESSAGE: "returnMessage", 238 | DEPART_WITH_SENDBACK_ID: "departWithSendBackId", 239 | DEPART: "depart" 240 | }; 241 | 242 | function setUpGlobalMessagePass() { 243 | if (ENVIRONMENT_IS_WORKER === false && window._globalMessagePassForWorkerLessEnv_ === undefined) { 244 | //Define only once ! 245 | var local = {}; 246 | 247 | local.registerBL = function (callback) { 248 | local.BL = callback; 249 | }; 250 | 251 | local.registerUI = function (callback) { 252 | local.UI = callback; 253 | }; 254 | local.sendToBL = function (message) { 255 | local.BL(message); 256 | }; 257 | local.sendToUI = function (message) { 258 | local.UI(message); 259 | }; 260 | window._globalMessagePassForWorkerLessEnv_ = local; 261 | } 262 | } 263 | 264 | var FakeWorker = (function () { 265 | function FakeWorker(BLL) { 266 | _classCallCheck(this, FakeWorker); 267 | 268 | if (BLL === undefined) { 269 | throw "Send BLL Variable Either True of False"; 270 | } 271 | this.BLL = BLL; 272 | } 273 | 274 | _createClass(FakeWorker, [{ 275 | key: "addEventListener", 276 | value: function addEventListener(topic, callback) { 277 | if (this.BLL) { 278 | window._globalMessagePassForWorkerLessEnv_.registerBL(callback); 279 | } else { 280 | window._globalMessagePassForWorkerLessEnv_.registerUI(callback); 281 | } 282 | } 283 | }, { 284 | key: "postMessage", 285 | value: function postMessage(message) { 286 | if (this.BLL) { 287 | window._globalMessagePassForWorkerLessEnv_.sendToUI({ 288 | data: message 289 | }); 290 | } else { 291 | window._globalMessagePassForWorkerLessEnv_.sendToBL({ 292 | data: message 293 | }); 294 | } 295 | } 296 | }]); 297 | 298 | return FakeWorker; 299 | })(); 300 | 301 | var BaseAdapter = (function () { 302 | function BaseAdapter() { 303 | _classCallCheck(this, BaseAdapter); 304 | 305 | this.isBridgeReady = false; 306 | this._evtBus = {}; 307 | this._unsubObj = []; 308 | this._returnCallback = []; 309 | this.BLLayer = true; 310 | } 311 | 312 | _createClass(BaseAdapter, [{ 313 | key: "_processRawMessage", 314 | value: function _processRawMessage(message) { 315 | console.log("Message Received", message); 316 | 317 | if (message.type === MESSAGE_TYPE.RETURN_MESSAGE) { 318 | var c = this._returnCallback[message.sendBackId]; 319 | if (typeof c === "function") { 320 | c(message.payload); 321 | this._returnCallback[message.sendBackId] = null; 322 | } else { 323 | console.error("message contains sendBackID which do not have any corrosponding callback"); 324 | } 325 | } else { 326 | var path = message.path; 327 | 328 | //Some Message comes from URL Worker thread, we need to process it. message is raw message. payload is inside raw message. 329 | // User is only interested in payload. 330 | var f = this._evtBus[path]; 331 | var THAT = this; 332 | if (f !== undefined && f.length !== 0) { 333 | f.map(function (v, i) { 334 | v(message.payload, function (sendBackData) { 335 | console.log("send Back data is", sendBackData); 336 | THAT.worker.postMessage({ 337 | payload: sendBackData, 338 | type: MESSAGE_TYPE.RETURN_MESSAGE, 339 | sendBackId: message.sendBackId 340 | }); 341 | }); 342 | }); 343 | } 344 | } 345 | } 346 | }, { 347 | key: "on", 348 | value: function on(path, callback) { 349 | if (this._evtBus[path] === undefined) { 350 | this._evtBus[path] = []; 351 | } 352 | var index = this._evtBus[path].push(callback) - 1; 353 | var unSubIndex = this._unsubObj.push({ 354 | path: path, 355 | index: index 356 | }) - 1; 357 | 358 | return unSubIndex; 359 | } 360 | }, { 361 | key: "off", 362 | value: function off(unSubIndex) { 363 | try { 364 | var _unsubObj$unSubIndex = this._unsubObj[unSubIndex]; 365 | var path = _unsubObj$unSubIndex.path; 366 | var index = _unsubObj$unSubIndex.index; 367 | 368 | this._evtBus[path][index] = null; 369 | } catch (ex) {} 370 | } 371 | }, { 372 | key: "post", 373 | value: function post(path, payload, callback) { 374 | if (callback === undefined) { 375 | this.worker.postMessage({ 376 | path: path, 377 | payload: payload, 378 | type: MESSAGE_TYPE.DEPART 379 | }); 380 | } else { 381 | var id = this._registerSendBack(path, callback); 382 | this.worker.postMessage({ 383 | path: path, 384 | payload: payload, 385 | type: MESSAGE_TYPE.DEPART_WITH_SENDBACK_ID, 386 | sendBackId: id 387 | }); 388 | } 389 | } 390 | }, { 391 | key: "_registerSendBack", 392 | value: function _registerSendBack(path, callback) { 393 | //when a Raw Message comes with type : "return", we need to find its corresponding callback. 394 | var x = this._returnCallback.push(callback); 395 | return x - 1; 396 | } 397 | }]); 398 | 399 | return BaseAdapter; 400 | })(); 401 | 402 | var LocalAdapter = (function (_BaseAdapter) { 403 | _inherits(LocalAdapter, _BaseAdapter); 404 | 405 | function LocalAdapter(url) { 406 | var _this = this; 407 | 408 | _classCallCheck(this, LocalAdapter); 409 | 410 | _get(Object.getPrototypeOf(LocalAdapter.prototype), "constructor", this).call(this); 411 | 412 | if (url !== undefined) { 413 | this._loadScript(url); 414 | this.BLLayer = false; 415 | } 416 | 417 | if (window._globalMessagePassForWorkerLessEnv_ === undefined) { 418 | setUpGlobalMessagePass(); 419 | } 420 | this.worker = new FakeWorker(this.BLLayer); 421 | 422 | this.worker.addEventListener('message', function (e) { 423 | _this._processRawMessage(e.data); 424 | }, false); 425 | } 426 | 427 | _createClass(LocalAdapter, [{ 428 | key: "_loadScript", 429 | value: function _loadScript(url) { 430 | var _this2 = this; 431 | 432 | var script = document.createElement('script'); 433 | script.src = url; 434 | script.onload = function () { 435 | _this2._onScriptLoaded(); 436 | }; 437 | document.head.appendChild(script); 438 | } 439 | }, { 440 | key: "_onScriptLoaded", 441 | value: function _onScriptLoaded() { 442 | this.isBridgeReady = true; 443 | if (this._onReadyCallback !== undefined) { 444 | this._onReadyCallback(); 445 | this._onReadyCallback === undefined; 446 | } 447 | } 448 | }, { 449 | key: "onReady", 450 | value: function onReady(callback) { 451 | if (this.isBridgeReady === true) { 452 | callback(); 453 | } else { 454 | this._onReadyCallback = callback; 455 | } 456 | } 457 | }]); 458 | 459 | return LocalAdapter; 460 | })(BaseAdapter); 461 | 462 | var WorkerAdapter = (function (_BaseAdapter2) { 463 | _inherits(WorkerAdapter, _BaseAdapter2); 464 | 465 | function WorkerAdapter(url) { 466 | var _this3 = this; 467 | 468 | _classCallCheck(this, WorkerAdapter); 469 | 470 | _get(Object.getPrototypeOf(WorkerAdapter.prototype), "constructor", this).call(this); 471 | if (ENVIRONMENT_IS_WORKER === false) { 472 | this.BLLayer = false; 473 | this.worker = new Worker(url); 474 | } else { 475 | this.BLLayer = true; 476 | this.worker = self; 477 | } 478 | this.worker.addEventListener('message', function (e) { 479 | _this3._processRawMessage(e.data); 480 | }, false); 481 | } 482 | 483 | _createClass(WorkerAdapter, [{ 484 | key: "onReady", 485 | value: function onReady(callback) { 486 | callback(); //Immediatly execute callback - TODO 487 | } 488 | }]); 489 | 490 | return WorkerAdapter; 491 | })(BaseAdapter); 492 | 493 | var BLLayerLoader = { 494 | load: function load(config) { 495 | if (ENVIRONMENT_IS_WORKER === true) { 496 | throw "This method should not be called from Worker"; 497 | return; 498 | } 499 | var url = config.url; 500 | var method = config.method; 501 | 502 | if (method === "Worker") { 503 | return new WorkerAdapter(url); 504 | } 505 | if (method === "Local") { 506 | return new LocalAdapter(url); 507 | } 508 | }, 509 | getBLBridge: function getBLBridge() { 510 | if (ENVIRONMENT_IS_WORKER === true) { 511 | return new WorkerAdapter(); 512 | } else { 513 | return new LocalAdapter(); 514 | } 515 | } 516 | }; 517 | 518 | module.exports = BLLayerLoader; 519 | 520 | /***/ }, 521 | 522 | /***/ 163: 523 | /***/ function(module, exports) { 524 | 525 | 'use strict'; 526 | 527 | Object.defineProperty(exports, '__esModule', { 528 | value: true 529 | }); 530 | var SHOW_ALL = 'show_all'; 531 | exports.SHOW_ALL = SHOW_ALL; 532 | var SHOW_COMPLETED = 'show_completed'; 533 | exports.SHOW_COMPLETED = SHOW_COMPLETED; 534 | var SHOW_ACTIVE = 'show_active'; 535 | exports.SHOW_ACTIVE = SHOW_ACTIVE; 536 | 537 | /***/ }, 538 | 539 | /***/ 166: 540 | /***/ function(module, exports) { 541 | 542 | // Copyright Joyent, Inc. and other Node contributors. 543 | // 544 | // Permission is hereby granted, free of charge, to any person obtaining a 545 | // copy of this software and associated documentation files (the 546 | // "Software"), to deal in the Software without restriction, including 547 | // without limitation the rights to use, copy, modify, merge, publish, 548 | // distribute, sublicense, and/or sell copies of the Software, and to permit 549 | // persons to whom the Software is furnished to do so, subject to the 550 | // following conditions: 551 | // 552 | // The above copyright notice and this permission notice shall be included 553 | // in all copies or substantial portions of the Software. 554 | // 555 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 556 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 557 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 558 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 559 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 560 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 561 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 562 | 563 | 'use strict'; 564 | 565 | function EventEmitter() { 566 | this._events = this._events || {}; 567 | this._maxListeners = this._maxListeners || undefined; 568 | } 569 | module.exports = EventEmitter; 570 | 571 | // Backwards-compat with node 0.10.x 572 | EventEmitter.EventEmitter = EventEmitter; 573 | 574 | EventEmitter.prototype._events = undefined; 575 | EventEmitter.prototype._maxListeners = undefined; 576 | 577 | // By default EventEmitters will print a warning if more than 10 listeners are 578 | // added to it. This is a useful default which helps finding memory leaks. 579 | EventEmitter.defaultMaxListeners = 10; 580 | 581 | // Obviously not all Emitters should be limited to 10. This function allows 582 | // that to be increased. Set to zero for unlimited. 583 | EventEmitter.prototype.setMaxListeners = function (n) { 584 | if (!isNumber(n) || n < 0 || isNaN(n)) throw TypeError('n must be a positive number'); 585 | this._maxListeners = n; 586 | return this; 587 | }; 588 | 589 | EventEmitter.prototype.emit = function (type) { 590 | var er, handler, len, args, i, listeners; 591 | 592 | if (!this._events) this._events = {}; 593 | 594 | // If there is no 'error' event listener then throw. 595 | if (type === 'error') { 596 | if (!this._events.error || isObject(this._events.error) && !this._events.error.length) { 597 | er = arguments[1]; 598 | if (er instanceof Error) { 599 | throw er; // Unhandled 'error' event 600 | } 601 | throw TypeError('Uncaught, unspecified "error" event.'); 602 | } 603 | } 604 | 605 | handler = this._events[type]; 606 | 607 | if (isUndefined(handler)) return false; 608 | 609 | if (isFunction(handler)) { 610 | switch (arguments.length) { 611 | // fast cases 612 | case 1: 613 | handler.call(this); 614 | break; 615 | case 2: 616 | handler.call(this, arguments[1]); 617 | break; 618 | case 3: 619 | handler.call(this, arguments[1], arguments[2]); 620 | break; 621 | // slower 622 | default: 623 | args = Array.prototype.slice.call(arguments, 1); 624 | handler.apply(this, args); 625 | } 626 | } else if (isObject(handler)) { 627 | args = Array.prototype.slice.call(arguments, 1); 628 | listeners = handler.slice(); 629 | len = listeners.length; 630 | for (i = 0; i < len; i++) listeners[i].apply(this, args); 631 | } 632 | 633 | return true; 634 | }; 635 | 636 | EventEmitter.prototype.addListener = function (type, listener) { 637 | var m; 638 | 639 | if (!isFunction(listener)) throw TypeError('listener must be a function'); 640 | 641 | if (!this._events) this._events = {}; 642 | 643 | // To avoid recursion in the case that type === "newListener"! Before 644 | // adding it to the listeners, first emit "newListener". 645 | if (this._events.newListener) this.emit('newListener', type, isFunction(listener.listener) ? listener.listener : listener); 646 | 647 | if (!this._events[type]) 648 | // Optimize the case of one listener. Don't need the extra array object. 649 | this._events[type] = listener;else if (isObject(this._events[type])) 650 | // If we've already got an array, just append. 651 | this._events[type].push(listener);else 652 | // Adding the second element, need to change to array. 653 | this._events[type] = [this._events[type], listener]; 654 | 655 | // Check for listener leak 656 | if (isObject(this._events[type]) && !this._events[type].warned) { 657 | if (!isUndefined(this._maxListeners)) { 658 | m = this._maxListeners; 659 | } else { 660 | m = EventEmitter.defaultMaxListeners; 661 | } 662 | 663 | if (m && m > 0 && this._events[type].length > m) { 664 | this._events[type].warned = true; 665 | console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); 666 | if (typeof console.trace === 'function') { 667 | // not supported in IE 10 668 | console.trace(); 669 | } 670 | } 671 | } 672 | 673 | return this; 674 | }; 675 | 676 | EventEmitter.prototype.on = EventEmitter.prototype.addListener; 677 | 678 | EventEmitter.prototype.once = function (type, listener) { 679 | if (!isFunction(listener)) throw TypeError('listener must be a function'); 680 | 681 | var fired = false; 682 | 683 | function g() { 684 | this.removeListener(type, g); 685 | 686 | if (!fired) { 687 | fired = true; 688 | listener.apply(this, arguments); 689 | } 690 | } 691 | 692 | g.listener = listener; 693 | this.on(type, g); 694 | 695 | return this; 696 | }; 697 | 698 | // emits a 'removeListener' event iff the listener was removed 699 | EventEmitter.prototype.removeListener = function (type, listener) { 700 | var list, position, length, i; 701 | 702 | if (!isFunction(listener)) throw TypeError('listener must be a function'); 703 | 704 | if (!this._events || !this._events[type]) return this; 705 | 706 | list = this._events[type]; 707 | length = list.length; 708 | position = -1; 709 | 710 | if (list === listener || isFunction(list.listener) && list.listener === listener) { 711 | delete this._events[type]; 712 | if (this._events.removeListener) this.emit('removeListener', type, listener); 713 | } else if (isObject(list)) { 714 | for (i = length; i-- > 0;) { 715 | if (list[i] === listener || list[i].listener && list[i].listener === listener) { 716 | position = i; 717 | break; 718 | } 719 | } 720 | 721 | if (position < 0) return this; 722 | 723 | if (list.length === 1) { 724 | list.length = 0; 725 | delete this._events[type]; 726 | } else { 727 | list.splice(position, 1); 728 | } 729 | 730 | if (this._events.removeListener) this.emit('removeListener', type, listener); 731 | } 732 | 733 | return this; 734 | }; 735 | 736 | EventEmitter.prototype.removeAllListeners = function (type) { 737 | var key, listeners; 738 | 739 | if (!this._events) return this; 740 | 741 | // not listening for removeListener, no need to emit 742 | if (!this._events.removeListener) { 743 | if (arguments.length === 0) this._events = {};else if (this._events[type]) delete this._events[type]; 744 | return this; 745 | } 746 | 747 | // emit removeListener for all listeners on all events 748 | if (arguments.length === 0) { 749 | for (key in this._events) { 750 | if (key === 'removeListener') continue; 751 | this.removeAllListeners(key); 752 | } 753 | this.removeAllListeners('removeListener'); 754 | this._events = {}; 755 | return this; 756 | } 757 | 758 | listeners = this._events[type]; 759 | 760 | if (isFunction(listeners)) { 761 | this.removeListener(type, listeners); 762 | } else if (listeners) { 763 | // LIFO order 764 | while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); 765 | } 766 | delete this._events[type]; 767 | 768 | return this; 769 | }; 770 | 771 | EventEmitter.prototype.listeners = function (type) { 772 | var ret; 773 | if (!this._events || !this._events[type]) ret = [];else if (isFunction(this._events[type])) ret = [this._events[type]];else ret = this._events[type].slice(); 774 | return ret; 775 | }; 776 | 777 | EventEmitter.prototype.listenerCount = function (type) { 778 | if (this._events) { 779 | var evlistener = this._events[type]; 780 | 781 | if (isFunction(evlistener)) return 1;else if (evlistener) return evlistener.length; 782 | } 783 | return 0; 784 | }; 785 | 786 | EventEmitter.listenerCount = function (emitter, type) { 787 | return emitter.listenerCount(type); 788 | }; 789 | 790 | function isFunction(arg) { 791 | return typeof arg === 'function'; 792 | } 793 | 794 | function isNumber(arg) { 795 | return typeof arg === 'number'; 796 | } 797 | 798 | function isObject(arg) { 799 | return typeof arg === 'object' && arg !== null; 800 | } 801 | 802 | function isUndefined(arg) { 803 | return arg === void 0; 804 | } 805 | 806 | /***/ }, 807 | 808 | /***/ 167: 809 | /***/ function(module, exports, __webpack_require__) { 810 | 811 | 'use strict'; 812 | 813 | var _actionToMethodsMapping; 814 | 815 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 816 | 817 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 818 | 819 | function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } } 820 | 821 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } 822 | 823 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 824 | 825 | function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 826 | 827 | var _constantsTodoFilters = __webpack_require__(163); 828 | 829 | var AppDispatcher = __webpack_require__(168); 830 | var TodoConstants = __webpack_require__(172); 831 | var BaseStore = __webpack_require__(174); 832 | 833 | var TodoStoreClass = (function (_BaseStore) { 834 | _inherits(TodoStoreClass, _BaseStore); 835 | 836 | function TodoStoreClass() { 837 | _classCallCheck(this, TodoStoreClass); 838 | 839 | _get(Object.getPrototypeOf(TodoStoreClass.prototype), 'constructor', this).call(this); 840 | if (this.state.todos.length !== 0) { 841 | this.counter = this.state.todos[this.state.todos.length - 1].id + 1; 842 | } else { 843 | this.counter = this.state.todos.length; 844 | } 845 | } 846 | 847 | _createClass(TodoStoreClass, [{ 848 | key: 'getInitialState', 849 | value: function getInitialState() { 850 | var defaultState = { 851 | todos: [], 852 | selectedFilter: _constantsTodoFilters.SHOW_ALL 853 | }; 854 | return defaultState; 855 | // try { 856 | // var state = JSON.parse(window.localStorage.getItem("todoStore")); 857 | // if (state !== null && state !== undefined) { 858 | // return state; 859 | // } else { 860 | // return defaultState; 861 | // } 862 | // } catch (ex) { 863 | // return defaultState; 864 | // } 865 | } 866 | }, { 867 | key: 'addTodo', 868 | value: function addTodo(text) { 869 | this.setState({ 870 | todos: [].concat(_toConsumableArray(this.state.todos), [{ 871 | task: text, 872 | done: false, 873 | id: this.counter 874 | }]) 875 | }); 876 | this.counter++; 877 | } 878 | }, { 879 | key: 'duringSetState', 880 | value: function duringSetState() { 881 | this.state.completed = this.getTotalCompleted(); 882 | this.state.uncompleted = this.state.todos.length - this.state.completed; 883 | //window.localStorage.setItem("todoStore", JSON.stringify(this.state)); 884 | } 885 | }, { 886 | key: 'markComplete', 887 | value: function markComplete(id) { 888 | this.setState({ 889 | todos: this.state.todos.map(function (v) { 890 | if (v.id === id) { 891 | v.done = true; 892 | } 893 | return v; 894 | }) 895 | }); 896 | } 897 | }, { 898 | key: 'remove', 899 | value: function remove(id) { 900 | this.setState({ 901 | todos: this.state.todos.filter(function (v) { 902 | return v.id !== id; 903 | }) 904 | }); 905 | } 906 | }, { 907 | key: 'removeAllCompleted', 908 | value: function removeAllCompleted() { 909 | this.setState({ 910 | todos: this.state.todos.filter(function (v) { 911 | return v.done === false; 912 | }) 913 | }); 914 | } 915 | }, { 916 | key: 'markAllComplete', 917 | value: function markAllComplete() { 918 | this.setState({ 919 | todos: this.state.todos.map(function (v) { 920 | v.done = true; 921 | return v; 922 | }) 923 | }); 924 | } 925 | }, { 926 | key: 'edit', 927 | value: function edit(id, task) { 928 | this.setState({ 929 | todos: this.state.todos.map(function (v) { 930 | if (v.id === id) { 931 | v.task = task; 932 | } 933 | return v; 934 | }) 935 | }); 936 | } 937 | }, { 938 | key: 'markAllUnComplete', 939 | value: function markAllUnComplete() { 940 | this.setState({ 941 | todos: this.state.todos.map(function (v) { 942 | v.done = false; 943 | return v; 944 | }) 945 | }); 946 | } 947 | }, { 948 | key: 'markUnComplete', 949 | value: function markUnComplete(id) { 950 | this.setState({ 951 | todos: this.state.todos.map(function (v) { 952 | if (v.id === id) { 953 | v.done = false; 954 | } 955 | return v; 956 | }) 957 | }); 958 | } 959 | }, { 960 | key: 'getTotalCompleted', 961 | value: function getTotalCompleted() { 962 | return this.state.todos.filter(function (v) { 963 | return v.done === true; 964 | }).length; 965 | } 966 | }, { 967 | key: 'onShow', 968 | value: function onShow(filter) { 969 | this.setState({ selectedFilter: filter, todos: this.state.todos }); 970 | } 971 | }]); 972 | 973 | return TodoStoreClass; 974 | })(BaseStore); 975 | 976 | var TodoStore = new TodoStoreClass(); 977 | var actionToMethodsMapping = (_actionToMethodsMapping = {}, _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_CREATE, "addTodo"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_REMOVE, "remove"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_MARK_COMPLETE, "markComplete"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_EDIT, "edit"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_MARK_UNCOMPLETE, "markUnComplete"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_MARK_ALL_COMPLETE, "markAllComplete"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_MARK_ALL_UNCOMPLETE, "markAllUnComplete"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_REMOVE_ALL_COMPLETED, "removeAllCompleted"), _defineProperty(_actionToMethodsMapping, TodoConstants.TODO_ON_SHOW, "onShow"), _actionToMethodsMapping); 978 | 979 | AppDispatcher.register(function (e) { 980 | var action = e.action; 981 | if (actionToMethodsMapping[action.actionType] !== undefined) { 982 | TodoStore[actionToMethodsMapping[action.actionType]].apply(TodoStore, action.args); 983 | } 984 | }); 985 | module.exports = TodoStore; 986 | 987 | /***/ }, 988 | 989 | /***/ 168: 990 | /***/ function(module, exports, __webpack_require__) { 991 | 992 | "use strict"; 993 | 994 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 995 | 996 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 997 | 998 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 999 | 1000 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 1001 | 1002 | var Dispatcher = __webpack_require__(169).Dispatcher; 1003 | 1004 | var AppDispatcher = (function (_Dispatcher) { 1005 | _inherits(AppDispatcher, _Dispatcher); 1006 | 1007 | function AppDispatcher() { 1008 | _classCallCheck(this, AppDispatcher); 1009 | 1010 | _get(Object.getPrototypeOf(AppDispatcher.prototype), "constructor", this).call(this); 1011 | } 1012 | 1013 | _createClass(AppDispatcher, [{ 1014 | key: "handleViewAction", 1015 | value: function handleViewAction(action) { 1016 | //console.log(action); 1017 | this.dispatch({ 1018 | source: "VIEW_ACTION", 1019 | action: action 1020 | }); 1021 | } 1022 | }]); 1023 | 1024 | return AppDispatcher; 1025 | })(Dispatcher); 1026 | 1027 | module.exports = new AppDispatcher(); 1028 | 1029 | /***/ }, 1030 | 1031 | /***/ 169: 1032 | /***/ function(module, exports, __webpack_require__) { 1033 | 1034 | /** 1035 | * Copyright (c) 2014-2015, Facebook, Inc. 1036 | * All rights reserved. 1037 | * 1038 | * This source code is licensed under the BSD-style license found in the 1039 | * LICENSE file in the root directory of this source tree. An additional grant 1040 | * of patent rights can be found in the PATENTS file in the same directory. 1041 | */ 1042 | 1043 | 'use strict'; 1044 | 1045 | module.exports.Dispatcher = __webpack_require__(170); 1046 | 1047 | /***/ }, 1048 | 1049 | /***/ 170: 1050 | /***/ function(module, exports, __webpack_require__) { 1051 | 1052 | /* WEBPACK VAR INJECTION */(function(process) {/** 1053 | * Copyright (c) 2014-2015, Facebook, Inc. 1054 | * All rights reserved. 1055 | * 1056 | * This source code is licensed under the BSD-style license found in the 1057 | * LICENSE file in the root directory of this source tree. An additional grant 1058 | * of patent rights can be found in the PATENTS file in the same directory. 1059 | * 1060 | * @providesModule Dispatcher 1061 | * 1062 | * @preventMunge 1063 | */ 1064 | 1065 | 'use strict'; 1066 | 1067 | exports.__esModule = true; 1068 | 1069 | function _classCallCheck(instance, Constructor) { 1070 | if (!(instance instanceof Constructor)) { 1071 | throw new TypeError('Cannot call a class as a function'); 1072 | } 1073 | } 1074 | 1075 | var invariant = __webpack_require__(171); 1076 | 1077 | var _prefix = 'ID_'; 1078 | 1079 | /** 1080 | * Dispatcher is used to broadcast payloads to registered callbacks. This is 1081 | * different from generic pub-sub systems in two ways: 1082 | * 1083 | * 1) Callbacks are not subscribed to particular events. Every payload is 1084 | * dispatched to every registered callback. 1085 | * 2) Callbacks can be deferred in whole or part until other callbacks have 1086 | * been executed. 1087 | * 1088 | * For example, consider this hypothetical flight destination form, which 1089 | * selects a default city when a country is selected: 1090 | * 1091 | * var flightDispatcher = new Dispatcher(); 1092 | * 1093 | * // Keeps track of which country is selected 1094 | * var CountryStore = {country: null}; 1095 | * 1096 | * // Keeps track of which city is selected 1097 | * var CityStore = {city: null}; 1098 | * 1099 | * // Keeps track of the base flight price of the selected city 1100 | * var FlightPriceStore = {price: null} 1101 | * 1102 | * When a user changes the selected city, we dispatch the payload: 1103 | * 1104 | * flightDispatcher.dispatch({ 1105 | * actionType: 'city-update', 1106 | * selectedCity: 'paris' 1107 | * }); 1108 | * 1109 | * This payload is digested by `CityStore`: 1110 | * 1111 | * flightDispatcher.register(function(payload) { 1112 | * if (payload.actionType === 'city-update') { 1113 | * CityStore.city = payload.selectedCity; 1114 | * } 1115 | * }); 1116 | * 1117 | * When the user selects a country, we dispatch the payload: 1118 | * 1119 | * flightDispatcher.dispatch({ 1120 | * actionType: 'country-update', 1121 | * selectedCountry: 'australia' 1122 | * }); 1123 | * 1124 | * This payload is digested by both stores: 1125 | * 1126 | * CountryStore.dispatchToken = flightDispatcher.register(function(payload) { 1127 | * if (payload.actionType === 'country-update') { 1128 | * CountryStore.country = payload.selectedCountry; 1129 | * } 1130 | * }); 1131 | * 1132 | * When the callback to update `CountryStore` is registered, we save a reference 1133 | * to the returned token. Using this token with `waitFor()`, we can guarantee 1134 | * that `CountryStore` is updated before the callback that updates `CityStore` 1135 | * needs to query its data. 1136 | * 1137 | * CityStore.dispatchToken = flightDispatcher.register(function(payload) { 1138 | * if (payload.actionType === 'country-update') { 1139 | * // `CountryStore.country` may not be updated. 1140 | * flightDispatcher.waitFor([CountryStore.dispatchToken]); 1141 | * // `CountryStore.country` is now guaranteed to be updated. 1142 | * 1143 | * // Select the default city for the new country 1144 | * CityStore.city = getDefaultCityForCountry(CountryStore.country); 1145 | * } 1146 | * }); 1147 | * 1148 | * The usage of `waitFor()` can be chained, for example: 1149 | * 1150 | * FlightPriceStore.dispatchToken = 1151 | * flightDispatcher.register(function(payload) { 1152 | * switch (payload.actionType) { 1153 | * case 'country-update': 1154 | * case 'city-update': 1155 | * flightDispatcher.waitFor([CityStore.dispatchToken]); 1156 | * FlightPriceStore.price = 1157 | * getFlightPriceStore(CountryStore.country, CityStore.city); 1158 | * break; 1159 | * } 1160 | * }); 1161 | * 1162 | * The `country-update` payload will be guaranteed to invoke the stores' 1163 | * registered callbacks in order: `CountryStore`, `CityStore`, then 1164 | * `FlightPriceStore`. 1165 | */ 1166 | 1167 | var Dispatcher = (function () { 1168 | function Dispatcher() { 1169 | _classCallCheck(this, Dispatcher); 1170 | 1171 | this._callbacks = {}; 1172 | this._isDispatching = false; 1173 | this._isHandled = {}; 1174 | this._isPending = {}; 1175 | this._lastID = 1; 1176 | } 1177 | 1178 | /** 1179 | * Registers a callback to be invoked with every dispatched payload. Returns 1180 | * a token that can be used with `waitFor()`. 1181 | */ 1182 | 1183 | Dispatcher.prototype.register = function register(callback) { 1184 | var id = _prefix + this._lastID++; 1185 | this._callbacks[id] = callback; 1186 | return id; 1187 | }; 1188 | 1189 | /** 1190 | * Removes a callback based on its token. 1191 | */ 1192 | 1193 | Dispatcher.prototype.unregister = function unregister(id) { 1194 | !this._callbacks[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.unregister(...): `%s` does not map to a registered callback.', id) : invariant(false) : undefined; 1195 | delete this._callbacks[id]; 1196 | }; 1197 | 1198 | /** 1199 | * Waits for the callbacks specified to be invoked before continuing execution 1200 | * of the current callback. This method should only be used by a callback in 1201 | * response to a dispatched payload. 1202 | */ 1203 | 1204 | Dispatcher.prototype.waitFor = function waitFor(ids) { 1205 | !this._isDispatching ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): Must be invoked while dispatching.') : invariant(false) : undefined; 1206 | for (var ii = 0; ii < ids.length; ii++) { 1207 | var id = ids[ii]; 1208 | if (this._isPending[id]) { 1209 | !this._isHandled[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.', id) : invariant(false) : undefined; 1210 | continue; 1211 | } 1212 | !this._callbacks[id] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', id) : invariant(false) : undefined; 1213 | this._invokeCallback(id); 1214 | } 1215 | }; 1216 | 1217 | /** 1218 | * Dispatches a payload to all registered callbacks. 1219 | */ 1220 | 1221 | Dispatcher.prototype.dispatch = function dispatch(payload) { 1222 | !!this._isDispatching ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.') : invariant(false) : undefined; 1223 | this._startDispatching(payload); 1224 | try { 1225 | for (var id in this._callbacks) { 1226 | if (this._isPending[id]) { 1227 | continue; 1228 | } 1229 | this._invokeCallback(id); 1230 | } 1231 | } finally { 1232 | this._stopDispatching(); 1233 | } 1234 | }; 1235 | 1236 | /** 1237 | * Is this Dispatcher currently dispatching. 1238 | */ 1239 | 1240 | Dispatcher.prototype.isDispatching = function isDispatching() { 1241 | return this._isDispatching; 1242 | }; 1243 | 1244 | /** 1245 | * Call the callback stored with the given id. Also do some internal 1246 | * bookkeeping. 1247 | * 1248 | * @internal 1249 | */ 1250 | 1251 | Dispatcher.prototype._invokeCallback = function _invokeCallback(id) { 1252 | this._isPending[id] = true; 1253 | this._callbacks[id](this._pendingPayload); 1254 | this._isHandled[id] = true; 1255 | }; 1256 | 1257 | /** 1258 | * Set up bookkeeping needed when dispatching. 1259 | * 1260 | * @internal 1261 | */ 1262 | 1263 | Dispatcher.prototype._startDispatching = function _startDispatching(payload) { 1264 | for (var id in this._callbacks) { 1265 | this._isPending[id] = false; 1266 | this._isHandled[id] = false; 1267 | } 1268 | this._pendingPayload = payload; 1269 | this._isDispatching = true; 1270 | }; 1271 | 1272 | /** 1273 | * Clear bookkeeping used for dispatching. 1274 | * 1275 | * @internal 1276 | */ 1277 | 1278 | Dispatcher.prototype._stopDispatching = function _stopDispatching() { 1279 | delete this._pendingPayload; 1280 | this._isDispatching = false; 1281 | }; 1282 | 1283 | return Dispatcher; 1284 | })(); 1285 | 1286 | module.exports = Dispatcher; 1287 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 1288 | 1289 | /***/ }, 1290 | 1291 | /***/ 171: 1292 | /***/ function(module, exports, __webpack_require__) { 1293 | 1294 | /* WEBPACK VAR INJECTION */(function(process) {/** 1295 | * Copyright 2013-2015, Facebook, Inc. 1296 | * All rights reserved. 1297 | * 1298 | * This source code is licensed under the BSD-style license found in the 1299 | * LICENSE file in the root directory of this source tree. An additional grant 1300 | * of patent rights can be found in the PATENTS file in the same directory. 1301 | * 1302 | * @providesModule invariant 1303 | */ 1304 | 1305 | "use strict"; 1306 | 1307 | /** 1308 | * Use invariant() to assert state which your program assumes to be true. 1309 | * 1310 | * Provide sprintf-style format (only %s is supported) and arguments 1311 | * to provide information about what broke and what you were 1312 | * expecting. 1313 | * 1314 | * The invariant message will be stripped in production, but the invariant 1315 | * will remain to ensure logic does not differ in production. 1316 | */ 1317 | 1318 | var invariant = function invariant(condition, format, a, b, c, d, e, f) { 1319 | if (process.env.NODE_ENV !== 'production') { 1320 | if (format === undefined) { 1321 | throw new Error('invariant requires an error message argument'); 1322 | } 1323 | } 1324 | 1325 | if (!condition) { 1326 | var error; 1327 | if (format === undefined) { 1328 | error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); 1329 | } else { 1330 | var args = [a, b, c, d, e, f]; 1331 | var argIndex = 0; 1332 | error = new Error('Invariant Violation: ' + format.replace(/%s/g, function () { 1333 | return args[argIndex++]; 1334 | })); 1335 | } 1336 | 1337 | error.framesToPop = 1; // we don't care about invariant's own frame 1338 | throw error; 1339 | } 1340 | }; 1341 | 1342 | module.exports = invariant; 1343 | /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 1344 | 1345 | /***/ }, 1346 | 1347 | /***/ 172: 1348 | /***/ function(module, exports, __webpack_require__) { 1349 | 1350 | 'use strict'; 1351 | 1352 | var keymirror = __webpack_require__(173); 1353 | 1354 | var TodoConstants = keymirror({ 1355 | TODO_CREATE: null, 1356 | TODO_REMOVE: null, 1357 | TODO_EDIT: null, 1358 | TODO_MARK_COMPLETE: null, 1359 | TODO_MARK_UNCOMPLETE: null, 1360 | TODO_MARK_ALL_COMPLETE: null, 1361 | TODO_MARK_ALL_UNCOMPLETE: null, 1362 | TODO_REMOVE_ALL_COMPLETED: null, 1363 | TODO_ON_SHOW: null 1364 | }); 1365 | 1366 | module.exports = TodoConstants; 1367 | 1368 | /***/ }, 1369 | 1370 | /***/ 173: 1371 | /***/ function(module, exports) { 1372 | 1373 | /** 1374 | * Copyright 2013-2014 Facebook, Inc. 1375 | * 1376 | * Licensed under the Apache License, Version 2.0 (the "License"); 1377 | * you may not use this file except in compliance with the License. 1378 | * You may obtain a copy of the License at 1379 | * 1380 | * http://www.apache.org/licenses/LICENSE-2.0 1381 | * 1382 | * Unless required by applicable law or agreed to in writing, software 1383 | * distributed under the License is distributed on an "AS IS" BASIS, 1384 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1385 | * See the License for the specific language governing permissions and 1386 | * limitations under the License. 1387 | * 1388 | */ 1389 | 1390 | "use strict"; 1391 | 1392 | /** 1393 | * Constructs an enumeration with keys equal to their value. 1394 | * 1395 | * For example: 1396 | * 1397 | * var COLORS = keyMirror({blue: null, red: null}); 1398 | * var myColor = COLORS.blue; 1399 | * var isColorValid = !!COLORS[myColor]; 1400 | * 1401 | * The last line could not be performed if the values of the generated enum were 1402 | * not equal to their keys. 1403 | * 1404 | * Input: {key1: val1, key2: val2} 1405 | * Output: {key1: key1, key2: key2} 1406 | * 1407 | * @param {object} obj 1408 | * @return {object} 1409 | */ 1410 | var keyMirror = function keyMirror(obj) { 1411 | var ret = {}; 1412 | var key; 1413 | if (!(obj instanceof Object && !Array.isArray(obj))) { 1414 | throw new Error('keyMirror(...): Argument must be an object.'); 1415 | } 1416 | for (key in obj) { 1417 | if (!obj.hasOwnProperty(key)) { 1418 | continue; 1419 | } 1420 | ret[key] = key; 1421 | } 1422 | return ret; 1423 | }; 1424 | 1425 | module.exports = keyMirror; 1426 | 1427 | /***/ }, 1428 | 1429 | /***/ 174: 1430 | /***/ function(module, exports, __webpack_require__) { 1431 | 1432 | 'use strict'; 1433 | 1434 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 1435 | 1436 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 1437 | 1438 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 1439 | 1440 | function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 1441 | 1442 | var EventEmitter = __webpack_require__(166).EventEmitter; 1443 | 1444 | var BaseStore = (function (_EventEmitter) { 1445 | _inherits(BaseStore, _EventEmitter); 1446 | 1447 | function BaseStore() { 1448 | _classCallCheck(this, BaseStore); 1449 | 1450 | _get(Object.getPrototypeOf(BaseStore.prototype), 'constructor', this).call(this); 1451 | this.setState(this.getInitialState()); 1452 | } 1453 | 1454 | _createClass(BaseStore, [{ 1455 | key: 'getState', 1456 | value: function getState() { 1457 | return this.state; 1458 | } 1459 | }, { 1460 | key: 'setState', 1461 | value: function setState(state) { 1462 | this.state = state; 1463 | this.duringSetState(); 1464 | this.emit('change'); 1465 | } 1466 | }, { 1467 | key: 'getInitialState', 1468 | value: function getInitialState() { 1469 | return {}; 1470 | } 1471 | }]); 1472 | 1473 | return BaseStore; 1474 | })(EventEmitter); 1475 | 1476 | module.exports = BaseStore; 1477 | 1478 | /***/ }, 1479 | 1480 | /***/ 175: 1481 | /***/ function(module, exports, __webpack_require__) { 1482 | 1483 | /** 1484 | * TodoActions 1485 | */ 1486 | 1487 | "use strict"; 1488 | 1489 | var AppDispatcher = __webpack_require__(168); 1490 | 1491 | var TodoConstants = __webpack_require__(172); 1492 | 1493 | var actionAlias = { 1494 | addTodo: TodoConstants.TODO_CREATE, 1495 | remove: TodoConstants.TODO_REMOVE, 1496 | markComplete: TodoConstants.TODO_MARK_COMPLETE, 1497 | markUnComplete: TodoConstants.TODO_MARK_UNCOMPLETE, 1498 | edit: TodoConstants.TODO_EDIT, 1499 | markAllComplete: TodoConstants.TODO_MARK_ALL_COMPLETE, 1500 | removeAllCompleted: TodoConstants.TODO_REMOVE_ALL_COMPLETED, 1501 | markAllUnComplete: TodoConstants.TODO_MARK_ALL_UNCOMPLETE, 1502 | onShow: TodoConstants.TODO_ON_SHOW 1503 | }; 1504 | 1505 | var TodoActions = {}; 1506 | Object.keys(actionAlias).map(function (key) { 1507 | TodoActions[key] = function () { 1508 | AppDispatcher.handleViewAction({ 1509 | actionType: actionAlias[key], 1510 | args: arguments 1511 | }); 1512 | }; 1513 | }); 1514 | 1515 | //window.TodoActions = TodoActions; 1516 | module.exports = TodoActions; 1517 | 1518 | /***/ } 1519 | 1520 | /******/ }); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |43 | bridge.post("/actions/TodoActions/addTodo", "TodoAdded From Console"); 44 |45 |
46 | bridge.post("/actions/TodoActions/markComplete", 0); 47 |48 |