{"action":"created","comment":{"url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/comments/65592716","id":65592716,"diff_hunk":"@@ -54,50 +57,105 @@ const ProjectServices = require('./sub-api/project-service');\n  */\n class CoinstacClient {\n   constructor(opts) {\n-    if (!opts) { throw new TypeError('coinstac-client requires configuration opts'); }\n-    this.appDirectory = appDirectory; // <== everybody needs me. don't move me, ok? :)\n-    mkdirp.sync(this.appDirectory); // @TODO, i know, i know. perhaps can be moved to init\n-    this.halfpenny = initializeAPIClient(this);\n+    if (!opts || !(opts instanceof Object)) {\n+      throw new TypeError('coinstac-client requires configuration opts');\n+    }\n+\n+    this.appDirectory = opts.appDirectory || appDirectory;\n+\n     this.dbRegistry = getDBRegistry(opts.db);\n+\n     this.logger = opts.logger || new Logger({ transports: [new Console()] });\n+\n     /* istanbul ignore if */\n-    if (opts.logLevel) { this.logger.level = opts.logLevel; }\n-\n-    // init sub-api services\n-    const subAPIConf = { client: this, dbRegistry: this.dbRegistry };\n-    this.auth = new Auth(subAPIConf);\n-    this.consortia = new ConsortiaService(subAPIConf);\n-    this.computations = new ComputationService(subAPIConf);\n-    this.projects = new ProjectServices(subAPIConf);\n+    if (opts.logLevel) {\n+      this.logger.level = opts.logLevel;\n+    }\n   }\n \n   /**\n-   * initialize coinstac-client-core. initialization consists of:\n-   * - instantiating an API client instance\n-   * - applying security headers to our PouchDB stores\n-   * @param {function} cb calls back with signature (err, undefined)\n-   * @returns {undefined}\n+   * Initialize.\n+   *\n+   * Start up coinstac-client-core. Initialization consists of:\n+   *\n+   *   * instantiating an API client instance\n+   *   * applying security headers to our PouchDB stores\n+   *\n+   * @param {Object} credentials\n+   * @param {string} credentials.password\n+   * @param {string} credentials.username\n+   * @param {string} [credentials.email]\n+   * @param {string} [credentials.name]\n+   * @param {Function} [cb] calls back with signature (err, undefined)\n+   * @returns {Promise} Rejects with an initialization error or resolves with\n+   * `undefined`.\n    */\n-  initialize(cb) {\n+  initialize(credentials, cb) {\n+    if (!(this instanceof CoinstacClient)) {\n+      throw new TypeError('expected `this` to be CoinstacClient instance');\n+    } else if (\n+      typeof credentials === 'undefined' || !(credentials instanceof Object)\n+    ) {\n+      throw new TypeError('Expected credentials object');\n+    } else if (!credentials.password || !credentials.username) {\n+      throw new TypeError(\n+        'Expected credentials to contain a username and password'\n+      );\n+    }\n+\n+    const callback = cb && cb instanceof Function ? cb : noop;\n+    const halfpennyDirectory = path.join(this.appDirectory, '.halfpenny');\n+\n     this.logger.info('initializing coinstac-client');\n-    try {\n-      /* istanbul ignore if */\n-      if (!(this instanceof CoinstacClient)) {\n-        throw new TypeError('expected `this` to be CoinstacClient instance');\n-      }\n-      /* istanbul ignore if */\n-      if (typeof cb === 'undefined' || !(cb instanceof Function)) {\n-        throw new TypeError('`initialize` requires callback');\n-      }\n+\n+    return new Promise((resolve, reject) => {\n       async.series([\n-        (cb) => hawkifyPouchy.inject(this, cb),\n-        (cb) => this._initComputationRegistry(cb),\n-        (cb) => this._initPool(cb),\n-        (cb) => this.pool.init(cb),\n-      ], cb);\n-    } catch (err) {\n-      return cb(err);\n-    }\n+        (cb1) => mkdirp(halfpennyDirectory, cb1),\n+        (cb2) => {\n+          const subAPIConf = {\n+            client: this,\n+            dbRegistry: this.dbRegistry,\n+          };\n+\n+          this.halfpenny = initializeAPIClient(halfpennyDirectory);\n+\n+          // init sub-api services\n+          this.auth = new Auth(subAPIConf);\n+          this.consortia = new ConsortiaService(subAPIConf);\n+          this.computations = new ComputationService(subAPIConf);\n+          this.projects = new ProjectServices(subAPIConf);\n+\n+          /**\n+          * Examine the shape of `credentials` to determine whether to log in","path":"src/index.js","position":139,"original_position":139,"commit_id":"a61f13663b2025b1156d10f828bfa5f17e47e297","original_commit_id":"342f53d2a232281eb239e779019a316b4e89c185","user":{"login":"swashcap","id":1858316,"avatar_url":"https://avatars.githubusercontent.com/u/1858316?v=3","gravatar_id":"","url":"https://api.github.com/users/swashcap","html_url":"https://github.com/swashcap","followers_url":"https://api.github.com/users/swashcap/followers","following_url":"https://api.github.com/users/swashcap/following{/other_user}","gists_url":"https://api.github.com/users/swashcap/gists{/gist_id}","starred_url":"https://api.github.com/users/swashcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swashcap/subscriptions","organizations_url":"https://api.github.com/users/swashcap/orgs","repos_url":"https://api.github.com/users/swashcap/repos","events_url":"https://api.github.com/users/swashcap/events{/privacy}","received_events_url":"https://api.github.com/users/swashcap/received_events","type":"User","site_admin":false},"body":"Potential usage change:\r\n\r\n1. Instantiate the class:\r\n  ```js\r\n  const coinstacClientInstance = new CoinstacClient({\r\n    db: 'http://localhost:5984',\r\n  });\r\n  ```\r\n\r\n  This does:\r\n\r\n  * Sets `dbRegistry`\r\n  * Sets `logger`\r\n\r\n2. Initialize to async-y setup:\r\n  ```js\r\n  coinstacClientInstance.initialize()\r\n    .then(() => myLogger.info('CoinstacClient ready!'))\r\n    .catch(myLogger.error.bind(myLogger));\r\n  ```\r\n\r\n  This does:\r\n\r\n  * Upserts `appDirectory`\r\n  * Sets `halfpenny` instance (async)\r\n  * Sets sub-api services on instance\r\n3. Log in/sign up:\r\n  ```js\r\n  coinstacClientInstance.login({\r\n    password: 'wat-pass',\r\n    username: 'wat-user',\r\n  })\r\n    .then(() => myLogger.info('Logged in!'))\r\n    .catch(myLogger.error.bind(myLogger));\r\n  ```\r\n\r\n  This does:\r\n\r\n  * Logs user in (duh)\r\n  * Adds Hawk credentials to PouchDB\r\n  * Initialize computation registry\r\n  * Initialize pool\r\n\r\nThoughts?","created_at":"2016-06-02T18:26:19Z","updated_at":"2016-06-02T18:26:19Z","html_url":"https://github.com/MRN-Code/coinstac-client-core/pull/58#discussion_r65592716","pull_request_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58","_links":{"self":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/comments/65592716"},"html":{"href":"https://github.com/MRN-Code/coinstac-client-core/pull/58#discussion_r65592716"},"pull_request":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58"}}},"pull_request":{"url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58","id":72229335,"html_url":"https://github.com/MRN-Code/coinstac-client-core/pull/58","diff_url":"https://github.com/MRN-Code/coinstac-client-core/pull/58.diff","patch_url":"https://github.com/MRN-Code/coinstac-client-core/pull/58.patch","issue_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/58","number":58,"state":"open","locked":false,"title":"Enhancement/refactor initialize","user":{"login":"swashcap","id":1858316,"avatar_url":"https://avatars.githubusercontent.com/u/1858316?v=3","gravatar_id":"","url":"https://api.github.com/users/swashcap","html_url":"https://github.com/swashcap","followers_url":"https://api.github.com/users/swashcap/followers","following_url":"https://api.github.com/users/swashcap/following{/other_user}","gists_url":"https://api.github.com/users/swashcap/gists{/gist_id}","starred_url":"https://api.github.com/users/swashcap/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swashcap/subscriptions","organizations_url":"https://api.github.com/users/swashcap/orgs","repos_url":"https://api.github.com/users/swashcap/repos","events_url":"https://api.github.com/users/swashcap/events{/privacy}","received_events_url":"https://api.github.com/users/swashcap/received_events","type":"User","site_admin":false},"body":"Asana task: https://app.asana.com/0/45796090191289/139350388636120\r\n\r\n* **Problem:**\r\n  * _coinstac-client-core explodes_ during Halfpenny instantiation due to a directory not existing\r\n  * instantiation lifecycle and login/signup process are confusing\r\n* **Solution:**\r\n  * Make major class instantiation async by moving it to `CoinstacClient#initialize` (see https://github.com/MRN-Code/coinstac-client-core/pull/58/commits/4632d48bb9fab548532a42127c91f845b5500040)\r\n  * Refactor tests (see aca95d8c53fe20973344ca2af920cea87d382899)\r\n* **Testing:**\r\n  1. Pull down latest\r\n  2. Run `npm test`\r\n  3. Make it great","created_at":"2016-06-01T18:28:35Z","updated_at":"2016-06-02T18:26:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5d7ffa589500c8e571434f97f00afcf1fd06d5f3","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58/commits","review_comments_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58/comments","review_comment_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/comments{/number}","comments_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/58/comments","statuses_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/statuses/a61f13663b2025b1156d10f828bfa5f17e47e297","head":{"label":"MRN-Code:enhancement/refactor-initialize","ref":"enhancement/refactor-initialize","sha":"a61f13663b2025b1156d10f828bfa5f17e47e297","user":{"login":"MRN-Code","id":5330818,"avatar_url":"https://avatars.githubusercontent.com/u/5330818?v=3","gravatar_id":"","url":"https://api.github.com/users/MRN-Code","html_url":"https://github.com/MRN-Code","followers_url":"https://api.github.com/users/MRN-Code/followers","following_url":"https://api.github.com/users/MRN-Code/following{/other_user}","gists_url":"https://api.github.com/users/MRN-Code/gists{/gist_id}","starred_url":"https://api.github.com/users/MRN-Code/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MRN-Code/subscriptions","organizations_url":"https://api.github.com/users/MRN-Code/orgs","repos_url":"https://api.github.com/users/MRN-Code/repos","events_url":"https://api.github.com/users/MRN-Code/events{/privacy}","received_events_url":"https://api.github.com/users/MRN-Code/received_events","type":"Organization","site_admin":false},"repo":{"id":49157861,"name":"coinstac-client-core","full_name":"MRN-Code/coinstac-client-core","owner":{"login":"MRN-Code","id":5330818,"avatar_url":"https://avatars.githubusercontent.com/u/5330818?v=3","gravatar_id":"","url":"https://api.github.com/users/MRN-Code","html_url":"https://github.com/MRN-Code","followers_url":"https://api.github.com/users/MRN-Code/followers","following_url":"https://api.github.com/users/MRN-Code/following{/other_user}","gists_url":"https://api.github.com/users/MRN-Code/gists{/gist_id}","starred_url":"https://api.github.com/users/MRN-Code/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MRN-Code/subscriptions","organizations_url":"https://api.github.com/users/MRN-Code/orgs","repos_url":"https://api.github.com/users/MRN-Code/repos","events_url":"https://api.github.com/users/MRN-Code/events{/privacy}","received_events_url":"https://api.github.com/users/MRN-Code/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/MRN-Code/coinstac-client-core","description":"coinstac core functionality api","fork":false,"url":"https://api.github.com/repos/MRN-Code/coinstac-client-core","forks_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/forks","keys_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/teams","hooks_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/hooks","issue_events_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/events{/number}","events_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/events","assignees_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/assignees{/user}","branches_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/branches{/branch}","tags_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/tags","blobs_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/statuses/{sha}","languages_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/languages","stargazers_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/stargazers","contributors_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/contributors","subscribers_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/subscribers","subscription_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/subscription","commits_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/contents/{+path}","compare_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/merges","archive_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/downloads","issues_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues{/number}","pulls_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls{/number}","milestones_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/milestones{/number}","notifications_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/labels{/name}","releases_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/releases{/id}","deployments_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/deployments","created_at":"2016-01-06T19:52:06Z","updated_at":"2016-01-19T16:59:50Z","pushed_at":"2016-06-02T18:07:08Z","git_url":"git://github.com/MRN-Code/coinstac-client-core.git","ssh_url":"git@github.com:MRN-Code/coinstac-client-core.git","clone_url":"https://github.com/MRN-Code/coinstac-client-core.git","svn_url":"https://github.com/MRN-Code/coinstac-client-core","homepage":null,"size":819,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":2,"forks":0,"open_issues":2,"watchers":0,"default_branch":"master"}},"base":{"label":"MRN-Code:master","ref":"master","sha":"de544be83024610b4c230e96111a9b34b690025e","user":{"login":"MRN-Code","id":5330818,"avatar_url":"https://avatars.githubusercontent.com/u/5330818?v=3","gravatar_id":"","url":"https://api.github.com/users/MRN-Code","html_url":"https://github.com/MRN-Code","followers_url":"https://api.github.com/users/MRN-Code/followers","following_url":"https://api.github.com/users/MRN-Code/following{/other_user}","gists_url":"https://api.github.com/users/MRN-Code/gists{/gist_id}","starred_url":"https://api.github.com/users/MRN-Code/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MRN-Code/subscriptions","organizations_url":"https://api.github.com/users/MRN-Code/orgs","repos_url":"https://api.github.com/users/MRN-Code/repos","events_url":"https://api.github.com/users/MRN-Code/events{/privacy}","received_events_url":"https://api.github.com/users/MRN-Code/received_events","type":"Organization","site_admin":false},"repo":{"id":49157861,"name":"coinstac-client-core","full_name":"MRN-Code/coinstac-client-core","owner":{"login":"MRN-Code","id":5330818,"avatar_url":"https://avatars.githubusercontent.com/u/5330818?v=3","gravatar_id":"","url":"https://api.github.com/users/MRN-Code","html_url":"https://github.com/MRN-Code","followers_url":"https://api.github.com/users/MRN-Code/followers","following_url":"https://api.github.com/users/MRN-Code/following{/other_user}","gists_url":"https://api.github.com/users/MRN-Code/gists{/gist_id}","starred_url":"https://api.github.com/users/MRN-Code/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MRN-Code/subscriptions","organizations_url":"https://api.github.com/users/MRN-Code/orgs","repos_url":"https://api.github.com/users/MRN-Code/repos","events_url":"https://api.github.com/users/MRN-Code/events{/privacy}","received_events_url":"https://api.github.com/users/MRN-Code/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/MRN-Code/coinstac-client-core","description":"coinstac core functionality api","fork":false,"url":"https://api.github.com/repos/MRN-Code/coinstac-client-core","forks_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/forks","keys_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/keys{/key_id}","collaborators_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/teams","hooks_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/hooks","issue_events_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/events{/number}","events_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/events","assignees_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/assignees{/user}","branches_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/branches{/branch}","tags_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/tags","blobs_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/refs{/sha}","trees_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/trees{/sha}","statuses_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/statuses/{sha}","languages_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/languages","stargazers_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/stargazers","contributors_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/contributors","subscribers_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/subscribers","subscription_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/subscription","commits_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/commits{/sha}","git_commits_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/git/commits{/sha}","comments_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/comments{/number}","issue_comment_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/comments{/number}","contents_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/contents/{+path}","compare_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/compare/{base}...{head}","merges_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/merges","archive_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/downloads","issues_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues{/number}","pulls_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls{/number}","milestones_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/milestones{/number}","notifications_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/labels{/name}","releases_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/releases{/id}","deployments_url":"https://api.github.com/repos/MRN-Code/coinstac-client-core/deployments","created_at":"2016-01-06T19:52:06Z","updated_at":"2016-01-19T16:59:50Z","pushed_at":"2016-06-02T18:07:08Z","git_url":"git://github.com/MRN-Code/coinstac-client-core.git","ssh_url":"git@github.com:MRN-Code/coinstac-client-core.git","clone_url":"https://github.com/MRN-Code/coinstac-client-core.git","svn_url":"https://github.com/MRN-Code/coinstac-client-core","homepage":null,"size":819,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":2,"forks":0,"open_issues":2,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58"},"html":{"href":"https://github.com/MRN-Code/coinstac-client-core/pull/58"},"issue":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/58"},"comments":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/issues/58/comments"},"review_comments":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58/comments"},"review_comment":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/pulls/58/commits"},"statuses":{"href":"https://api.github.com/repos/MRN-Code/coinstac-client-core/statuses/a61f13663b2025b1156d10f828bfa5f17e47e297"}}}}
{"actor":{"display_login":"swashcap"}}