{"action":"created","issue":{"url":"https://api.github.com/repos/caolan/highland/issues/269","labels_url":"https://api.github.com/repos/caolan/highland/issues/269/labels{/name}","comments_url":"https://api.github.com/repos/caolan/highland/issues/269/comments","events_url":"https://api.github.com/repos/caolan/highland/issues/269/events","html_url":"https://github.com/caolan/highland/issues/269","id":67816784,"number":269,"title":"Custom operators","user":{"login":"ivan-kleshnin","id":2128182,"avatar_url":"https://avatars.githubusercontent.com/u/2128182?v=3","gravatar_id":"","url":"https://api.github.com/users/ivan-kleshnin","html_url":"https://github.com/ivan-kleshnin","followers_url":"https://api.github.com/users/ivan-kleshnin/followers","following_url":"https://api.github.com/users/ivan-kleshnin/following{/other_user}","gists_url":"https://api.github.com/users/ivan-kleshnin/gists{/gist_id}","starred_url":"https://api.github.com/users/ivan-kleshnin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ivan-kleshnin/subscriptions","organizations_url":"https://api.github.com/users/ivan-kleshnin/orgs","repos_url":"https://api.github.com/users/ivan-kleshnin/repos","events_url":"https://api.github.com/users/ivan-kleshnin/events{/privacy}","received_events_url":"https://api.github.com/users/ivan-kleshnin/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-04-11T18:31:31Z","updated_at":"2015-04-12T08:47:28Z","closed_at":null,"body":"RxJS [allows](https://github.com/ReactiveX/RxJava/wiki/Implementing-Your-Own-Operators) to implement your own custom operators. \r\n\r\nWhat about Highland? I don't see any documentation on this. Is it conventional? If not, why?\r\nWorking with complex data like Vinyl objects in Gulp streams it would be great to have such option.\r\n\r\nExample case, a lot of boilerplate and repeating code:\r\n\r\n```javascript\r\n// === Gulp is globbing over JSON files ===\r\n...\r\n// Update some field in JSON \r\n.map(file => {\r\n  let json = file.contents.toString();\r\n  let js = JSON.parse(json);\r\n  // update obj here... \r\n  let str = JSON.stringify(obj, null, 2);\r\n  file.contents = new Buffer(str);\r\n  return file;\r\n})\r\n...\r\n// Filter over another field in JSON\r\n.filter(file => {\r\n  let json = file.contents.toString(); // this mess again ^_^\r\n  let js = JSON.parse(json);\r\n  // evaluate cond here...\r\n  return cond;\r\n})\r\n```\r\n\r\nData is too complex above and operators are weak. It probably may be like this:\r\n\r\n```javascript\r\n// === Gulp is globbing over JSON files ===\r\n...\r\n.pipe(Highland())\r\n.asObject()\r\n// Update some field in JSON \r\n.map(obj => {\r\n  // update obj here...\r\n  return obj;\r\n})\r\n...\r\n// Filter over another field in JSON \r\n.filter(obj => {\r\n  // evaluate cond here...\r\n  return cond;\r\n})\r\n.asVinyl()\r\n```\r\nSo I basically add `asObject` and `asVinyl` operators which convert Vinyl object with JSON content into JS object and vice versa and use existing operators like `map` and `filter` in their full power.\r\n"},"comment":{"url":"https://api.github.com/repos/caolan/highland/issues/comments/92020591","html_url":"https://github.com/caolan/highland/issues/269#issuecomment-92020591","issue_url":"https://api.github.com/repos/caolan/highland/issues/269","id":92020591,"user":{"login":"vqvu","id":6435429,"avatar_url":"https://avatars.githubusercontent.com/u/6435429?v=3","gravatar_id":"","url":"https://api.github.com/users/vqvu","html_url":"https://github.com/vqvu","followers_url":"https://api.github.com/users/vqvu/followers","following_url":"https://api.github.com/users/vqvu/following{/other_user}","gists_url":"https://api.github.com/users/vqvu/gists{/gist_id}","starred_url":"https://api.github.com/users/vqvu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vqvu/subscriptions","organizations_url":"https://api.github.com/users/vqvu/orgs","repos_url":"https://api.github.com/users/vqvu/repos","events_url":"https://api.github.com/users/vqvu/events{/privacy}","received_events_url":"https://api.github.com/users/vqvu/received_events","type":"User","site_admin":false},"created_at":"2015-04-12T08:47:28Z","updated_at":"2015-04-12T08:47:28Z","body":"Oh, what I meant was that a function used with `through` is still an operator, same as something in the prototype.\r\n\r\nThere's some discussion on why we don't expose the prototype in #148. It mostly has to do with having multiple versions of highland at once (when using NPM).\r\n\r\nIn any case, I do agree that application code can do things that library code doesn't, since you control application code directly (still don't like patching the prototype but I don't want to get into a coding style discussion here). So for your use case, you should be able to go ahead and do\r\n\r\n```javascript\r\nvar prototype = Object.getPrototypeOf(_());\r\nprototype.myOperator = function (...) {\r\n...\r\n}\r\n```\r\n\r\nThis will work with the current version of library (and probably with any future 2.x version)."}}