GitHub PullRequestReviewCommentEvent at 2014-12-23 00:25:05
Repository: objectstate
Actor: AWinterman
Payload: {"action":"created","comment":{"url":"https://api.github.com/repos/urbanairship/objectstate/pulls/comments/22198861","id":22198861,"diff_hunk":"@@ -1,152 +1,139 @@\n // Copyright 2014 Urban Airship and Contributors\n \n-var Stream = require('stream')\n+var through = require('through')\n \n-function ObjectState(initial) {\n-  Stream.call(this)\n+var deepequal = require('deep-equal')\n+  , prop = require('deep-property')\n \n-  this.writable = true\n-  this.readable = true\n-  this.state = initial || {}\n-}\n+module.exports = objectState\n \n-var cons = ObjectState\n-  , proto = cons.prototype = Object.create(Stream.prototype)\n+function objectState(_initial) {\n+  var state = deepcopy(_initial) || {}\n+    , stream = through(write)\n \n-proto.constructor = cons\n+  stream.get = get\n+  stream.set = set\n+  stream.remove = remove\n \n-proto.wait = function(fn) {\n-  var should_emit = false\n+  stream.listen = listen\n+  stream.listenOn = listenOn\n \n-  // shadow the prototype property\n-  this.emit = function() {\n-    should_emit = true\n-  }\n+  stream.wait = wait\n \n-  try {\n-    fn()\n-  } finally {\n-    delete this.emit\n-    should_emit && this.emitState()\n-  }\n-}\n+  stream.state = copyState\n+  stream.emitState = emitState\n \n-proto.listen = function(ee, name, params) {\n-  ee.on(name, this.receive_event.bind(this, params))\n+  return stream\n \n-  return this\n-}\n-\n-proto.emitState = function() {\n-  this.emit('data', this.state)\n-}\n-\n-proto.deepcopy = function() {\n-  return JSON.parse(JSON.stringify(this.state))\n-}\n+  function write(data) {\n+    if(equal(state, data)) {\n+      return\n+    }\n \n-proto.copy = function() {\n-  var out = {}\n+    state = deepcopy(data)\n \n-  for(var key in this.state) {\n-    out[key] = this.state[key]\n+    emitState()\n   }\n \n-  return out\n-}\n-\n-proto.snapshot = function(deep) {\n-  deep = deep === undefined ? true : deep\n+  function get(keypath) {\n+    return deepcopy(prop.get(state, keypath))\n+  }\n \n-  var self = this\n-    , state = self[deep ? 'deepcopy' : 'copy']()\n+  function set(keypath, val) {\n+    if(equal(get(keypath), val)) {\n+      return\n+    }\n \n-  return restore\n+    prop.set(state, keypath, deepcopy(val))\n \n-  function restore() {\n-    self.state = state\n-    self.emitState()\n+    emitState()\n   }\n-}\n-\n-proto.include = function(os) {\n-  var self = this\n \n-  os.on('data', ondata)\n-    .on('delete-key', ondeletekey)\n+  function remove(keypath) {\n+    var shouldEmit = prop.remove(state, keypath)\n \n-  return os\n-\n-  function ondata(state) {\n-    for(var key in state) {\n-      self.state[key] = state[key]\n+    if(shouldEmit) {\n+      stream.queue(state)\n     }\n-\n-    self.emitState()\n   }\n \n-  function ondeletekey(key) {\n-    self._remove(key)\n+  function listen(src, keypath) {\n+    src.on('data', function(data) {\n+      set(keypath, data)\n+    })\n+\n+    return stream\n   }\n-}\n \n-proto.get = function(key) {\n-  return this.state[key]\n-}\n+  function listenOn(ee, name, params) {\n+    var paramsLength = params.length\n \n-proto.set = function(key, val) {\n-  this.state[key] = val\n+    ee.on(name, receiveEvent)\n \n-  this.emitState()\n-}\n+    return stream\n \n-proto.remove = function(attr) {\n-  this._remove(attr)\n-  this.emitState()\n-}\n+    function receiveEvent() {\n+      var args = [].slice.call(arguments)\n \n-proto.write = function(data) {\n-  this.state = data\n+      wait(setParams)\n \n-  this.emitState()\n-}\n-\n-proto._remove = function(attr) {\n-  if(this.state.hasOwnProperty(attr)) {\n-    delete this.state[attr]\n+      function setParams() {\n+        var param\n+          , arg\n \n-    this.emit('delete-key', attr)\n-  }\n-}\n+        for(var i = 0; i < paramsLength; ++i) {","path":"index.js","position":172,"original_position":172,"commit_id":"c3a4d8891b75ff92a3f0fe20dd191be836a2f6c0","original_commit_id":"c3a4d8891b75ff92a3f0fe20dd191be836a2f6c0","user":{"login":"AWinterman","id":524923,"avatar_url":"https://avatars.githubusercontent.com/u/524923?v=3","gravatar_id":"","url":"https://api.github.com/users/AWinterman","html_url":"https://github.com/AWinterman","followers_url":"https://api.github.com/users/AWinterman/followers","following_url":"https://api.github.com/users/AWinterman/following{/other_user}","gists_url":"https://api.github.com/users/AWinterman/gists{/gist_id}","starred_url":"https://api.github.com/users/AWinterman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AWinterman/subscriptions","organizations_url":"https://api.github.com/users/AWinterman/orgs","repos_url":"https://api.github.com/users/AWinterman/repos","events_url":"https://api.github.com/users/AWinterman/events{/privacy}","received_events_url":"https://api.github.com/users/AWinterman/received_events","type":"User","site_admin":false},"body":":heart: this makes me happy.","created_at":"2014-12-23T00:25:05Z","updated_at":"2014-12-23T00:25:05Z","html_url":"https://github.com/urbanairship/objectstate/pull/14#discussion_r22198861","pull_request_url":"https://api.github.com/repos/urbanairship/objectstate/pulls/14","_links":{"self":{"href":"https://api.github.com/repos/urbanairship/objectstate/pulls/comments/22198861"},"html":{"href":"https://github.com/urbanairship/objectstate/pull/14#discussion_r22198861"},"pull_request":{"href":"https://api.github.com/repos/urbanairship/objectstate/pulls/14"}}},"pull_request":{"url":"https://api.github.com/repos/urbanairship/objectstate/pulls/14","id":26489302,"html_url":"https://github.com/urbanairship/objectstate/pull/14","diff_url":"https://github.com/urbanairship/objectstate/pull/14.diff","patch_url":"https://github.com/urbanairship/objectstate/pull/14.patch","issue_url":"https://api.github.com/repos/urbanairship/objectstate/issues/14","number":14,"state":"open","locked":false,"title":"Emit on change, deep copy objects","user":{"login":"jarofghosts","id":1013892,"avatar_url":"https://avatars.githubusercontent.com/u/1013892?v=3","gravatar_id":"","url":"https://api.github.com/users/jarofghosts","html_url":"https://github.com/jarofghosts","followers_url":"https://api.github.com/users/jarofghosts/followers","following_url":"https://api.github.com/users/jarofghosts/following{/other_user}","gists_url":"https://api.github.com/users/jarofghosts/gists{/gist_id}","starred_url":"https://api.github.com/users/jarofghosts/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jarofghosts/subscriptions","organizations_url":"https://api.github.com/users/jarofghosts/orgs","repos_url":"https://api.github.com/users/jarofghosts/repos","events_url":"https://api.github.com/users/jarofghosts/events{/privacy}","received_events_url":"https://api.github.com/users/jarofghosts/received_events","type":"User","site_admin":false},"body":"To version: `2.0.0`\r\n\r\n* Only emit on change\r\n* Deep copy all objects on input and output\r\n* Add keypath access\r\n* Fix nested `.wait()`\r\n\r\nThis also, somewhat controversially, switches ObjectState to use a more \"functional\" style internally. This successfully hides the internal state object from any outside mutation, and does not present any notable performance hits.","created_at":"2014-12-23T00:09:38Z","updated_at":"2014-12-23T00:25:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a360022d2b610ab24298b456048e8d6f176abac9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/urbanairship/objectstate/pulls/14/commits","review_comments_url":"https://api.github.com/repos/urbanairship/objectstate/pulls/14/comments","review_comment_url":"https://api.github.com/repos/urbanairship/objectstate/pulls/comments/{number}","comments_url":"https://api.github.com/repos/urbanairship/objectstate/issues/14/comments","statuses_url":"https://api.github.com/repos/urbanairship/objectstate/statuses/c3a4d8891b75ff92a3f0fe20dd191be836a2f6c0","head":{"label":"urbanairship:version-2","ref":"version-2","sha":"c3a4d8891b75ff92a3f0fe20dd191be836a2f6c0","user":{"login":"urbanairship","id":360059,"avatar_url":"https://avatars.githubusercontent.com/u/360059?v=3","gravatar_id":"","url":"https://api.github.com/users/urbanairship","html_url":"https://github.com/urbanairship","followers_url":"https://api.github.com/users/urbanairship/followers","following_url":"https://api.github.com/users/urbanairship/following{/other_user}","gists_url":"https://api.github.com/users/urbanairship/gists{/gist_id}","starred_url":"https://api.github.com/users/urbanairship/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/urbanairship/subscriptions","organizations_url":"https://api.github.com/users/urbanairship/orgs","repos_url":"https://api.github.com/users/urbanairship/repos","events_url":"https://api.github.com/users/urbanairship/events{/privacy}","received_events_url":"https://api.github.com/users/urbanairship/received_events","type":"Organization","site_admin":false},"repo":{"id":28195890,"name":"objectstate","full_name":"urbanairship/objectstate","owner":{"login":"urbanairship","id":360059,"avatar_url":"https://avatars.githubusercontent.com/u/360059?v=3","gravatar_id":"","url":"https://api.github.com/users/urbanairship","html_url":"https://github.com/urbanairship","followers_url":"https://api.github.com/users/urbanairship/followers","following_url":"https://api.github.com/users/urbanairship/following{/other_user}","gists_url":"https://api.github.com/users/urbanairship/gists{/gist_id}","starred_url":"https://api.github.com/users/urbanairship/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/urbanairship/subscriptions","organizations_url":"https://api.github.com/users/urbanairship/orgs","repos_url":"https://api.github.com/users/urbanairship/repos","events_url":"https://api.github.com/users/urbanairship/events{/privacy}","received_events_url":"https://api.github.com/users/urbanairship/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/urbanairship/objectstate","description":"Streaming state management for node and the browser","fork":false,"url":"https://api.github.com/repos/urbanairship/objectstate","forks_url":"https://api.github.com/repos/urbanairship/objectstate/forks","keys_url":"https://api.github.com/repos/urbanairship/objectstate/keys{/key_id}","collaborators_url":"https://api.github.com/repos/urbanairship/objectstate/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/urbanairship/objectstate/teams","hooks_url":"https://api.github.com/repos/urbanairship/objectstate/hooks","issue_events_url":"https://api.github.com/repos/urbanairship/objectstate/issues/events{/number}","events_url":"https://api.github.com/repos/urbanairship/objectstate/events","assignees_url":"https://api.github.com/repos/urbanairship/objectstate/assignees{/user}","branches_url":"https://api.github.com/repos/urbanairship/objectstate/branches{/branch}","tags_url":"https://api.github.com/repos/urbanairship/objectstate/tags","blobs_url":"https://api.github.com/repos/urbanairship/objectstate/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/urbanairship/objectstate/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/urbanairship/objectstate/git/refs{/sha}","trees_url":"https://api.github.com/repos/urbanairship/objectstate/git/trees{/sha}","statuses_url":"https://api.github.com/repos/urbanairship/objectstate/statuses/{sha}","languages_url":"https://api.github.com/repos/urbanairship/objectstate/languages","stargazers_url":"https://api.github.com/repos/urbanairship/objectstate/stargazers","contributors_url":"https://api.github.com/repos/urbanairship/objectstate/contributors","subscribers_url":"https://api.github.com/repos/urbanairship/objectstate/subscribers","subscription_url":"https://api.github.com/repos/urbanairship/objectstate/subscription","commits_url":"https://api.github.com/repos/urbanairship/objectstate/commits{/sha}","git_commits_url":"https://api.github.com/repos/urbanairship/objectstate/git/commits{/sha}","comments_url":"https://api.github.com/repos/urbanairship/objectstate/comments{/number}","issue_comment_url":"https://api.github.com/repos/urbanairship/objectstate/issues/comments/{number}","contents_url":"https://api.github.com/repos/urbanairship/objectstate/contents/{+path}","compare_url":"https://api.github.com/repos/urbanairship/objectstate/compare/{base}...{head}","merges_url":"https://api.github.com/repos/urbanairship/objectstate/merges","archive_url":"https://api.github.com/repos/urbanairship/objectstate/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/urbanairship/objectstate/downloads","issues_url":"https://api.github.com/repos/urbanairship/objectstate/issues{/number}","pulls_url":"https://api.github.com/repos/urbanairship/objectstate/pulls{/number}","milestones_url":"https://api.github.com/repos/urbanairship/objectstate/milestones{/number}","notifications_url":"https://api.github.com/repos/urbanairship/objectstate/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/urbanairship/objectstate/labels{/name}","releases_url":"https://api.github.com/repos/urbanairship/objectstate/releases{/id}","created_at":"2014-12-18T18:24:42Z","updated_at":"2014-12-22T19:59:01Z","pushed_at":"2014-12-23T00:09:00Z","git_url":"git://github.com/urbanairship/objectstate.git","ssh_url":"git@github.com:urbanairship/objectstate.git","clone_url":"https://github.com/urbanairship/objectstate.git","svn_url":"https://github.com/urbanairship/objectstate","homepage":null,"size":0,"stargazers_count":2,"watchers_count":2,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":6,"forks":0,"open_issues":6,"watchers":2,"default_branch":"master"}},"base":{"label":"urbanairship:master","ref":"master","sha":"6bc45e1479f2a4a91b308e91c763fe7b68c9061c","user":{"login":"urbanairship","id":360059,"avatar_url":"https://avatars.githubusercontent.com/u/360059?v=3","gravatar_id":"","url":"https://api.github.com/users/urbanairship","html_url":"https://github.com/urbanairship","followers_url":"https://api.github.com/users/urbanairship/followers","following_url":"https://api.github.com/users/urbanairship/following{/other_user}","gists_url":"https://api.github.com/users/urbanairship/gists{/gist_id}","starred_url":"https://api.github.com/users/urbanairship/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/urbanairship/subscriptions","organizations_url":"https://api.github.com/users/urbanairship/orgs","repos_url":"https://api.github.com/users/urbanairship/repos","events_url":"https://api.github.com/users/urbanairship/events{/privacy}","received_events_url":"https://api.github.com/users/urbanairship/received_events","type":"Organization","site_admin":false},"repo":{"id":28195890,"name":"objectstate","full_name":"urbanairship/objectstate","owner":{"login":"urbanairship","id":360059,"avatar_url":"https://avatars.githubusercontent.com/u/360059?v=3","gravatar_id":"","url":"https://api.github.com/users/urbanairship","html_url":"https://github.com/urbanairship","followers_url":"https://api.github.com/users/urbanairship/followers","following_url":"https://api.github.com/users/urbanairship/following{/other_user}","gists_url":"https://api.github.com/users/urbanairship/gists{/gist_id}","starred_url":"https://api.github.com/users/urbanairship/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/urbanairship/subscriptions","organizations_url":"https://api.github.com/users/urbanairship/orgs","repos_url":"https://api.github.com/users/urbanairship/repos","events_url":"https://api.github.com/users/urbanairship/events{/privacy}","received_events_url":"https://api.github.com/users/urbanairship/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/urbanairship/objectstate","description":"Streaming state management for node and the browser","fork":false,"url":"https://api.github.com/repos/urbanairship/objectstate","forks_url":"https://api.github.com/repos/urbanairship/objectstate/forks","keys_url":"https://api.github.com/repos/urbanairship/objectstate/keys{/key_id}","collaborators_url":"https://api.github.com/repos/urbanairship/objectstate/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/urbanairship/objectstate/teams","hooks_url":"https://api.github.com/repos/urbanairship/objectstate/hooks","issue_events_url":"https://api.github.com/repos/urbanairship/objectstate/issues/events{/number}","events_url":"https://api.github.com/repos/urbanairship/objectstate/events","assignees_url":"https://api.github.com/repos/urbanairship/objectstate/assignees{/user}","branches_url":"https://api.github.com/repos/urbanairship/objectstate/branches{/branch}","tags_url":"https://api.github.com/repos/urbanairship/objectstate/tags","blobs_url":"https://api.github.com/repos/urbanairship/objectstate/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/urbanairship/objectstate/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/urbanairship/objectstate/git/refs{/sha}","trees_url":"https://api.github.com/repos/urbanairship/objectstate/git/trees{/sha}","statuses_url":"https://api.github.com/repos/urbanairship/objectstate/statuses/{sha}","languages_url":"https://api.github.com/repos/urbanairship/objectstate/languages","stargazers_url":"https://api.github.com/repos/urbanairship/objectstate/stargazers","contributors_url":"https://api.github.com/repos/urbanairship/objectstate/contributors","subscribers_url":"https://api.github.com/repos/urbanairship/objectstate/subscribers","subscription_url":"https://api.github.com/repos/urbanairship/objectstate/subscription","commits_url":"https://api.github.com/repos/urbanairship/objectstate/commits{/sha}","git_commits_url":"https://api.github.com/repos/urbanairship/objectstate/git/commits{/sha}","comments_url":"https://api.github.com/repos/urbanairship/objectstate/comments{/number}","issue_comment_url":"https://api.github.com/repos/urbanairship/objectstate/issues/comments/{number}","contents_url":"https://api.github.com/repos/urbanairship/objectstate/contents/{+path}","compare_url":"https://api.github.com/repos/urbanairship/objectstate/compare/{base}...{head}","merges_url":"https://api.github.com/repos/urbanairship/objectstate/merges","archive_url":"https://api.github.com/repos/urbanairship/objectstate/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/urbanairship/objectstate/downloads","issues_url":"https://api.github.com/repos/urbanairship/objectstate/issues{/number}","pulls_url":"https://api.github.com/repos/urbanairship/objectstate/pulls{/number}","milestones_url":"https://api.github.com/repos/urbanairship/objectstate/milestones{/number}","notifications_url":"https://api.github.com/repos/urbanairship/objectstate/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/urbanairship/objectstate/labels{/name}","releases_url":"https://api.github.com/repos/urbanairship/objectstate/releases{/id}","created_at":"2014-12-18T18:24:42Z","updated_at":"2014-12-22T19:59:01Z","pushed_at":"2014-12-23T00:09:00Z","git_url":"git://github.com/urbanairship/objectstate.git","ssh_url":"git@github.com:urbanairship/objectstate.git","clone_url":"https://github.com/urbanairship/objectstate.git","svn_url":"https://github.com/urbanairship/objectstate","homepage":null,"size":0,"stargazers_count":2,"watchers_count":2,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":6,"forks":0,"open_issues":6,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/urbanairship/objectstate/pulls/14"},"html":{"href":"https://github.com/urbanairship/objectstate/pull/14"},"issue":{"href":"https://api.github.com/repos/urbanairship/objectstate/issues/14"},"comments":{"href":"https://api.github.com/repos/urbanairship/objectstate/issues/14/comments"},"review_comments":{"href":"https://api.github.com/repos/urbanairship/objectstate/pulls/14/comments"},"review_comment":{"href":"https://api.github.com/repos/urbanairship/objectstate/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/urbanairship/objectstate/pulls/14/commits"},"statuses":{"href":"https://api.github.com/repos/urbanairship/objectstate/statuses/c3a4d8891b75ff92a3f0fe20dd191be836a2f6c0"}}}}