Permalink
Browse files

initial

  • Loading branch information...
0 parents commit e4b1284b631561d7f355cfc9bc75cadd5cfda94d @dominictarr committed Sep 15, 2012
Showing with 221 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +4 −0 .travis.yml
  3. +22 −0 LICENSE
  4. +62 −0 README.md
  5. +43 −0 index.js
  6. +18 −0 package.json
  7. +42 −0 test/buffering.js
  8. +27 −0 test/index.js
@@ -0,0 +1,3 @@
+node_modules
+node_modules/*
+npm_debug.log
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+ - 0.6
+ - 0.8
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 'Dominic Tarr'
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software and
+associated documentation files (the "Software"), to
+deal in the Software without restriction, including
+without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom
+the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,62 @@
+# query-stream
+
+<img src=https://secure.travis-ci.org/'Dominic Tarr'/query-stream.png?branch=master>
+
+create autosuggest widgets with a async function.
+
+create a query stream:
+
+``` js
+var query = require('query-stream')
+var qs = query(function (query, cb) {
+ //make request to
+ make_query_to_wherever(query, cb)
+})
+
+```
+
+then, write queries to it:
+
+``` js
+qs.write('samestuth')
+
+//if you change your query it retries the search
+
+qs.write('some stuff')
+```
+
+output chunks will look like this:
+
+``` js
+//assuming get(q, cb) calls back a string
+"samestuff not found",
+"CLEAR", //this means new results
+"stuff1",
+"stuff2",
+etc..
+```
+`"CLEAR"` is a special message.
+it means that the following is a new response,
+and the display should clear previous elements.
+
+
+# UI
+
+Pipe a input field into this, and out to a list.
+NOTE, this stuff isn't implemented yet!
+But it will look something like this:
+``` js
+//input-stream creates a stream of DOM events.
+inputStream('#query', 'onchange', function (e) {
+ return e.value
+}).pipe(qs)
+//element stream adds elements to a given root Element.
+.pipe(elementStream('#results', function (e) {
+ if(e === 'CLEAR')
+ return this.root.removeAllChildren()
+ return '<li>'+e+'</li>'
+})
+
+## License
+
+MIT
@@ -0,0 +1,43 @@
+var through = require('through')
+
+module.exports = function (request, init) {
+ var self, requests = 0, ended = false, max = -1, stream = null
+
+ function cleanup() {
+ ended = true
+ }
+
+ return self = through (function (data) {
+ //each chunk calls the request.
+ var args = Array.isArray(data) ? data.concat(next) : [data, next]
+ var requestN = ++requests
+ request.apply(this, args)
+
+ function append (data) {
+ self.queue(data)
+ }
+
+ function next (err, data) {
+ if(ended) return
+ // forget old requests there is a newer one.
+ if(requests !== requestN) return
+ //this means the stuff previously emitted is not wanted any more
+ self.buffer.length = 0
+ if(requestN !== 1)
+ self.queue('CLEAR')
+
+ if(err) return cleanup(), self.emit('error', err)
+
+ if(Array.isArray(data))
+ data.forEach(append)
+ else if('function' == typeof data.pipe) {
+ if(stream) stream.removeListener('data', append)
+ stream = data.on('data', append)
+ if(stream.resume) stream.resume() //just in case.
+ }
+ else
+ append(data)
+ }
+ }, cleanup)
+}
+
@@ -0,0 +1,18 @@
+{
+ "name": "query-stream",
+ "destription": "a stream for autosuggest queries",
+ "version": "0.0.0",
+ "homepage": "https://github.com/dominictarr/query-stream",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/dominictarr/query-stream.git"
+ },
+ "dependencies": {
+ "through": "~1.1.0"
+ },
+ "scripts": {
+ "test": "set -e; for t in test/*.js; do node $t; done"
+ },
+ "author": "'Dominic Tarr' <dominic.tarr@gmail.com> (http://dominictarr.com)",
+ "license": "MIT"
+}
@@ -0,0 +1,42 @@
+var query = require('../')
+var assert = require('assert')
+
+var examples = {
+ A : [1, 2, 3],
+ AA: [1, 2, 3, 4, 5],
+ B : [6, 7, 8]
+}
+
+var expected = [ 1, 2, 3, 'CLEAR', 6, 7, 8, 'CLEAR', 1, 2, 3, 4, 5]
+var actual = []
+
+var qs = query(function (key, cb) {
+ cb(null, examples[key] || [])
+})
+
+var actual = []
+qs.on('data', actual.push.bind(actual))
+qs.pause()
+qs.on('data', function () {
+ qs.pause()
+})
+function read () {
+ var l = actual.length
+ qs.resume()
+ //hopefully, something has been added
+ return actual[l] //else, this will be undefined
+}
+
+qs.write('A')
+assert.deepEqual(actual, [])
+read(); read();
+assert.deepEqual(actual, [1, 2])
+read();
+assert.deepEqual(actual, [1, 2, 3])
+qs.write('B')
+read(); read();
+assert.deepEqual(actual, [1, 2, 3, 'CLEAR', 6])
+qs.write('AA')
+while(read())
+ console.log(actual)
+console.log('passed')
@@ -0,0 +1,27 @@
+var query = require('../')
+var assert = require('assert')
+
+var examples = {
+ A : [1, 2, 3],
+ AA: [1, 2, 3, 4, 5],
+ B : [6, 7, 8]
+}
+
+var expected = [ 1, 2, 3, 'CLEAR', 6, 7, 8, 'CLEAR', 1, 2, 3, 4, 5]
+
+var qs = query(function (key, cb) {
+ cb(null, examples[key] || [])
+})
+var actual = []
+qs.on('data', actual.push.bind(actual))
+
+qs.write('A')
+qs.write('B')
+qs.write('AA')
+qs.end()
+
+console.log(actual)
+assert.deepEqual(actual, expected)
+console.log('passed')
+
+

0 comments on commit e4b1284

Please sign in to comment.