Simple email application for Android. Original source code: https://framagit.org/dystopia-project/simple-email
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
5.6 KiB

  1. # JSONStream
  2. streaming JSON.parse and stringify
  3. ![](https://secure.travis-ci.org/dominictarr/JSONStream.png?branch=master)
  4. ## install
  5. ```npm install JSONStream```
  6. ## example
  7. ``` js
  8. var request = require('request')
  9. , JSONStream = require('JSONStream')
  10. , es = require('event-stream')
  11. request({url: 'http://isaacs.couchone.com/registry/_all_docs'})
  12. .pipe(JSONStream.parse('rows.*'))
  13. .pipe(es.mapSync(function (data) {
  14. console.error(data)
  15. return data
  16. }))
  17. ```
  18. ## JSONStream.parse(path)
  19. parse stream of values that match a path
  20. ``` js
  21. JSONStream.parse('rows.*.doc')
  22. ```
  23. The `..` operator is the recursive descent operator from [JSONPath](http://goessner.net/articles/JsonPath/), which will match a child at any depth (see examples below).
  24. If your keys have keys that include `.` or `*` etc, use an array instead.
  25. `['row', true, /^doc/]`.
  26. If you use an array, `RegExp`s, booleans, and/or functions. The `..` operator is also available in array representation, using `{recurse: true}`.
  27. any object that matches the path will be emitted as 'data' (and `pipe`d down stream)
  28. If `path` is empty or null, no 'data' events are emitted.
  29. If you want to have keys emitted, you can prefix your `*` operator with `$`: `obj.$*` - in this case the data passed to the stream is an object with a `key` holding the key and a `value` property holding the data.
  30. ### Examples
  31. query a couchdb view:
  32. ``` bash
  33. curl -sS localhost:5984/tests/_all_docs&include_docs=true
  34. ```
  35. you will get something like this:
  36. ``` js
  37. {"total_rows":129,"offset":0,"rows":[
  38. { "id":"change1_0.6995461115147918"
  39. , "key":"change1_0.6995461115147918"
  40. , "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
  41. , "doc":{
  42. "_id": "change1_0.6995461115147918"
  43. , "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
  44. },
  45. { "id":"change2_0.6995461115147918"
  46. , "key":"change2_0.6995461115147918"
  47. , "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
  48. , "doc":{
  49. "_id":"change2_0.6995461115147918"
  50. , "_rev":"1-13677d36b98c0c075145bb8975105153"
  51. , "hello":2
  52. }
  53. },
  54. ]}
  55. ```
  56. we are probably most interested in the `rows.*.doc`
  57. create a `Stream` that parses the documents from the feed like this:
  58. ``` js
  59. var stream = JSONStream.parse(['rows', true, 'doc']) //rows, ANYTHING, doc
  60. stream.on('data', function(data) {
  61. console.log('received:', data);
  62. });
  63. //emits anything from _before_ the first match
  64. stream.on('header', function (data) {
  65. console.log('header:', data) // => {"total_rows":129,"offset":0}
  66. })
  67. ```
  68. awesome!
  69. In case you wanted the contents the doc emitted:
  70. ``` js
  71. var stream = JSONStream.parse(['rows', true, 'doc', {emitKey: true}]) //rows, ANYTHING, doc, items in docs with keys
  72. stream.on('data', function(data) {
  73. console.log('key:', data.key);
  74. console.log('value:', data.value);
  75. });
  76. ```
  77. You can also emit the path:
  78. ``` js
  79. var stream = JSONStream.parse(['rows', true, 'doc', {emitPath: true}]) //rows, ANYTHING, doc, items in docs with keys
  80. stream.on('data', function(data) {
  81. console.log('path:', data.path);
  82. console.log('value:', data.value);
  83. });
  84. ```
  85. ### recursive patterns (..)
  86. `JSONStream.parse('docs..value')`
  87. (or `JSONStream.parse(['docs', {recurse: true}, 'value'])` using an array)
  88. will emit every `value` object that is a child, grand-child, etc. of the
  89. `docs` object. In this example, it will match exactly 5 times at various depth
  90. levels, emitting 0, 1, 2, 3 and 4 as results.
  91. ```js
  92. {
  93. "total": 5,
  94. "docs": [
  95. {
  96. "key": {
  97. "value": 0,
  98. "some": "property"
  99. }
  100. },
  101. {"value": 1},
  102. {"value": 2},
  103. {"blbl": [{}, {"a":0, "b":1, "value":3}, 10]},
  104. {"value": 4}
  105. ]
  106. }
  107. ```
  108. ## JSONStream.parse(pattern, map)
  109. provide a function that can be used to map or filter
  110. the json output. `map` is passed the value at that node of the pattern,
  111. if `map` return non-nullish (anything but `null` or `undefined`)
  112. that value will be emitted in the stream. If it returns a nullish value,
  113. nothing will be emitted.
  114. `JSONStream` also emits `'header'` and `'footer'` events,
  115. the `'header'` event contains anything in the output that was before
  116. the first match, and the `'footer'`, is anything after the last match.
  117. ## JSONStream.stringify(open, sep, close)
  118. Create a writable stream.
  119. you may pass in custom `open`, `close`, and `seperator` strings.
  120. But, by default, `JSONStream.stringify()` will create an array,
  121. (with default options `open='[\n', sep='\n,\n', close='\n]\n'`)
  122. If you call `JSONStream.stringify(false)`
  123. the elements will only be seperated by a newline.
  124. If you only write one item this will be valid JSON.
  125. If you write many items,
  126. you can use a `RegExp` to split it into valid chunks.
  127. ## JSONStream.stringifyObject(open, sep, close)
  128. Very much like `JSONStream.stringify`,
  129. but creates a writable stream for objects instead of arrays.
  130. Accordingly, `open='{\n', sep='\n,\n', close='\n}\n'`.
  131. When you `.write()` to the stream you must supply an array with `[ key, data ]`
  132. as the first argument.
  133. ## unix tool
  134. query npm to see all the modules that browserify has ever depended on.
  135. ``` bash
  136. curl https://registry.npmjs.org/browserify | JSONStream 'versions.*.dependencies'
  137. ```
  138. ## numbers
  139. numbers will be emitted as numbers.
  140. huge numbers that cannot be represented in memory as javascript numbers will be emitted as strings.
  141. cf https://github.com/creationix/jsonparse/commit/044b268f01c4b8f97fb936fc85d3bcfba179e5bb for details.
  142. ## Acknowlegements
  143. this module depends on https://github.com/creationix/jsonparse
  144. by Tim Caswell
  145. and also thanks to Florent Jaby for teaching me about parsing with:
  146. https://github.com/Floby/node-json-streams
  147. ## license
  148. Dual-licensed under the MIT License or the Apache License, version 2.0