├── .gitignore ├── LICENSE ├── README.md ├── lib ├── cycle-gun.js ├── cycle-gun.js.map ├── example │ ├── browser │ │ ├── app.js │ │ ├── app.js.map │ │ ├── index.js │ │ └── index.js.map │ └── server │ │ ├── server.js │ │ ├── server.js.map │ │ ├── server2.js │ │ └── server2.js.map ├── index.js └── index.js.map ├── package.json ├── src ├── cycle-gun.ts ├── example │ ├── browser │ │ ├── app.ts │ │ └── index.ts │ └── server │ │ └── server.ts └── index.ts ├── test └── browser │ ├── bundle.js │ ├── index.html │ └── index.js └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | data.json 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 JuniperChicago 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cycle-gun 2 | 3 | A [cycle.js](https://github.com/cyclejs/cyclejs) driver that wraps a [gun.js](https://github.com/amark/gun) store instance. 4 | 5 | Note: This driver currently depends on the [xstream](https://github.com/staltz/xstream) library. 6 | 7 | ## Overview 8 | 9 | - Gun.js store is created inside a cycle driver pointing to an optional peer. 10 | - The source from the Gun driver is an object with 3 methods: `select`, `shallow`, and `each` 11 | - The sink stream emits "command" functions which take the gun.js instance and apply some changes to it using the normal Gun.js API 12 | 13 | ## Installation 14 | 15 | ``` 16 | npm install --save cycle-gun 17 | ``` 18 | 19 | ## GunSource 20 | 21 | The source from the Gun.js driver is an object with some methods that return streams. 22 | 23 | Use `gunSource.select('books')` to go to the `books` path in the graph. It returns a new `gunSource` object. 24 | 25 | Use `gunSource.shallow()` to get a Stream of the data under the current path. This is equivalent to Gun's `.on(callback)` API. 26 | 27 | ```typescript 28 | const presidentAge$ = sources.gun 29 | .select('president').shallow() 30 | .map(x => { 31 | // x is the data for `president` 32 | return x.age; 33 | }) 34 | ``` 35 | 36 | Use `gunSource.each()` to get a Stream of the data under each child property of the current path. This is equivalent to Gun's `.map().on(callback)` API. The return stream will emit an object `{key, value}`. This method is useful when the current path points to a set of many resources. 37 | 38 | ```typescript 39 | const book$ = sources.gun 40 | .select('books').each() 41 | .map(x => { 42 | // x is an object {key, value} representing ONE book 43 | return x.value; 44 | }) 45 | ``` 46 | 47 | ## Sinking commands to gun driver 48 | 49 | In this version, we can send commands to the gun driver by sending a function through the sink stream with payload references. 50 | 51 | ```typescript 52 | const outgoingGunTodo$ = event$ 53 | .map((event) => function command(gunInstance) { 54 | return gunInstance 55 | .get('example/todo/data') 56 | .path(uuid()) 57 | .put(event.payload); 58 | }) 59 | ``` 60 | 61 | ## A more detailed example 62 | 63 | Note: virtual-dom details omitted and transducers are verbose here 64 | 65 | ```typescript 66 | import xs from 'xstream'; 67 | import { run } from '@cycle/run'; 68 | //import { makeDOMDriver } from '@cycle/dom'; 69 | import { makeGunDriver } from 'cycle-gun'; 70 | import * as uuid from 'uuid-random'; 71 | import * as equal from 'deep-equal'; 72 | import dropRepeats from 'xstream/extra/dropRepeats'; 73 | 74 | function main(sources) { 75 | 76 | const {DOM, gun} = sources; 77 | 78 | const gunTodoEvent$ = sources.gun 79 | .select('example').select('todo').select('data') 80 | .shallow(); 81 | 82 | // map gun driver events into messages, or return as state 83 | const gunState$ = gunTodoEvent$ 84 | .compose(dropRepeats(equal)) 85 | .map((event) => { 86 | return { typeKey: 'getTodo', payload: event }; 87 | }) 88 | 89 | // sink gunState$ into a flux-type store or into vdom 90 | 91 | 92 | 93 | 94 | // sink map filtered stream of payloads into function and emit function 95 | const outgoingGunEvents$ = event$ 96 | .filter(event => event.typeKey === 'putTodo') 97 | .map((event) => { 98 | return (gunInstance) => { 99 | return gunInstance.get('example/todo/data').path(uuid()).put(event.payload); 100 | } 101 | }) 102 | 103 | return { 104 | // DOM: vtree$ 105 | gun: outgoingGunEvents$ 106 | }; 107 | } 108 | 109 | const drivers = { 110 | // DOM: makeDOMDriver('#app'), 111 | gun: makeGunDriver({root: 'root', peers: ['http://localhost:3500']}) 112 | }; 113 | 114 | run(main, drivers); 115 | 116 | ``` 117 | 118 | 119 | ## Other cyclejs reources 120 | 121 | Please see [awesome-cyclejs](https://github.com/cyclejs-community/awesome-cyclejs) - A curated list of awesome Cycle.js resources. 122 | 123 | 124 | [MIT License](./LICENSE) 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /lib/cycle-gun.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var xstream_1 = require("xstream"); 4 | var Gun = require("gun"); 5 | var GunSource = (function () { 6 | function GunSource(gun, path) { 7 | this.gun = gun; 8 | this.path = path; 9 | } 10 | GunSource.prototype.select = function (key) { 11 | return new GunSource(this.gun, this.path.concat(key)); 12 | }; 13 | GunSource.prototype.shallow = function () { 14 | var self = this; 15 | return xstream_1.default.create({ 16 | start: function (listener) { 17 | (_a = self.gun).get.apply(_a, self.path).on(function (x) { 18 | listener.next(x); 19 | }); 20 | var _a; 21 | }, 22 | stop: function () { 23 | }, 24 | }); 25 | }; 26 | GunSource.prototype.each = function () { 27 | var self = this; 28 | return xstream_1.default.create({ 29 | start: function (listener) { 30 | (_a = self.gun).get.apply(_a, self.path).map().on(function (value, key) { 31 | listener.next({ key: key, value: value }); 32 | }); 33 | var _a; 34 | }, 35 | stop: function () { 36 | }, 37 | }); 38 | }; 39 | return GunSource; 40 | }()); 41 | exports.GunSource = GunSource; 42 | function makeGunDriver(opts) { 43 | // console.log('gun opts.root--------------------------------------') 44 | // console.log(opts) 45 | // console.log('-----------------------------------------------------') 46 | var gun = Gun(opts); 47 | return function gunDriver(sink) { 48 | sink.addListener({ 49 | next: function (command) { return command(gun); }, 50 | }); 51 | return new GunSource(gun, []); 52 | }; 53 | } 54 | exports.makeGunDriver = makeGunDriver; 55 | //# sourceMappingURL=cycle-gun.js.map -------------------------------------------------------------------------------- /lib/cycle-gun.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"cycle-gun.js","sourceRoot":"","sources":["../src/cycle-gun.ts"],"names":[],"mappings":";;AAAA,mCAA4C;AAC5C,yBAA0B;AAE1B;IAIE,mBAAY,GAAQ,EAAE,IAAmB;QACvC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAEM,0BAAM,GAAb,UAAc,GAAW;QACvB,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IACvD,CAAC;IAEM,2BAAO,GAAd;QACE,IAAM,IAAI,GAAG,IAAI,CAAA;QAEjB,MAAM,CAAC,iBAAE,CAAC,MAAM,CAAC;YACf,KAAK,YAAC,QAAuB;gBAC3B,CAAA,KAAA,IAAI,CAAC,GAAG,CAAA,CAAC,GAAG,WAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,UAAC,CAAM;oBACnC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBAClB,CAAC,CAAC,CAAA;;YACJ,CAAC;YACD,IAAI;YACJ,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;IAEM,wBAAI,GAAX;QACE,IAAM,IAAI,GAAG,IAAI,CAAA;QACjB,MAAM,CAAC,iBAAE,CAAC,MAAM,CAAC;YACf,KAAK,YAAC,QAA6C;gBACjD,CAAA,KAAA,IAAI,CAAC,GAAG,CAAA,CAAC,GAAG,WAAI,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,UAAC,KAAU,EAAE,GAAW;oBAC1D,QAAQ,CAAC,IAAI,CAAC,EAAC,GAAG,KAAA,EAAE,KAAK,OAAA,EAAC,CAAC,CAAA;gBAC7B,CAAC,CAAC,CAAA;;YACJ,CAAC;YACD,IAAI;YACJ,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;IACH,gBAAC;AAAD,CAAC,AAvCD,IAuCC;AAvCY,8BAAS;AA2CtB,uBAA8B,IAAS;IACrC,qEAAqE;IACrE,oBAAoB;IACpB,uEAAuE;IAEvE,IAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAA;IAErB,MAAM,CAAC,mBAAmB,IAAsB;QAC9C,IAAI,CAAC,WAAW,CAAC;YACf,IAAI,EAAE,UAAC,OAAgB,IAAK,OAAA,OAAO,CAAC,GAAG,CAAC,EAAZ,CAAY;SACzC,CAAC,CAAA;QAEF,MAAM,CAAC,IAAI,SAAS,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC/B,CAAC,CAAA;AACH,CAAC;AAdD,sCAcC"} -------------------------------------------------------------------------------- /lib/example/browser/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var xstream_1 = require("xstream"); 4 | var sampleCombine_1 = require("xstream/extra/sampleCombine"); 5 | //import * as uuid from '../../../node_modules/uuid-random/uuid-random.min.js'; 6 | var uuid = require("uuid-random"); 7 | var dom_1 = require("@cycle/dom"); 8 | /** 9 | * Transforms gun store object into object containing headers and rows 10 | * 11 | * @param {any} inStream 12 | * @returns 13 | */ 14 | function transformTodoStream(inStream) { 15 | return inStream.map(function (state) { 16 | var rows = []; 17 | var headings = []; 18 | var count = 1; 19 | for (var key in state) { 20 | var row = state[key]; 21 | if (!state[key] || typeof row === 'object') 22 | continue; 23 | var c = count++; 24 | // might want to convert to json here... 25 | rows.push({ key: key, val: row }); 26 | } 27 | if (rows.length > 0) { 28 | headings = Object.keys(rows[0]); 29 | headings.push('X'); 30 | } 31 | return { 32 | headings: headings, 33 | rows: rows 34 | }; 35 | }); 36 | } 37 | function theadElems(tableData) { 38 | var headings = tableData.headings; 39 | var thElems = headings 40 | .filter(function (heading) { return heading !== 'key'; }) // skippings the key 41 | .map(function (heading) { 42 | if (heading === 'X') { 43 | return dom_1.th('.th-delete', 'X'); 44 | } 45 | else { 46 | return dom_1.th('', heading); 47 | } 48 | }); 49 | return dom_1.tr('', thElems); 50 | } 51 | /** 52 | * build table body elements 53 | * 54 | * @param {any} tableData 55 | * @returns 56 | */ 57 | function tbodyElems(tableData) { 58 | var headings = tableData.headings, rows = tableData.rows; 59 | return rows.map(function (row) { 60 | var tdElems = headings 61 | .filter(function (heading) { return heading !== 'key'; }) // skipping the key 62 | .map(function (heading) { 63 | if (heading === 'X') { 64 | //console.log(row.key) 65 | return dom_1.td('.delete', [dom_1.button({ attrs: { class: 'button-remove', 'data-key': row.key } }, 'X')]); 66 | } 67 | else { 68 | return dom_1.td('', row[heading]); 69 | } 70 | }); 71 | return dom_1.tr('', tdElems); 72 | }); 73 | } 74 | function app(sources) { 75 | function intent(DOM) { 76 | // clear 77 | var clearButtonClick$ = DOM.select('#clear').events('click'); 78 | // remove task 79 | var removeButtonClick$ = DOM.select('.button-remove').events('click'); 80 | // save task 81 | var saveButtonClick$ = DOM.select('#save-task').events('click'); 82 | // return - save task 83 | var keydownEvent$ = DOM.select('#text-newtask').events('keypress') 84 | .filter(function (event) { return event.keyCode === 13; }) 85 | .map(function (event) { 86 | event = event || window.event; // get window.event if e argument missing (in IE) 87 | event.preventDefault(); 88 | return {}; 89 | }); 90 | // input text value 91 | var textEvent$ = DOM.select('#text-newtask').events('input') 92 | .map(function (ev) { return ev.target.value; }) 93 | .startWith('') 94 | .map(function (event) { return ({ typeKey: 'text-content', payload: event }); }); 95 | // merge task save events 96 | var saveClickOrEnter$ = xstream_1.default.merge(saveButtonClick$, keydownEvent$); 97 | // transform remove task message and payload 98 | var outgunRemoveTask$ = removeButtonClick$ 99 | .map(function (event) { 100 | var key = event.target.getAttribute('data-key'); 101 | return { typeKey: 'out-gun', payload: { key: key, value: null } }; 102 | }); 103 | // transform add task message and payload 104 | // TODO: check for duplicates on text event 105 | var outgunAddTask$ = saveClickOrEnter$ 106 | .compose(sampleCombine_1.default(textEvent$)) 107 | .map(function (_a) { 108 | var click = _a[0], event = _a[1]; 109 | return ({ typeKey: 'out-gun', payload: { key: uuid(), value: event.payload } }); 110 | }); 111 | // transform text clearing events into messages 112 | var textClearEvents$ = xstream_1.default.merge(clearButtonClick$, saveButtonClick$, keydownEvent$) 113 | .map(function (event) { return ({ typeKey: 'text-clear', payload: null }); }); 114 | return { 115 | textEvent$: textEvent$, 116 | textClearEvents$: textClearEvents$, 117 | outgun$: xstream_1.default.merge(outgunAddTask$, outgunRemoveTask$) 118 | }; 119 | } 120 | // utilizes a reducer type store 121 | // reducers are selected using streams and filters 122 | function model(event$) { 123 | var clearTransformer$ = event$.filter(function (event) { return event.typeKey === 'text-clear'; }) 124 | .map(function (event) { 125 | return function (acc) { 126 | acc = ''; 127 | return acc; 128 | }; 129 | }); 130 | var textTransformer$ = event$.filter(function (event) { return event.typeKey === 'text-content'; }) 131 | .map(function (event) { 132 | return function (acc) { 133 | acc = event.payload; 134 | return acc; 135 | }; 136 | }); 137 | var transformSelector$ = xstream_1.default.merge(clearTransformer$, textTransformer$); 138 | // general transformer function 139 | var transformer = function (acc, trnsFn) { return trnsFn(acc); }; 140 | return transformSelector$.fold(transformer, ''); 141 | } 142 | function vtree(gunStream, textStream) { 143 | return xstream_1.default.combine(gunStream, textStream).map(function (_a) { 144 | //////////////////////////////// 145 | var gun = _a[0], text = _a[1]; 146 | return dom_1.div('pure-g', [ 147 | dom_1.div('', [ 148 | dom_1.main('.content', [ 149 | dom_1.section('.margin-top', [ 150 | dom_1.h2("Cycle-Gun Task List Example") 151 | ]), 152 | dom_1.section('', [ 153 | dom_1.form('.pure-form.pure-form-stacked', [ 154 | dom_1.fieldset('', [ 155 | dom_1.label({ attrs: { for: 'text-newtask' } }, 'Add Task'), 156 | dom_1.input({ 157 | attrs: { 158 | class: '', 159 | type: 'text', 160 | id: 'text-newtask', 161 | autocomplete: 'off' 162 | }, 163 | hook: { 164 | update: function (o, n) { return n.elm.value = text; } 165 | } 166 | }), 167 | ]) 168 | ]), 169 | dom_1.button('#save-task.pure-button.pure-button-primary.button-margin-right', 'save'), 170 | dom_1.button('#clear.pure-button.pure-button-primary', 'clear') 171 | ]), 172 | dom_1.section('', [ 173 | dom_1.div('', [ 174 | dom_1.table('.pure-table.example-table', [ 175 | dom_1.thead('', [theadElems(gun)]), 176 | dom_1.tbody(tbodyElems(gun)) 177 | ]) 178 | ]) 179 | ]) 180 | ]) 181 | ]) 182 | ]); 183 | ////////////////////////////// 184 | }); 185 | } 186 | var DOM = sources.DOM, gun = sources.gun; 187 | // Get streams from cycle-gun driver 188 | /////////////////////////////////////////////////////////////////////////// 189 | console.log('sources.gun', gun); 190 | var gunTodoEvent$ = gun 191 | .select('example') 192 | .select('todo') 193 | .select('data') 194 | .shallow(); 195 | console.log('gunTodoEvent$', gunTodoEvent$); 196 | // We are removing nulls, keys that are meta, etc... 197 | var gunTable$ = transformTodoStream(gunTodoEvent$); 198 | // intent() returns and object of streams 199 | var events = intent(DOM); 200 | var blendedTextEvents$ = xstream_1.default.merge(events.textEvent$, events.textClearEvents$); 201 | var outgoingGunTodo$ = events.outgun$ 202 | .filter(function (event) { return event.typeKey === 'out-gun'; }) 203 | .map(function (event) { 204 | var _a = event.payload, key = _a.key, value = _a.value; 205 | // return function that directly interacts with the gun instance 206 | return function (gunInstance) { 207 | // gun.js api here 208 | return gunInstance.get('example/todo/data').get(key).put(value); 209 | }; 210 | }); 211 | var textState$ = model(blendedTextEvents$); 212 | var vtree$ = vtree(gunTable$, textState$); 213 | var sinks = { 214 | gun: outgoingGunTodo$, 215 | DOM: vtree$ 216 | }; 217 | return sinks; 218 | } 219 | exports.default = app; 220 | //# sourceMappingURL=app.js.map -------------------------------------------------------------------------------- /lib/example/browser/app.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../src/example/browser/app.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /lib/example/browser/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var xstream_1 = require("xstream"); 4 | var run_1 = require("@cycle/run"); 5 | var dom_1 = require("@cycle/dom"); 6 | var index_js_1 = require("../../index.js"); 7 | var app_1 = require("./app"); 8 | // Watch here 9 | /** 10 | * main function 11 | * 12 | * @param {any} sources 13 | * @returns 14 | */ 15 | function main(sources) { 16 | var DOM = sources.DOM; 17 | var appPage = app_1.default(sources); 18 | var sinks = { 19 | DOM: appPage.DOM, 20 | gun: xstream_1.default.merge(appPage.gun), 21 | }; 22 | return sinks; 23 | } 24 | var drivers = { 25 | DOM: dom_1.makeDOMDriver('#app'), 26 | gun: index_js_1.makeGunDriver('http://localhost:3800') 27 | }; 28 | run_1.run(main, drivers); 29 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /lib/example/browser/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/example/browser/index.ts"],"names":[],"mappings":";;AAAA,mCAAyB;AACzB,kCAAiC;AACjC,kCAAgD;AAChD,2CAA+C;AAE/C,6BAAwB;AAExB,aAAa;AAEb;;;;;GAKG;AACH,cAAc,OAAO;IAEV,IAAA,iBAAG,CAAY;IACtB,IAAM,OAAO,GAAG,aAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAM,KAAK,GAAG;QACV,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG,EAAE,iBAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;KAC7B,CAAA;IACD,MAAM,CAAC,KAAK,CAAC;AACjB,CAAC;AAED,IAAM,OAAO,GAAG;IACZ,GAAG,EAAE,mBAAa,CAAC,MAAM,CAAC;IAC1B,GAAG,EAAE,wBAAa,CAAC,uBAAuB,CAAC;CAC9C,CAAA;AAED,SAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC"} -------------------------------------------------------------------------------- /lib/example/server/server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Test & Development Server 4 | * 5 | * 6 | */ 7 | Object.defineProperty(exports, "__esModule", { value: true }); 8 | var Gun = require("gun"); 9 | var http = require("http"); 10 | var port = 3800; 11 | var ip = '127.0.0.1'; 12 | var gun = Gun({ 13 | file: './data.json', 14 | s3: { 15 | key: '', 16 | secret: '', 17 | bucket: '' // The bucket you want to save into 18 | } 19 | }); 20 | var server = http.createServer(function (req, res) { 21 | if (gun.wsp.server(req, res)) { 22 | console.log(req.url); 23 | console.log(res.statusCode); 24 | return; // filters gun requests! 25 | } 26 | }); 27 | gun.wsp(server); 28 | server.listen(port, ip); 29 | console.log('Server started on port', port, 'with /gun'); 30 | //# sourceMappingURL=server.js.map -------------------------------------------------------------------------------- /lib/example/server/server.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/example/server/server.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAEH,yBAA2B;AAC3B,2BAA8B;AAE9B,IAAM,IAAI,GAAG,IAAI,CAAC;AAClB,IAAM,EAAE,GAAG,WAAW,CAAC;AAEvB,IAAM,GAAG,GAAG,GAAG,CAAC;IACd,IAAI,EAAE,aAAa;IACnB,EAAE,EAAE;QACF,GAAG,EAAE,EAAE;QACP,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,EAAE,CAAC,mCAAmC;KAC/C;CACF,CAAC,CAAC;AAEH,IAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,GAAG,EAAE,GAAG;IAEjD,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE5B,MAAM,CAAC,CAAC,wBAAwB;IAClC,CAAC;AACH,CAAC,CAAC,CAAC;AAGH,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAChB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAExB,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC"} -------------------------------------------------------------------------------- /lib/example/server/server2.js: -------------------------------------------------------------------------------- 1 | var port = process.env.OPENSHIFT_NODEJS_PORT || process.env.VCAP_APP_PORT || process.env.PORT || process.argv[2] || 3000; 2 | var host = process.env.OPENSHIFT_NODEJS_HOST || process.env.VCAP_APP_HOST || process.env.HOST || 'localhost'; 3 | var express = require('express'); 4 | var proxy = require('express-http-proxy'); 5 | var http = require('http'); 6 | var app = express(); 7 | var server = http.createServer(app); 8 | var Gun = require('gun'); 9 | var gun = Gun({ 10 | file: 'data.json', 11 | web: server 12 | }); 13 | app.use(Gun.serve); 14 | app.use(proxy(host + ':4200')); 15 | server.listen(port); 16 | console.log('Server started on port ' + port + ' with /gun'); 17 | //# sourceMappingURL=server2.js.map -------------------------------------------------------------------------------- /lib/example/server/server2.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"server2.js","sourceRoot":"","sources":["../../../src/example/server/server2.ts"],"names":[],"mappings":"AAAA,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACzH,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC;AAE7G,IAAI,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AACjC,IAAI,KAAK,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAC1C,IAAI,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC3B,IAAI,GAAG,GAAG,OAAO,EAAE,CAAC;AACpB,IAAI,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AAEpC,IAAI,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;AACzB,IAAI,GAAG,GAAG,GAAG,CAAC;IACb,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,MAAM;CACX,CAAC,CAAC;AAIH,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACnB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;AAC/B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAEpB,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,IAAI,GAAG,YAAY,CAAC,CAAC"} -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var cycle_gun_1 = require("./cycle-gun"); 4 | exports.makeGunDriver = cycle_gun_1.makeGunDriver; 5 | exports.GunSource = cycle_gun_1.GunSource; 6 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /lib/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yCAAqD;AAA7C,oCAAA,aAAa,CAAA;AAAE,gCAAA,SAAS,CAAA"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cycle-gun", 3 | "version": "0.2.0", 4 | "description": "A cycle.js driver that wraps gun.js", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test-browser-bundler": "./node_modules/.bin/browserify test/browser/index.js --debug > test/browser/bundle.js", 8 | "test-browser-watch": "./node_modules/.bin/watchify test/browser/index.js -o test/browser/bundle.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/JuniperChicago/cycle-gun.git" 14 | }, 15 | "keywords": [ 16 | "cycle.js", 17 | "gun.js" 18 | ], 19 | "author": "Robin Schulemann ", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/JuniperChicago/cycle-gun/issues" 23 | }, 24 | "homepage": "https://github.com/JuniperChicago/cycle-gun#readme", 25 | "dependencies": { 26 | "gun": "^0.9.8", 27 | "xstream": "^11.1.0" 28 | }, 29 | "devDependencies": { 30 | "@cycle/dom": "17.x", 31 | "@cycle/run": "3.x", 32 | "@types/node": "^7.0.22", 33 | "browserify": "14.1.0", 34 | "chai": "3.5.0", 35 | "deep-equal": "1.0.1", 36 | "express": "^4.16.2", 37 | "express-http-proxy": "^1.1.0", 38 | "mocha": "3.2.0", 39 | "typescript": "^2.3.4", 40 | "uuid-random": "^1.0.5", 41 | "watchify": "3.9.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/cycle-gun.ts: -------------------------------------------------------------------------------- 1 | import xs, {Listener, Stream} from 'xstream' 2 | import * as Gun from 'gun' 3 | 4 | export class GunSource { 5 | private gun: any 6 | private path: Array 7 | 8 | constructor(gun: any, path: Array) { 9 | this.gun = gun 10 | this.path = path 11 | } 12 | 13 | public select(key: string): GunSource { 14 | return new GunSource(this.gun, this.path.concat(key)) 15 | } 16 | 17 | public shallow(): Stream { 18 | const self = this 19 | 20 | return xs.create({ 21 | start(listener: Listener) { 22 | self.gun.get(...self.path).on((x: any) => { 23 | listener.next(x) 24 | }) 25 | }, 26 | stop() { 27 | }, 28 | }) 29 | } 30 | 31 | public each(): Stream<{key: string, value: any}> { 32 | const self = this 33 | return xs.create({ 34 | start(listener: Listener<{key: string, value: any}>) { 35 | self.gun.get(...self.path).map().on((value: any, key: string) => { 36 | listener.next({key, value}) 37 | }) 38 | }, 39 | stop() { 40 | }, 41 | }) 42 | } 43 | } 44 | 45 | export type Command = (gun: any) => void 46 | 47 | export function makeGunDriver(opts: any) { 48 | // console.log('gun opts.root--------------------------------------') 49 | // console.log(opts) 50 | // console.log('-----------------------------------------------------') 51 | 52 | const gun = Gun(opts) 53 | 54 | return function gunDriver(sink: Stream) { 55 | sink.addListener({ 56 | next: (command: Command) => command(gun), 57 | }) 58 | 59 | return new GunSource(gun, []) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/example/browser/app.ts: -------------------------------------------------------------------------------- 1 | import xs, { Stream } from 'xstream'; 2 | import sampleCombine from 'xstream/extra/sampleCombine' 3 | //import * as uuid from '../../../node_modules/uuid-random/uuid-random.min.js'; 4 | import * as uuid from 'uuid-random'; 5 | 6 | import { 7 | legend, 8 | div, 9 | table, 10 | td, 11 | tr, 12 | th, 13 | thead, 14 | tbody, 15 | header, 16 | span, 17 | form, 18 | input, 19 | label, 20 | button, 21 | section, 22 | main, 23 | h2, 24 | h3, 25 | h4, 26 | fieldset 27 | 28 | } from '@cycle/dom'; 29 | 30 | 31 | /** 32 | * Transforms gun store object into object containing headers and rows 33 | * 34 | * @param {any} inStream 35 | * @returns 36 | */ 37 | function transformTodoStream(inStream) { 38 | return inStream.map((state) => { 39 | let rows = []; 40 | let headings = []; 41 | let count = 1; 42 | for (let key in state) { 43 | let row = state[key]; 44 | if (!state[key] || typeof row === 'object') continue; 45 | let c = count++ 46 | // might want to convert to json here... 47 | rows.push({ key, val: row }) 48 | } 49 | if (rows.length > 0) { 50 | headings = Object.keys(rows[0]) 51 | headings.push('X') 52 | } 53 | return { 54 | headings, 55 | rows 56 | }; 57 | }); 58 | } 59 | 60 | 61 | function theadElems(tableData) { 62 | const { headings } = tableData; 63 | 64 | const thElems = headings 65 | .filter(heading => heading !== 'key') // skippings the key 66 | .map(heading => { 67 | if (heading === 'X') { 68 | return th('.th-delete', 'X') 69 | } else { 70 | return th('', heading) 71 | } 72 | }) 73 | 74 | return tr('', thElems); 75 | } 76 | 77 | 78 | /** 79 | * build table body elements 80 | * 81 | * @param {any} tableData 82 | * @returns 83 | */ 84 | function tbodyElems(tableData) { 85 | const { headings, rows } = tableData; 86 | return rows.map((row) => { 87 | 88 | const tdElems = headings 89 | .filter(heading => heading !== 'key') // skipping the key 90 | .map((heading) => { 91 | 92 | if (heading === 'X') { 93 | //console.log(row.key) 94 | return td('.delete', [button({ attrs: { class: 'button-remove', 'data-key': row.key } }, 'X')]) 95 | } else { 96 | return td('', row[heading]) 97 | } 98 | }) 99 | 100 | return tr('', tdElems); 101 | }) 102 | } 103 | 104 | export default function app(sources) { 105 | 106 | 107 | function intent(DOM) { 108 | 109 | // clear 110 | const clearButtonClick$ = DOM.select('#clear').events('click') 111 | 112 | // remove task 113 | const removeButtonClick$ = DOM.select('.button-remove').events('click') 114 | 115 | // save task 116 | const saveButtonClick$ = DOM.select('#save-task').events('click') 117 | 118 | // return - save task 119 | const keydownEvent$ = DOM.select('#text-newtask').events('keypress') 120 | .filter(event => event.keyCode === 13) 121 | .map((event) => { 122 | event = event || window.event; // get window.event if e argument missing (in IE) 123 | event.preventDefault(); 124 | return {}; 125 | }) 126 | 127 | // input text value 128 | const textEvent$ = DOM.select('#text-newtask').events('input') 129 | .map(ev => ev.target.value) 130 | .startWith('') 131 | .map(event => ({ typeKey: 'text-content', payload: event })) 132 | 133 | // merge task save events 134 | const saveClickOrEnter$ = xs.merge(saveButtonClick$, keydownEvent$); 135 | 136 | // transform remove task message and payload 137 | const outgunRemoveTask$ = removeButtonClick$ 138 | .map(event => { 139 | const key = event.target.getAttribute('data-key'); 140 | return { typeKey: 'out-gun', payload: { key, value: null } } 141 | }) 142 | 143 | // transform add task message and payload 144 | // TODO: check for duplicates on text event 145 | const outgunAddTask$ = saveClickOrEnter$ 146 | .compose(sampleCombine(textEvent$)) 147 | .map(([click, event]: [any, any]) => 148 | ({ typeKey: 'out-gun', payload: { key: uuid(), value: event.payload } }) 149 | ) 150 | 151 | // transform text clearing events into messages 152 | const textClearEvents$ = xs.merge(clearButtonClick$, saveButtonClick$, keydownEvent$) 153 | .map(event => ({ typeKey: 'text-clear', payload: null })); 154 | 155 | return { 156 | textEvent$, 157 | textClearEvents$, 158 | outgun$: xs.merge(outgunAddTask$, outgunRemoveTask$) as Stream<{ typeKey: string, payload: any }> 159 | } 160 | } 161 | 162 | 163 | // utilizes a reducer type store 164 | // reducers are selected using streams and filters 165 | function model(event$) { 166 | 167 | const clearTransformer$ = event$.filter(event => event.typeKey === 'text-clear') 168 | .map((event) => { 169 | return function (acc) { 170 | acc = '' 171 | return acc; 172 | } 173 | }) 174 | 175 | const textTransformer$ = event$.filter(event => event.typeKey === 'text-content') 176 | .map((event) => { 177 | return function (acc) { 178 | acc = event.payload; 179 | return acc; 180 | } 181 | }) 182 | 183 | const transformSelector$ = xs.merge(clearTransformer$, textTransformer$) 184 | 185 | // general transformer function 186 | const transformer = (acc, trnsFn) => trnsFn(acc); 187 | 188 | return transformSelector$.fold(transformer, '') 189 | 190 | } 191 | 192 | function vtree(gunStream, textStream) { 193 | 194 | return xs.combine(gunStream, textStream).map(([gun, text]) => { 195 | 196 | //////////////////////////////// 197 | 198 | return div('pure-g', [ 199 | div('', [ 200 | main('.content', [ 201 | section('.margin-top', [ 202 | h2("Cycle-Gun Task List Example") 203 | ]), 204 | section('', [ 205 | form('.pure-form.pure-form-stacked', [ 206 | fieldset('', [ 207 | label({ attrs: { for: 'text-newtask' } }, 'Add Task'), 208 | input({ 209 | attrs: { 210 | class: '', 211 | type: 'text', 212 | id: 'text-newtask', 213 | autocomplete: 'off' 214 | }, 215 | hook: { 216 | update: (o, n) => n.elm.value = text 217 | } 218 | }), 219 | ]) 220 | ]), 221 | button('#save-task.pure-button.pure-button-primary.button-margin-right', 'save'), 222 | button('#clear.pure-button.pure-button-primary', 'clear') 223 | ]), 224 | section('', [ 225 | div('', [ 226 | table('.pure-table.example-table', [ 227 | thead('', [theadElems(gun)]), 228 | tbody(tbodyElems(gun)) 229 | ]) 230 | ]) 231 | ]) 232 | ]) 233 | ]) 234 | ]) 235 | 236 | ////////////////////////////// 237 | }) 238 | } 239 | 240 | const { DOM, gun } = sources; 241 | 242 | // Get streams from cycle-gun driver 243 | /////////////////////////////////////////////////////////////////////////// 244 | console.log('sources.gun', gun) 245 | 246 | 247 | const gunTodoEvent$ = gun 248 | .select('example') 249 | .select('todo') 250 | .select('data') 251 | .shallow(); 252 | 253 | console.log('gunTodoEvent$', gunTodoEvent$) 254 | 255 | // We are removing nulls, keys that are meta, etc... 256 | const gunTable$ = transformTodoStream(gunTodoEvent$); 257 | 258 | // intent() returns and object of streams 259 | const events = intent(DOM); 260 | 261 | const blendedTextEvents$ = xs.merge(events.textEvent$, events.textClearEvents$) 262 | 263 | const outgoingGunTodo$ = events.outgun$ 264 | .filter((event) => event.typeKey === 'out-gun') 265 | .map((event) => { 266 | const { key, value } = event.payload; 267 | 268 | // return function that directly interacts with the gun instance 269 | return (gunInstance) => { 270 | 271 | // gun.js api here 272 | return gunInstance.get('example/todo/data').get(key).put(value); 273 | } 274 | }) 275 | 276 | const textState$ = model(blendedTextEvents$); 277 | 278 | const vtree$ = vtree(gunTable$, textState$); 279 | 280 | const sinks = { 281 | gun: outgoingGunTodo$, 282 | DOM: vtree$ 283 | }; 284 | 285 | return sinks; 286 | } -------------------------------------------------------------------------------- /src/example/browser/index.ts: -------------------------------------------------------------------------------- 1 | import xs from 'xstream'; 2 | import { run } from '@cycle/run'; 3 | import { makeDOMDriver, div } from '@cycle/dom'; 4 | import { makeGunDriver } from '../../index.js'; 5 | 6 | import app from './app'; 7 | 8 | // Watch here 9 | 10 | /** 11 | * main function 12 | * 13 | * @param {any} sources 14 | * @returns 15 | */ 16 | function main(sources) { 17 | 18 | const {DOM} = sources; 19 | const appPage = app(sources); 20 | const sinks = { 21 | DOM: appPage.DOM, 22 | gun: xs.merge(appPage.gun), 23 | } 24 | return sinks; 25 | } 26 | 27 | const drivers = { 28 | DOM: makeDOMDriver('#app'), 29 | gun: makeGunDriver('http://localhost:3800') 30 | } 31 | 32 | run(main, drivers); 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/example/server/server.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Test & Development Server 3 | * 4 | * 5 | */ 6 | 7 | import * as Gun from 'gun'; 8 | import http = require('http'); 9 | 10 | const port = 3800; 11 | const ip = '127.0.0.1'; 12 | 13 | const gun = Gun({ 14 | file: './data.json', 15 | s3: { 16 | key: '', // AWS Access Key 17 | secret: '', // AWS Secret Token 18 | bucket: '' // The bucket you want to save into 19 | } 20 | }); 21 | 22 | const server = http.createServer(function (req, res) { 23 | 24 | if (gun.wsp.server(req, res)) { 25 | console.log(req.url); 26 | console.log(res.statusCode); 27 | 28 | return; // filters gun requests! 29 | } 30 | }); 31 | 32 | 33 | gun.wsp(server); 34 | server.listen(port, ip); 35 | 36 | console.log('Server started on port', port, 'with /gun'); 37 | 38 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export {makeGunDriver, GunSource} from './cycle-gun'; 2 | -------------------------------------------------------------------------------- /test/browser/bundle.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && typeof x[0] !== 'number') return false; 303 | return true; 304 | } 305 | 306 | function objEquiv(a, b, opts) { 307 | var i, key; 308 | if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) 309 | return false; 310 | // an identical 'prototype' property. 311 | if (a.prototype !== b.prototype) return false; 312 | //~~~I've managed to break Object.keys through screwy arguments passing. 313 | // Converting to array solves the problem. 314 | if (isArguments(a)) { 315 | if (!isArguments(b)) { 316 | return false; 317 | } 318 | a = pSlice.call(a); 319 | b = pSlice.call(b); 320 | return deepEqual(a, b, opts); 321 | } 322 | if (isBuffer(a)) { 323 | if (!isBuffer(b)) { 324 | return false; 325 | } 326 | if (a.length !== b.length) return false; 327 | for (i = 0; i < a.length; i++) { 328 | if (a[i] !== b[i]) return false; 329 | } 330 | return true; 331 | } 332 | try { 333 | var ka = objectKeys(a), 334 | kb = objectKeys(b); 335 | } catch (e) {//happens when one is a string literal and the other isn't 336 | return false; 337 | } 338 | // having the same number of owned properties (keys incorporates 339 | // hasOwnProperty) 340 | if (ka.length != kb.length) 341 | return false; 342 | //the same set of keys (although not necessarily the same order), 343 | ka.sort(); 344 | kb.sort(); 345 | //~~~cheap key test 346 | for (i = ka.length - 1; i >= 0; i--) { 347 | if (ka[i] != kb[i]) 348 | return false; 349 | } 350 | //equivalent values for every corresponding key, and 351 | //~~~possibly expensive deep test 352 | for (i = ka.length - 1; i >= 0; i--) { 353 | key = ka[i]; 354 | if (!deepEqual(a[key], b[key], opts)) return false; 355 | } 356 | return typeof a === typeof b; 357 | } 358 | 359 | },{"./lib/is_arguments.js":6,"./lib/keys.js":7}],6:[function(require,module,exports){ 360 | var supportsArgumentsClass = (function(){ 361 | return Object.prototype.toString.call(arguments) 362 | })() == '[object Arguments]'; 363 | 364 | exports = module.exports = supportsArgumentsClass ? supported : unsupported; 365 | 366 | exports.supported = supported; 367 | function supported(object) { 368 | return Object.prototype.toString.call(object) == '[object Arguments]'; 369 | }; 370 | 371 | exports.unsupported = unsupported; 372 | function unsupported(object){ 373 | return object && 374 | typeof object == 'object' && 375 | typeof object.length == 'number' && 376 | Object.prototype.hasOwnProperty.call(object, 'callee') && 377 | !Object.prototype.propertyIsEnumerable.call(object, 'callee') || 378 | false; 379 | }; 380 | 381 | },{}],7:[function(require,module,exports){ 382 | exports = module.exports = typeof Object.keys === 'function' 383 | ? Object.keys : shim; 384 | 385 | exports.shim = shim; 386 | function shim (obj) { 387 | var keys = []; 388 | for (var key in obj) keys.push(key); 389 | return keys; 390 | } 391 | 392 | },{}],8:[function(require,module,exports){ 393 | (function (global){ 394 | !function(){function t(n){function o(t){return t.split("/").slice(-1).toString().replace(".js","")}return n.slice?t[o(n)]:function(e,i){n(e={exports:{}}),t[o(i)]=e.exports}}var n;"undefined"!=typeof window&&(n=window),"undefined"!=typeof global&&(n=global),n=n||{};var o=n.console||{log:function(){}};if("undefined"!=typeof module)var e=module;t(function(t){var n={};n.fns=n.fn={is:function(t){return!!t&&"function"==typeof t}},n.bi={is:function(t){return t instanceof Boolean||"boolean"==typeof t}},n.num={is:function(t){return!e(t)&&(t-parseFloat(t)+1>=0||1/0===t||-(1/0)===t)}},n.text={is:function(t){return"string"==typeof t}},n.text.ify=function(t){return n.text.is(t)?t:"undefined"!=typeof JSON?JSON.stringify(t):t&&t.toString?t.toString():t},n.text.random=function(t,n){var o="";for(t=t||24,n=n||"0123456789ABCDEFGHIJKLMNOPQRSTUVWXZabcdefghijklmnopqrstuvwxyz";t>0;)o+=n.charAt(Math.floor(Math.random()*n.length)),t--;return o},n.text.match=function(t,o){function e(t,n){for(var o,e=-1,i=0;o=n[i++];)if(!~(e=t.indexOf(o,e+1)))return!1;return!0}var i=!1;if(t=t||"",o=n.text.is(o)?{"=":o}:o||{},n.obj.has(o,"~")&&(t=t.toLowerCase(),o["="]=(o["="]||o["~"]).toLowerCase()),n.obj.has(o,"="))return t===o["="];if(n.obj.has(o,"*")){if(t.slice(0,o["*"].length)!==o["*"])return!1;i=!0,t=t.slice(o["*"].length)}if(n.obj.has(o,"!")){if(t.slice(-o["!"].length)!==o["!"])return!1;i=!0}if(n.obj.has(o,"+")&&n.list.map(n.list.is(o["+"])?o["+"]:[o["+"]],function(n){return t.indexOf(n)>=0?void(i=!0):!0}))return!1;if(n.obj.has(o,"-")&&n.list.map(n.list.is(o["-"])?o["-"]:[o["-"]],function(n){return t.indexOf(n)<0?void(i=!0):!0}))return!1;if(n.obj.has(o,">")){if(!(t>o[">"]))return!1;i=!0}if(n.obj.has(o,"<")){if(!(tn?-1:n>o?1:0):0}},n.list.map=function(t,n,o){return a(t,n,o)},n.list.index=1,n.obj={is:function(t){return t?t instanceof Object&&t.constructor===Object||"Object"===Object.prototype.toString.call(t).match(/^\[object (\w+)\]$/)[1]:!1}},n.obj.put=function(t,n,o){return(t||{})[n]=o,t},n.obj.has=function(t,n){return t&&Object.prototype.hasOwnProperty.call(t,n)},n.obj.del=function(t,n){return t?(t[n]=null,delete t[n],t):void 0},n.obj.as=function(t,n,o,e){return t[n]=t[n]||(e===o?{}:o)},n.obj.ify=function(t){if(r(t))return t;try{t=JSON.parse(t)}catch(n){t={}}return t},function(){function t(t,n){u(this,n)&&o!==this[n]||(this[n]=t)}var o;n.obj.to=function(n,o){return o=o||{},a(n,t,o),o}}(),n.obj.copy=function(t){return t?JSON.parse(JSON.stringify(t)):t},function(){function t(t,n){var o=this.n;if(!o||!(n===o||r(o)&&u(o,n)))return n?!0:void 0}n.obj.empty=function(n,o){return n&&a(n,t,{n:o})?!1:!0}}(),function(){function t(n,o){return 2===arguments.length?(t.r=t.r||{},void(t.r[n]=o)):(t.r=t.r||[],void t.r.push(n))}var i=Object.keys;n.obj.map=function(a,s,f){var c,l,p,d,g,h=0,v=o(s);if(t.r=null,i&&r(a)&&(d=Object.keys(a),g=!0),e(a)||d)for(l=(d||a).length;l>h;h++){var _=h+n.list.index;if(v){if(p=g?s.call(f||this,a[d[h]],d[h],t):s.call(f||this,a[h],_,t),p!==c)return p}else if(s===a[g?d[h]:h])return d?d[h]:_}else for(h in a)if(v){if(u(a,h)&&(p=f?s.call(f,a[h],h,t):s(a[h],h,t),p!==c))return p}else if(s===a[h])return h;return v?t.r:n.list.index?0:-1}}(),n.time={},n.time.is=function(t){return t?t instanceof Date:+(new Date).getTime()};var o=n.fn.is,e=n.list.is,i=n.obj,r=i.is,u=i.has,a=i.map;t.exports=n})(t,"./type"),t(function(t){t.exports=function n(t,o,e){if(!t)return{to:n};var t=(this.tag||(this.tag={}))[t]||(this.tag[t]={tag:t,to:n._={next:function(){}}});if(o instanceof Function){var i={off:n.off||(n.off=function(){return this.next===n._.next?!0:(this===this.the.last&&(this.the.last=this.back),this.to.back=this.back,this.next=n._.next,void(this.back.to=this.to))}),to:n._,next:o,the:t,on:this,as:e};return(i.back=t.last||t).to=i,t.last=i}return(t=t.to).next(o),t}})(t,"./onto"),t(function(n){function o(t,n){n=n||{},n.id=n.id||"#",n.rid=n.rid||"@",n.uuid=n.uuid||function(){return+new Date+Math.random()};var o=e;return o.stun=function(t){var n=function(t){return n.off&&n===this.stun?(this.stun=null,!1):o.stun.skip?!1:(t&&(t.cb=t.fn,t.off(),e.queue.push(t)),!0)},e=n.res=function(t,r){if(!n.off){if(t instanceof Function)return o.stun.skip=!0,t.call(r),void(o.stun.skip=!1);n.off=!0;var u,a=0,s=e.queue,f=s.length;for(e.queue=[],n===i.stun&&(i.stun=null),a;f>a;a++)u=s[a],u.fn=u.cb,u.cb=null,o.stun.skip=!0,u.ctx.on(u.tag,u.fn,u),o.stun.skip=!1}},i=t._;return e.back=i.stun||(i.back||{_:{}})._.stun,e.back&&(e.back.next=n),e.queue=[],i.stun=n,e},o}var e=t("./onto");n.exports=o})(t,"./onify"),t(function(n){function o(t,n,e){o.time=e,o.waiting.push({when:t,event:n||function(){}}),o.soonest=t?0:t-n,clearTimeout(o.id),o.id=setTimeout(o.check,t)}},o.each=function(t,n,o){var e=this;t&&(t.when<=e.now?t.event instanceof Function&&setTimeout(function(){t.event()},0):(e.soonest=e.soonestt)return{defer:!0};if(e>n)return{historical:!0};if(n>e)return{converge:!0,incoming:!0};if(n===e){if(i=o(i)||"",r=o(r)||"",i===r)return{state:!0};if(r>i)return{converge:!0,current:!0};if(i>r)return{converge:!0,incoming:!0}}return{err:"Invalid CRDT Data: "+i+" to "+r+" at "+n+" to "+e+"!"}}if("undefined"==typeof JSON)throw new Error("JSON is not included in this browser. Please load it first: ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js");var o=JSON.stringify;t.exports=n})(t,"./HAM"),t(function(n){var o=t("./type"),e={};e.is=function(t){return t===i?!1:null===t?!0:t===1/0?!1:s(t)||u(t)||a(t)?!0:e.rel.is(t)||!1},e.rel={_:"#"},function(){function t(t,n){var o=this;return o.id?o.id=!1:n==r&&s(t)?void(o.id=t):o.id=!1}e.rel.is=function(n){if(n&&n[r]&&!n._&&c(n)){var o={};if(p(n,t,o),o.id)return o.id}return!1}}(),e.rel.ify=function(t){return l({},r,t)};var i,r=e.rel._,u=o.bi.is,a=o.num.is,s=o.text.is,f=o.obj,c=f.is,l=f.put,p=f.map;n.exports=e})(t,"./val"),t(function(n){var o=t("./type"),e=t("./val"),i={_:"_"};i.soul=function(t,n){return t&&t._&&t._[n||p]},i.soul.ify=function(t,n){return n="string"==typeof n?{soul:n}:n||{},t=t||{},t._=t._||{},t._[p]=n.soul||t._[p]||l(),t},i.soul._=e.rel._,function(){function t(t,n){return n!==i._?e.is(t)?void(this.cb&&this.cb.call(this.as,t,n,this.n,this.s)):!0:void 0}i.is=function(n,o,e){var r;return a(n)&&(r=i.soul(n))?!f(n,t,{as:e,cb:o,s:r,n:n}):!1}}(),function(){function t(t,n){var o,i,r=this.o;return r.map?(o=r.map.call(this.as,t,""+n,r.node),void(i===o?s(r.node,n):r.node&&(r.node[n]=o))):void(e.is(t)&&(r.node[n]=t))}i.ify=function(n,o,e){return o?"string"==typeof o?o={soul:o}:o instanceof Function&&(o={map:o}):o={},o.map&&(o.node=o.map.call(e,n,r,o.node||{})),(o.node=i.soul.ify(o.node||{},o))&&f(n,t,{o:o,as:e}),o.node}}();var r,u=o.obj,a=u.is,s=u.del,f=u.map,c=o.text,l=c.random,p=i.soul._;n.exports=i})(t,"./node"),t(function(n){function o(){var t;return t=f?c+f.now():r(),t>u?(a=0,u=t+o.drift):u=t+(a+=1)/s+o.drift}var e=t("./type"),i=t("./node"),r=e.time.is,u=-(1/0),a=0,s=1e3,f="undefined"!=typeof performance?performance.timing&&performance:!1,c=f&&f.timing&&f.timing.navigationStart||(f=!1);o._=">",o.drift=0,o.is=function(t,n,e){var i=n&&t&&t[x]&&t[x][o._]||e;if(i)return m(i=i[n])?i:-(1/0)},o.ify=function(t,n,e,r,u){if(!t||!t[x]){if(!u)return;t=i.soul.ify(t,u)}var a=d(t[x],o._);return l!==n&&n!==x&&(m(e)&&(a[n]=e),l!==r&&(t[n]=r)),t},o.to=function(t,n,e){var r=t[n];return h(r)&&(r=_(r)),o.ify(e,n,o.is(t,n),r,i.soul(t))},function(){function t(t,n){x!==n&&o.ify(this.o,n,this.s)}o.map=function(n,e,i){var r,u=h(u=n||e)?u:null;return n=k(n=n||e)?n:null,u&&!n?(e=m(e)?e:o(),u[x]=u[x]||{},v(u,t,{o:u,s:e}),u):(i=i||h(e)?e:r,e=m(e)?e:o(),function(o,u,a,s){return n?(n.call(i||this||{},o,u,a,s),void(g(a,u)&&r===a[u]||t.call({o:a,s:e},o,u))):(t.call({o:a,s:e},o,u),o)})}}();var l,p=e.obj,d=p.as,g=p.has,h=p.is,v=p.map,_=p.copy,b=e.num,m=b.is,y=e.fn,k=y.is,x=i._;n.exports=o})(t,"./state"),t(function(n){var o=t("./type"),e=t("./val"),i=t("./node"),r={};!function(){function t(t,o){return t&&o===i.soul(t)&&i.is(t,this.fn,this.as)?void(this.cb&&(n.n=t,n.as=this.as,this.cb.call(n.as,t,o,n))):!0}function n(t){t&&i.is(n.n,t,n.as)}r.is=function(n,o,e,i){return n&&s(n)&&!l(n)?!d(n,t,{cb:o,fn:e,as:i}):!1}}(),function(){function t(t,r){var u;return(u=l(t,r))?u:(r.env=t,r.soul=o,i.ify(r.obj,n,r)&&(t.graph[e.rel.is(r.rel)]=r.node),r)}function n(n,o,r){var s,l,p=this,d=p.env;if(i._===o&&c(n,e.rel._))return r._;if(s=a(n,o,r,p,d)){if(o||(p.node=p.node||r||{},c(n,i._)&&(p.node._=g(n._)),p.node=i.soul.ify(p.node,e.rel.is(p.rel)),p.rel=p.rel||e.rel.ify(i.soul(p.node))),(l=d.map)&&(l.call(d.as||{},n,o,r,p),c(r,o))){if(n=r[o],u===n)return void f(r,o);if(!(s=a(n,o,r,p,d)))return}if(!o)return p.node;if(!0===s)return n;if(l=t(d,{obj:n,path:p.path.concat(o)}),l.node)return l.rel}}function o(t){var n=this,o=e.rel.is(n.rel),r=n.env.graph;n.rel=n.rel||e.rel.ify(t),n.rel[e.rel._]=t,n.node&&n.node[i._]&&(n.node[i._][e.rel._]=t),c(r,o)&&(r[t]=r[o],f(r,o))}function a(t,n,o,i,r){var u;return e.is(t)?!0:s(t)?1:(u=r.invalid)?(t=u.call(r.as||{},t,n,o),a(t,n,o,i,r)):void(r.err="Invalid value at '"+i.path.concat(n).join(".")+"'!")}function l(t,n){for(var o,e=t.seen,i=e.length;i--;)if(o=e[i],n.obj===o.obj)return o;e.push(n)}r.ify=function(n,o,i){var r={path:[],obj:n};return o?"string"==typeof o?o={soul:o}:o instanceof Function&&(o.map=o):o={},o.soul&&(r.rel=e.rel.ify(o.soul)),o.graph=o.graph||{},o.seen=o.seen||[],o.as=o.as||i,t(o,r),o.root=r.node,o.graph}}(),r.node=function(t){var n=i.soul(t);if(n)return p({},n,t)},function(){function t(t,n){var o,u;if(i._===n){if(l(t,e.rel._))return;return void(this.obj[n]=g(t))}return(o=e.rel.is(t))?(u=this.opt.seen[o])?void(this.obj[n]=u):void(this.obj[n]=this.opt.seen[o]=r.to(this.graph,o,this.opt)):void(this.obj[n]=t)}r.to=function(n,o,e){if(n){var i={};return e=e||{seen:{}},d(n[o],t,{obj:i,graph:n,opt:e}),i}}}();var u,a=(o.fn.is,o.obj),s=a.is,f=a.del,c=a.has,l=a.empty,p=a.put,d=a.map,g=a.copy;n.exports=r})(t,"./graph"),t(function(n){function o(){this.cache={}}var e=t("./type");o.prototype.track=function(t){return this.cache[t]=e.time.is(),this.to||this.gc(),t},o.prototype.check=function(t){return e.obj.has(this.cache,t)?this.track(t):!1},o.prototype.gc=function(){var t=this,n=e.time.is(),o=n,i=3e5;e.obj.map(t.cache,function(r,u){o=Math.min(n,r),i>n-r||e.obj.del(t.cache,u)});var r=e.obj.empty(t.cache);if(r)return void(t.to=null);var u=n-o,a=i-u;t.to=setTimeout(function(){t.gc()},a)},n.exports=o})(t,"./dup"),t(function(n){function i(t){return t instanceof i?(this._={gun:this}).gun:this instanceof i?i.create(this._={gun:this,opt:t}):new i(t)}i.is=function(t){return t instanceof i},i.version=.7,i.chain=i.prototype,i.chain.toJSON=function(){};var r=t("./type");r.obj.to(r,i),i.HAM=t("./HAM"),i.val=t("./val"),i.node=t("./node"),i.state=t("./state"),i.graph=t("./graph"),i.dup=t("./dup"),i.schedule=t("./schedule"),i.on=t("./onify")(),i._={node:i.node._,soul:i.val.rel._,state:i.state._,field:".",value:"="},function(){function t(t){var n,o=this,e=o.as;if(t.gun||(t.gun=e.gun),t["#"]||(t["#"]=i.text.random()),!e.dup.check(t["#"])){if(t["@"]){if(e.ack(t["@"],t))return;return e.dup.track(t["#"]),void i.on("out",p(t,{gun:e.gun}))}e.dup.track(t["#"]),n=p(t,{gun:e.gun}),t.get&&i.on("get",n),t.put&&i.on("put",n),i.on("out",n)}}i.create=function(n){n.on=n.on||i.on,n.root=n.root||n.gun,n.graph=n.graph||{},n.dup=n.dup||new i.dup,n.ask=i.on.ask,n.ack=i.on.ack;var o=n.gun.opt(n.opt);return n.once||(n.on("in",t,n),n.on("out",t,n)),n.once=1,o}}(),function(){function t(t,n,o,e){var r=this,u=i.state.is(o,n);if(!u)return r.err="Error: No state on '"+n+"' in node '"+e+"'!";var a=r.graph[e]||v,s=i.state.is(a,n,!0),f=a[n],c=i.HAM(r.machine,u,s,t,f);c.incoming||c.defer&&(r.defer=u<(r.defer||1/0)?u:r.defer),r.put[e]=i.state.to(o,n,r.put[e]),(r.diff||(r.diff={}))[e]=i.state.to(o,n,r.diff[e])}function n(t,n){var e=(this.gun._.next||v)[n];if(e){var r=this.map[n]={put:this.node=t,get:this.soul=n,gun:this.ref=e};d(t,o,this),i.on("node",r)}}function o(t,n){var o=this.graph,e=this.soul,r=this.ref._;o[e]=i.state.to(this.node,n,o[e]),(r.put||(r.put={}))[n]=t}function e(t){t.gun&&t.gun._.on("in",t)}i.on("put",function(o){if(!o["#"])return this.to.next(o);var r=this,a={gun:o.gun,graph:o.gun._.graph,put:{},map:{},machine:i.state()};return i.graph.is(o.put,null,t,a)||(a.err="Error: Invalid graph!"),a.err?a.gun.on("in",{"@":o["#"],err:i.log(a.err)}):(d(a.put,n,a),d(a.map,e,a),u!==a.defer&&i.schedule(a.defer,function(){i.on("put",o)},i.state),void(a.diff&&r.to.next(p(o,{put:a.diff}))))})}(),function(){i.on("get",function(t){var n,o=this,e=t.get[g],r=t.gun._,u=r.graph[e],a=t.get[h],s=r.next||(r.next={}),f=(s[e]||v)._;if(!u||!f)return o.to.next(t);if(a){if(!l(u,a))return o.to.next(t);u=i.state.to(u,a)}else u=i.obj.copy(u);u=i.graph.node(u),n=f.ack,r.on("in",{"@":t["#"],how:"mem",put:u,gun:f.gun}),n>0||o.to.next(t)})}(),function(){i.on.ask=function(t,n){if(this.on){var o=i.text.random();return t&&this.on(o,t,n),o}},i.on.ack=function(t,n){if(t&&n&&this.on){var o=t["#"]||t;if(this.tag&&this.tag[o])return this.on(o,n),!0}}}(),function(){i.chain.opt=function(t){t=t||{};var n=this,o=n._,e=t.peers||t;return c(t)||(t={}),c(o.opt)||(o.opt=t),a(e)&&(e=[e]),s(e)&&(e=d(e,function(t,n,o){o(t,{url:t})}),c(o.opt.peers)||(o.opt.peers={}),o.opt.peers=p(e,o.opt.peers)),o.opt.wsc=o.opt.wsc||{protocols:""},o.opt.peers=o.opt.peers||{},p(t,o.opt),i.on("opt",o),n}}();var u,a=i.text.is,s=i.list.is,f=i.obj,c=f.is,l=f.has,p=f.to,d=f.map,g=(f.copy,i._.soul),h=i._.field,v=(i.val.rel.is,{});o.debug=function(t,n){return o.debug.i&&t===o.debug.i&&o.debug.i++&&(o.log.apply(o,arguments)||n)},i.log=function(){return!i.log.off&&o.log.apply(o,arguments),[].slice.call(arguments).join(" ")},i.log.once=function(t,n,o){return(o=i.log.once)[t]=o[t]||0,o[t]++||i.log(n)},i.log.once("welcome","Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!"),"undefined"!=typeof window&&(window.Gun=i),"undefined"!=typeof e&&(e.exports=i),n.exports=i})(t,"./root"),t(function(){var n=t("./root");n.chain.back=function(t,n){var i;if(-1===t||1/0===t)return this._.root;if(1===t)return this._.back||this;var r=this,u=r._;if("string"==typeof t&&(t=t.split(".")),t instanceof Array){var a=0,s=t.length,i=u;for(a;s>a;a++)i=(i||e)[t[a]];if(o!==i)return n?r:i;if(i=u.back)return i.back(t,n)}else if(t instanceof Function){for(var f,i={back:r};(i=i.back)&&(i=i._)&&!(f=t(i,n)););return f}};var o,e={}})(t,"./back"),t(function(){function o(t){var n,o,e,i=this.as,r=i.gun,u=r.back(-1);if(t.gun||(t.gun=r),o=t.get)if(e=o[m])e=u.get(e)._,g(o,y)?g(n=e.put,o=o[y])&&e.on("in",{get:e.get,put:c.state.to(n,o),gun:e.gun}):g(e,"put")&&e.on("in",e);else if(g(o,y)){o=o[y];var a=o?r.get(o)._:i;if(l!==a.put)return void a.on("in",a);if(g(i,"put")){var s,f=i.put;if((s=c.node.soul(f))&&(f=c.val.rel.ify(s)),s=c.val.rel.is(f)){if(!t.gun._)return;return void t.gun._.on("out",{get:e={"#":s,".":o,gun:t.gun},"#":u._.ask(c.HAM.synth,e),gun:t.gun})}if(l===f||c.val.is(f)){if(!t.gun._)return;return void t.gun._.on("in",{get:o,gun:t.gun})}}else i.map&&b(i.map,function(t){t.at.on("in",t.at)});if(i.soul){if(!t.gun._)return;return void t.gun._.on("out",{get:e={"#":i.soul,".":o,gun:t.gun},"#":u._.ask(c.HAM.synth,e),gun:t.gun})}if(i.get){if(!i.back._)return;return void i.back._.on("out",{get:h({},y,i.get),gun:r})}t=_(t,{get:{}})}else{if(g(i,"put")?i.on("in",i):i.map&&b(i.map,function(t){t.at.on("in",t.at)}),i.ack&&!g(i,"put"))return;if(i.ack=-1,i.soul)return void i.on("out",{get:e={"#":i.soul,gun:i.gun},"#":u._.ask(c.HAM.synth,e),gun:i.gun});if(i.get){if(!i.back._)return;return void i.back._.on("out",{get:h({},y,i.get),gun:i.gun})}}i.back._.on("out",t)}function e(t){t=t._||t;{var n,o=this,e=this.as,u=t.gun,f=u._,d=t.put;e.back._||p}if(0>e.ack&&!t.ack&&!c.val.rel.is(d)&&(e.ack=1),e.get&&t.get!==e.get&&(t=_(t,{get:e.get})),e.field&&f!==e&&(t=_(t,{gun:e.gun}),f.ack&&(e.ack=e.ack||f.ack)),l===d){if(o.to.next(t),e.soul)return;return r(e,t,o),e.field&&s(e,t),v(f.echo,e.id),void v(e.map,f.id)}return e.soul?(e.root._.now&&(t=_(t,{put:d=f.put})),o.to.next(t),r(e,t,o),void b(d,a,{at:t,cat:e})):(n=c.val.rel.is(d))?(i(e,t,f,n),o.to.next(t),void r(e,t,o)):c.val.is(d)?(e.field||e.soul?s(e,t):(f.field||f.soul)&&((f.echo||(f.echo={}))[e.id]=e,(e.map||(e.map={}))[f.id]=e.map[f.id]||{at:f}),o.to.next(t),void r(e,t,o)):(e.field&&f!==e&&g(f,"put")&&(e.put=f.put),(n=c.node.soul(d))&&f.field&&(f.put=e.root.get(n)._.put),o.to.next(t),r(e,t,o),i(e,t,f,n),void b(d,a,{at:t,cat:e}))}function i(t,n,o,e){if(e&&k!==t.get){var r=t.root.get(e)._;t.field?o=r:o.field&&i(o,n,o,e),o!==t&&((o.echo||(o.echo={}))[t.id]=t,t.field&&!(t.map||p)[o.id]&&s(t,n),r=(t.map||(t.map={}))[o.id]=t.map[o.id]||{at:o},e!==r.rel&&f(t,r.rel=e))}}function r(t,n,o){t.echo&&(t.field&&(n=_(n,{event:o})),b(t.echo,u,n))}function u(t){t.on("in",this)}function a(t,n){var o,e,i,r=this.cat,u=r.next||p,a=this.at;(k!==n||u[n])&&(o=u[n])&&(i=o._,i.field?(t&&t[m]&&c.val.rel.is(t)===c.node.soul(i.put)||(i.put=t),e=o):e=a.gun.get(n),i.on("in",{put:t,get:n,gun:e,via:a}))}function s(t){if(t.field||t.soul){var n=t.map;t.map=null,null!==n&&(l!==n||t.put===l)&&(b(n,function(n){(n=n.at)&&v(n.echo,t.id)}),b(t.next,function(t,n){var o=t._;o.put=l,o.ack&&(o.ack=-1),o.on("in",{get:n,gun:t,put:l})}))}}function f(t,n){var o=t.root.get(n)._;return t.ack?(o.ack=o.ack||-1,void o.on("out",{get:o={"#":n,gun:o.gun},"#":t.root._.ask(c.HAM.synth,o)})):void b(t.next,function(o,e){o._.on("out",{get:o={"#":n,".":e,gun:o},"#":t.root._.ask(c.HAM.synth,o)})})}var c=t("./root");c.chain.chain=function(){var t=this._,i=new this.constructor(this),r=i._;return r.root=n=t.root,r.id=++n._.once,r.back=this,r.on=c.on,c.on("chain",r),r.on("in",e,r),r.on("out",o,r),i},c.chain.chain.input=e;var l,p={},d=c.obj,g=d.has,h=d.put,v=d.del,_=d.to,b=d.map,m=c._.soul,y=c._.field,k=c.node._})(t,"./chain"),t(function(){function n(t,n){var o=n._,e=o.next,i=n.chain(),r=i._;return e||(e=o.next={}),e[r.get=t]=i,o.root===n?r.soul=t:(o.soul||o.field)&&(r.field=t),i}function o(t){var n,o=this,e=o.as,r=t.gun,a=r._,f=t.put;i===f&&(f=a.put),(n=f)&&n[s._]&&(n=s.is(n))&&(n=a.root.get(n)._,i!==n.put&&(t=u(t,{put:n.put}))),e.use(t,t.event||o),o.to.next(t)}var e=t("./root");e.chain.get=function(t,i,r){if("string"!=typeof t){if(t instanceof Function){var u=this,s=u._;return r=i||{},r.use=t,r.out=r.out||{cap:1},r.out.get=r.out.get||{},"_"!=s.get&&(s.root._.now=!0),s.on("in",o,r),s.on("out",r.out),s.root._.now=!1,u}return a(t)?this.get(""+t,i,r):((r=this.chain())._.err={err:e.log("Invalid get request!",t)},i&&i.call(r,r._.err),r)}var u,c,l=this,p=l._,d=p.next||f;return(u=d[t])||(u=n(t,l)),(c=p.stun)&&(u._.stun=u._.stun||c),i&&i instanceof Function&&u.get(i,r),u};var i,r=e.obj,u=(r.has,e.obj.to),a=e.num.is,s=e.val.rel,f=(e.node._,{})})(t,"./get"),t(function(){function n(t){t.batch=e;var n=t.opt||{},o=t.env=s.state.map(r,n.state);return o.soul=t.soul,t.graph=s.graph.ify(t.data,o,t),o.err?((t.ack||h).call(t,t.out={err:s.log(o.err)}),void(t.res&&t.res())):void t.batch()}function e(){var t=this;t.graph&&!d(t.stun,i)&&((t.res||v)(function(){t.ref._.on("out",{cap:3,gun:t.ref,put:t.out=t.env.graph,opt:t.opt,"#":t.gun.back(-1)._.ask(function(n){this.off(),t.ack&&t.ack(n,this)},t.opt)})},t),t.res&&t.res())}function i(t){return t?!0:void 0}function r(t,n,o,e){var i=this;!n&&e.path.length&&(i.res||v)(function(){var t=e.path,n=i.ref,o=(i.opt,0),r=t.length;for(o;r>o;o++)n=n.get(t[o]);if(i.not||s.node.soul(e.obj)){var a=s.node.soul(e.obj)||((i.opt||{}).uuid||i.gun.back("opt.uuid")||s.text.random)();return n.back(-1).get(a),void e.soul(a)}(i.stun=i.stun||{})[t]=!0,n.get("_").get(u,{as:{at:e,as:i}})},{as:i,at:e})}function u(t,n){var o=this.as,e=o.at;if(o=o.as,t.gun&&t.gun._.back){n.off(),t=t.gun._.back._;var i=s.node.soul(e.obj)||s.node.soul(t.put)||s.val.rel.is(t.put)||((o.opt||{}).uuid||o.gun.back("opt.uuid")||s.text.random)();t.gun.back(-1).get(i),e.soul(i),o.stun[e.path]=!1,o.batch()}}function a(t,n){var e=this.as;if(t.gun&&t.gun._){if(t.err)return void o.log("Please report this as an issue! Put.any.err");var i,r=t.gun._.back._,u=r.put,a=e.opt||{};if(n.off(),e.ref!==e.gun){if(i=e.gun._.get||r.get,!i)return void o.log("Please report this as an issue! Put.no.get");e.data=p({},i,e.data),i=null}if(f===u){if(!r.get)return;r.soul||(i=r.gun.back(function(t){return t.soul?t.soul:void(e.data=p({},t.get,e.data))})),i=i||r.get,r=r.root.get(i)._,e.not=e.soul=i,u=e.data}e.not||(e.soul=s.node.soul(u))||(e.soul=e.path&&l(e.data)?(a.uuid||r.root._.opt.uuid||s.text.random)():t.soul||r.soul||(a.uuid||r.root._.opt.uuid||s.text.random)()),e.ref.put(e.data,e.soul,e)}}var s=t("./root");s.chain.put=function(t,o,e){var i,r=this,u=r._,f=u.root;return e=e||{},e.data=t,e.gun=e.gun||r,"string"==typeof o?e.soul=o:e.ack=o,u.soul&&(e.soul=u.soul),e.soul||f===r?l(e.data)?(e.gun=r=f.get(e.soul=e.soul||(e.not=s.node.soul(e.data)||(f._.opt.uuid||s.text.random)())),e.ref=e.gun,n(e),r):((e.ack||h).call(e,e.out={err:s.log("Data saved to the root level of the graph must be a node (an object), not a",typeof e.data,'of "'+e.data+'"!')}),e.res&&e.res(),r):s.is(t)?(t.get(function(t,n){n.off();var i=s.node.soul(t.put);return i?void r.put(s.val.rel.ify(i),o,e):void s.log("The reference you are saving is a",typeof t.put,'"'+e.put+'", not a node (object)!')}),r):(e.ref=e.ref||f===(i=u.back)?r:i,e.ref._.soul&&s.val.is(e.data)&&u.get?(e.data=p({},u.get,e.data),e.ref.put(e.data,e.soul,e),r):(e.ref.get("_").get(a,{as:e}),e.out||(e.res=e.res||s.on.stun(e.ref),e.gun._.stun=e.ref._.stun),r))};var f,c=s.obj,l=c.is,p=c.put,d=c.map,g={},h=function(){},v=function(t,n){t.call(n||g)}})(t,"./put"),t(function(n){var e=t("./root");n.exports=e,function(){function t(t,n){if(e._.node!==n){var r=this.node,u=this.vertex,a=this.union,s=this.machine,f=g(r,n),c=g(u,n);if(i===f||i===c)return!0;var l=t,p=u[n];if(!_(l)&&i!==l)return!0;if(!_(p)&&i!==p)return!0;var d=e.HAM(s,f,c,l,p);if(d.err)return void o.log(".!HYPOTHETICAL AMNESIA MACHINE ERR!.",n,d.err);if(!(d.state||d.historical||d.current))return d.incoming?(a[n]=t,void h(a,n,f)):d.defer?(a[n]=t,void h(a,n,f)):void 0}}function n(t,n){var o=this;if(e._.node!==n&&_(t)){var i=o.node,r=o.vertex,u=g(i,n,!0),a=g(r,n,!0),s=o.delta,f=e.HAM(o.machine,u,a,t,r[n]);f.incoming&&(s[n]=t,h(s,n,u))}}e.HAM.union=function(n,o,i){return o&&o._&&(n=n||e.node.soul.ify({_:{">":{}}},e.node.soul(o)),n&&n._&&(i=a(i)?{machine:i}:{machine:e.state()},i.union=n||e.obj.copy(n),i.vertex=n,i.node=o,!l(o,t,i)))?i.union:void 0},e.HAM.delta=function(t,o,i){return i=a(i)?{machine:i}:{machine:e.state()},t?(i.soul=e.node.soul(i.vertex=t),i.soul?(i.delta=e.node.soul.ify({},i.soul),l(i.node=o,n,i),i.delta):void 0):e.obj.copy(o)},e.HAM.synth=function(t){var n=this.as,o=n.gun._;if(!t.put||n["."]&&!f(t.put[n["#"]],o.get)){if(o.put!==i)return;return void o.on("in",{get:o.get,put:o.put=i,gun:o.gun})}t.gun=o.root,e.on("put",t)},e.HAM.synth_=function(t,n,o){var r=this.as||o,u=r._,a=u.root._,s={};if(!t.put){if(u.put!==i)return;return void u.on("in",{get:u.get,put:u.put=i,gun:r,via:t})}l(t.put,function(t,n){var o=this.graph;s[n]=e.HAM.delta(o[n],t,{graph:o}),o[n]=e.HAM.union(o[n],t)||o[n]},a),t.gun!==a.gun&&(s=t.put),l(s,function(o,r){var a=this,s=a.next||(a.next={}),l=s[r]||(s[r]=a.gun.get(r)),p=l._;return p.put=a.graph[r],u.field&&!f(o,u.field)?((t=c(t,{})).put=i,void e.HAM.synth(t,n,u.gun)):void p.on("in",{put:o,get:r,gun:l,via:t})},a)}}();{var i,r=e,u=r.num,a=u.is,s=r.obj,f=s.has,c=(s.put,s.to),l=s.map,p=e.node,d=(p.soul,p.is,p.ify,e.state),g=d.is,h=d.ify,v=e.val,_=v.is;v.rel.is}})(t,"./index"),t(function(n){var o=t("./root");t("./index"),t("./opt"),t("./chain"),t("./back"),t("./put"),t("./get"),n.exports=o})(t,"./core"),t(function(){var n=t("./core");n.chain.path=function(t,o,e){var i,r=this,u=r;if(e=e||{},e.path=!0,n.log.once("pathing","Warning: `.path` to be removed from core (but available as an extension), use `.get` chains instead. If you are opposed to this, please voice your opinion in https://gitter.im/amark/gun and ask others."),u===u._.root)return o&&o({err:n.log("Can't do that on root instance.")}),u;if("string"==typeof t){if(i=t.split(e.split||"."),1===i.length)return u=r.get(t,o,e),u._.opt=e,u;t=i}if(t instanceof Array){if(t.length>1){u=r;var a=0,s=t.length;for(a;s>a;a++)u=u.get(t[a],a+1===s?o:null,e)}else u=r.get(t[0],o,e);return u._.opt=e,u}return t||0==t?(u=r.get(""+t,o,e),u._.opt=e,u):r}})(t,"./path"),t(function(){function n(t,n){var o,r=this,u=t.gun,s=u._,f=s.put||t.put,o=r.last,c=s.id+t.get;if(i!==f){if(f&&f[a._]&&(o=a.is(f))){if(o=s.root.get(o)._,i===o.put)return;f=o.put}r.change&&(f=t.put),(o.put!==f||o.get!==c||e.node.soul(f))&&(o.put=f,o.get=c,s.last=f,r.as?r.ok.call(r.as,t,n):r.ok.call(u,f,t.get,t,n))}}function o(t,n){var e,r=this.as,u=r.cat,s=t.gun,f=s._,c=f.put||t.put;if(c&&c[a._]&&(e=a.is(c))){if(e=u.root.get(e)._,i===e.put)return;c=e.put}if(n.wait&&clearTimeout(n.wait),!r.async)return void(n.wait=setTimeout(function(){o.call({as:r},t,n,n.wait||1)},r.wait||99));if(u.field||u.soul){if(n.off())return}else{if((r.seen=r.seen||{})[f.id])return;r.seen[f.id]=!0}r.ok.call(t.gun||r.gun,c,t.get)}var e=t("./core");e.chain.on=function(t,o,e,i){var r,u,a=this,f=a._;if("string"==typeof t)return o?(r=f.on(t,o,e||f,i),e&&e.gun&&(e.subs||(e.subs=[])).push(r),u=function(){r&&r.off&&r.off(),u.off()},u.off=a.off.bind(a)||s,a.off=u,a):f.on(t);var c=o;return c=!0===c?{change:!0}:c||{},c.ok=t,c.last={},a.get(n,c),a},e.chain.val=function(t,n){var r=this,u=r._,a=u.put;if(0=a?n():void(o||(clearTimeout(o),o=setTimeout(n,1e3)))}),Gun.on("get",function(t){this.to.next(t);var n,o,i,u,a=t.gun,s=t.get;if((i=t.opt||{}).prefix=i.prefix||t.gun.back("opt.prefix")||"gun/",s&&(n=s[Gun._.soul])){var f=s["."];o=Gun.obj.ify(e.getItem(i.prefix+n)||null)||r[n]||u,o&&f&&(o=Gun.state.to(o,f)),(o||Gun.obj.empty(a.back("opt.peers")))&&a.on("in",{"@":t["#"],put:Gun.graph.node(o),how:"lS"})}})}})(t,"./adapters/localStorage"),t(function(){function n(t){var n=a,o=this,i=t.wire||e(t,o);return o.wsp&&o.wsp.count++,i?i.readyState===i.OPEN?void i.send(n):void(t.queue=t.queue||[]).push(n):void 0}function o(t,n,e){if(e&&t){try{t=JSON.parse(t.data||t)}catch(i){}if(t instanceof Array)for(var r,u=0;r=t[u++];)o(r,n,e);else e.wsp&&1===e.wsp.count&&((t.body||t).wsp=f),e.gun.on("in",t.body||t)}}function e(t,e){if(t&&t.url){var s=t.url.replace("http","ws"),f=t.wire=new u(s,e.opt.wsc.protocols,e.opt.wsc);return f.onclose=function(){i(t,e)},f.onerror=function(n){i(t,e),n&&"ECONNREFUSED"===n.code},f.onopen=function(){var o=t.queue;t.queue=[],r.obj.map(o,function(o){a=o,n.call(e,t)})},f.onmessage=function(n){o(n,t,e)},f}}function i(t,n){clearTimeout(t.defer),t.defer=setTimeout(function(){e(t,n)},2e3)}var r=t("./core");if("undefined"==typeof JSON)throw new Error("Gun depends on JSON. Please load it first:\najax.cdnjs.com/ajax/libs/json2/20110223/json2.js");var u;if("undefined"!=typeof window){u=window.WebSocket||window.webkitWebSocket||window.mozWebSocket;var a,s,f=function(){};r.on("out",function(t){this.to.next(t);var o=t.gun._.root._,e=o.wsp||(o.wsp={});if(!t.wsp||1!==e.count){if(a=JSON.stringify(t),o.udrain)return void o.udrain.push(a);o.udrain=[],clearTimeout(s),s=setTimeout(function(){if(o.udrain){var t=o.udrain;o.udrain=null,t.length&&(a=JSON.stringify(t),r.obj.map(o.opt.peers,n,o))}},1),e.count=0,r.obj.map(o.opt.peers,n,o)}})}})(t,"./polyfill/request")}(); 395 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 396 | },{}],9:[function(require,module,exports){ 397 | module.exports = require('./lib/index'); 398 | 399 | },{"./lib/index":10}],10:[function(require,module,exports){ 400 | (function (global){ 401 | 'use strict'; 402 | 403 | Object.defineProperty(exports, "__esModule", { 404 | value: true 405 | }); 406 | 407 | var _ponyfill = require('./ponyfill'); 408 | 409 | var _ponyfill2 = _interopRequireDefault(_ponyfill); 410 | 411 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 412 | 413 | var root; /* global window */ 414 | 415 | 416 | if (typeof self !== 'undefined') { 417 | root = self; 418 | } else if (typeof window !== 'undefined') { 419 | root = window; 420 | } else if (typeof global !== 'undefined') { 421 | root = global; 422 | } else if (typeof module !== 'undefined') { 423 | root = module; 424 | } else { 425 | root = Function('return this')(); 426 | } 427 | 428 | var result = (0, _ponyfill2['default'])(root); 429 | exports['default'] = result; 430 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 431 | },{"./ponyfill":11}],11:[function(require,module,exports){ 432 | 'use strict'; 433 | 434 | Object.defineProperty(exports, "__esModule", { 435 | value: true 436 | }); 437 | exports['default'] = symbolObservablePonyfill; 438 | function symbolObservablePonyfill(root) { 439 | var result; 440 | var _Symbol = root.Symbol; 441 | 442 | if (typeof _Symbol === 'function') { 443 | if (_Symbol.observable) { 444 | result = _Symbol.observable; 445 | } else { 446 | result = _Symbol('observable'); 447 | _Symbol.observable = result; 448 | } 449 | } else { 450 | result = '@@observable'; 451 | } 452 | 453 | return result; 454 | }; 455 | },{}],12:[function(require,module,exports){ 456 | "use strict"; 457 | var index_1 = require("../index"); 458 | var empty = {}; 459 | var DropRepeatsOperator = (function () { 460 | function DropRepeatsOperator(ins, fn) { 461 | this.ins = ins; 462 | this.fn = fn; 463 | this.type = 'dropRepeats'; 464 | this.out = null; 465 | this.v = empty; 466 | } 467 | DropRepeatsOperator.prototype._start = function (out) { 468 | this.out = out; 469 | this.ins._add(this); 470 | }; 471 | DropRepeatsOperator.prototype._stop = function () { 472 | this.ins._remove(this); 473 | this.out = null; 474 | this.v = empty; 475 | }; 476 | DropRepeatsOperator.prototype.isEq = function (x, y) { 477 | return this.fn ? this.fn(x, y) : x === y; 478 | }; 479 | DropRepeatsOperator.prototype._n = function (t) { 480 | var u = this.out; 481 | if (!u) 482 | return; 483 | var v = this.v; 484 | if (v !== empty && this.isEq(t, v)) 485 | return; 486 | this.v = t; 487 | u._n(t); 488 | }; 489 | DropRepeatsOperator.prototype._e = function (err) { 490 | var u = this.out; 491 | if (!u) 492 | return; 493 | u._e(err); 494 | }; 495 | DropRepeatsOperator.prototype._c = function () { 496 | var u = this.out; 497 | if (!u) 498 | return; 499 | u._c(); 500 | }; 501 | return DropRepeatsOperator; 502 | }()); 503 | exports.DropRepeatsOperator = DropRepeatsOperator; 504 | /** 505 | * Drops consecutive duplicate values in a stream. 506 | * 507 | * Marble diagram: 508 | * 509 | * ```text 510 | * --1--2--1--1--1--2--3--4--3--3| 511 | * dropRepeats 512 | * --1--2--1--------2--3--4--3---| 513 | * ``` 514 | * 515 | * Example: 516 | * 517 | * ```js 518 | * import dropRepeats from 'xstream/extra/dropRepeats' 519 | * 520 | * const stream = xs.of(1, 2, 1, 1, 1, 2, 3, 4, 3, 3) 521 | * .compose(dropRepeats()) 522 | * 523 | * stream.addListener({ 524 | * next: i => console.log(i), 525 | * error: err => console.error(err), 526 | * complete: () => console.log('completed') 527 | * }) 528 | * ``` 529 | * 530 | * ```text 531 | * > 1 532 | * > 2 533 | * > 1 534 | * > 2 535 | * > 3 536 | * > 4 537 | * > 3 538 | * > completed 539 | * ``` 540 | * 541 | * Example with a custom isEqual function: 542 | * 543 | * ```js 544 | * import dropRepeats from 'xstream/extra/dropRepeats' 545 | * 546 | * const stream = xs.of('a', 'b', 'a', 'A', 'B', 'b') 547 | * .compose(dropRepeats((x, y) => x.toLowerCase() === y.toLowerCase())) 548 | * 549 | * stream.addListener({ 550 | * next: i => console.log(i), 551 | * error: err => console.error(err), 552 | * complete: () => console.log('completed') 553 | * }) 554 | * ``` 555 | * 556 | * ```text 557 | * > a 558 | * > b 559 | * > a 560 | * > B 561 | * > completed 562 | * ``` 563 | * 564 | * @param {Function} isEqual An optional function of type 565 | * `(x: T, y: T) => boolean` that takes an event from the input stream and 566 | * checks if it is equal to previous event, by returning a boolean. 567 | * @return {Stream} 568 | */ 569 | function dropRepeats(isEqual) { 570 | if (isEqual === void 0) { isEqual = void 0; } 571 | return function dropRepeatsOperator(ins) { 572 | return new index_1.Stream(new DropRepeatsOperator(ins, isEqual)); 573 | }; 574 | } 575 | Object.defineProperty(exports, "__esModule", { value: true }); 576 | exports.default = dropRepeats; 577 | 578 | },{"../index":13}],13:[function(require,module,exports){ 579 | "use strict"; 580 | var __extends = (this && this.__extends) || function (d, b) { 581 | for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 582 | function __() { this.constructor = d; } 583 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 584 | }; 585 | var symbol_observable_1 = require("symbol-observable"); 586 | var NO = {}; 587 | exports.NO = NO; 588 | function noop() { } 589 | function cp(a) { 590 | var l = a.length; 591 | var b = Array(l); 592 | for (var i = 0; i < l; ++i) 593 | b[i] = a[i]; 594 | return b; 595 | } 596 | function and(f1, f2) { 597 | return function andFn(t) { 598 | return f1(t) && f2(t); 599 | }; 600 | } 601 | function _try(c, t, u) { 602 | try { 603 | return c.f(t); 604 | } 605 | catch (e) { 606 | u._e(e); 607 | return NO; 608 | } 609 | } 610 | var NO_IL = { 611 | _n: noop, 612 | _e: noop, 613 | _c: noop, 614 | }; 615 | exports.NO_IL = NO_IL; 616 | // mutates the input 617 | function internalizeProducer(producer) { 618 | producer._start = function _start(il) { 619 | il.next = il._n; 620 | il.error = il._e; 621 | il.complete = il._c; 622 | this.start(il); 623 | }; 624 | producer._stop = producer.stop; 625 | } 626 | var StreamSub = (function () { 627 | function StreamSub(_stream, _listener) { 628 | this._stream = _stream; 629 | this._listener = _listener; 630 | } 631 | StreamSub.prototype.unsubscribe = function () { 632 | this._stream.removeListener(this._listener); 633 | }; 634 | return StreamSub; 635 | }()); 636 | var Observer = (function () { 637 | function Observer(_listener) { 638 | this._listener = _listener; 639 | } 640 | Observer.prototype.next = function (value) { 641 | this._listener._n(value); 642 | }; 643 | Observer.prototype.error = function (err) { 644 | this._listener._e(err); 645 | }; 646 | Observer.prototype.complete = function () { 647 | this._listener._c(); 648 | }; 649 | return Observer; 650 | }()); 651 | var FromObservable = (function () { 652 | function FromObservable(observable) { 653 | this.type = 'fromObservable'; 654 | this.ins = observable; 655 | this.active = false; 656 | } 657 | FromObservable.prototype._start = function (out) { 658 | this.out = out; 659 | this.active = true; 660 | this._sub = this.ins.subscribe(new Observer(out)); 661 | if (!this.active) 662 | this._sub.unsubscribe(); 663 | }; 664 | FromObservable.prototype._stop = function () { 665 | if (this._sub) 666 | this._sub.unsubscribe(); 667 | this.active = false; 668 | }; 669 | return FromObservable; 670 | }()); 671 | var Merge = (function () { 672 | function Merge(insArr) { 673 | this.type = 'merge'; 674 | this.insArr = insArr; 675 | this.out = NO; 676 | this.ac = 0; 677 | } 678 | Merge.prototype._start = function (out) { 679 | this.out = out; 680 | var s = this.insArr; 681 | var L = s.length; 682 | this.ac = L; 683 | for (var i = 0; i < L; i++) 684 | s[i]._add(this); 685 | }; 686 | Merge.prototype._stop = function () { 687 | var s = this.insArr; 688 | var L = s.length; 689 | for (var i = 0; i < L; i++) 690 | s[i]._remove(this); 691 | this.out = NO; 692 | }; 693 | Merge.prototype._n = function (t) { 694 | var u = this.out; 695 | if (u === NO) 696 | return; 697 | u._n(t); 698 | }; 699 | Merge.prototype._e = function (err) { 700 | var u = this.out; 701 | if (u === NO) 702 | return; 703 | u._e(err); 704 | }; 705 | Merge.prototype._c = function () { 706 | if (--this.ac <= 0) { 707 | var u = this.out; 708 | if (u === NO) 709 | return; 710 | u._c(); 711 | } 712 | }; 713 | return Merge; 714 | }()); 715 | var CombineListener = (function () { 716 | function CombineListener(i, out, p) { 717 | this.i = i; 718 | this.out = out; 719 | this.p = p; 720 | p.ils.push(this); 721 | } 722 | CombineListener.prototype._n = function (t) { 723 | var p = this.p, out = this.out; 724 | if (out === NO) 725 | return; 726 | if (p.up(t, this.i)) { 727 | var a = p.vals; 728 | var l = a.length; 729 | var b = Array(l); 730 | for (var i = 0; i < l; ++i) 731 | b[i] = a[i]; 732 | out._n(b); 733 | } 734 | }; 735 | CombineListener.prototype._e = function (err) { 736 | var out = this.out; 737 | if (out === NO) 738 | return; 739 | out._e(err); 740 | }; 741 | CombineListener.prototype._c = function () { 742 | var p = this.p; 743 | if (p.out === NO) 744 | return; 745 | if (--p.Nc === 0) 746 | p.out._c(); 747 | }; 748 | return CombineListener; 749 | }()); 750 | var Combine = (function () { 751 | function Combine(insArr) { 752 | this.type = 'combine'; 753 | this.insArr = insArr; 754 | this.out = NO; 755 | this.ils = []; 756 | this.Nc = this.Nn = 0; 757 | this.vals = []; 758 | } 759 | Combine.prototype.up = function (t, i) { 760 | var v = this.vals[i]; 761 | var Nn = !this.Nn ? 0 : v === NO ? --this.Nn : this.Nn; 762 | this.vals[i] = t; 763 | return Nn === 0; 764 | }; 765 | Combine.prototype._start = function (out) { 766 | this.out = out; 767 | var s = this.insArr; 768 | var n = this.Nc = this.Nn = s.length; 769 | var vals = this.vals = new Array(n); 770 | if (n === 0) { 771 | out._n([]); 772 | out._c(); 773 | } 774 | else { 775 | for (var i = 0; i < n; i++) { 776 | vals[i] = NO; 777 | s[i]._add(new CombineListener(i, out, this)); 778 | } 779 | } 780 | }; 781 | Combine.prototype._stop = function () { 782 | var s = this.insArr; 783 | var n = s.length; 784 | var ils = this.ils; 785 | for (var i = 0; i < n; i++) 786 | s[i]._remove(ils[i]); 787 | this.out = NO; 788 | this.ils = []; 789 | this.vals = []; 790 | }; 791 | return Combine; 792 | }()); 793 | var FromArray = (function () { 794 | function FromArray(a) { 795 | this.type = 'fromArray'; 796 | this.a = a; 797 | } 798 | FromArray.prototype._start = function (out) { 799 | var a = this.a; 800 | for (var i = 0, n = a.length; i < n; i++) 801 | out._n(a[i]); 802 | out._c(); 803 | }; 804 | FromArray.prototype._stop = function () { 805 | }; 806 | return FromArray; 807 | }()); 808 | var FromPromise = (function () { 809 | function FromPromise(p) { 810 | this.type = 'fromPromise'; 811 | this.on = false; 812 | this.p = p; 813 | } 814 | FromPromise.prototype._start = function (out) { 815 | var prod = this; 816 | this.on = true; 817 | this.p.then(function (v) { 818 | if (prod.on) { 819 | out._n(v); 820 | out._c(); 821 | } 822 | }, function (e) { 823 | out._e(e); 824 | }).then(noop, function (err) { 825 | setTimeout(function () { throw err; }); 826 | }); 827 | }; 828 | FromPromise.prototype._stop = function () { 829 | this.on = false; 830 | }; 831 | return FromPromise; 832 | }()); 833 | var Periodic = (function () { 834 | function Periodic(period) { 835 | this.type = 'periodic'; 836 | this.period = period; 837 | this.intervalID = -1; 838 | this.i = 0; 839 | } 840 | Periodic.prototype._start = function (out) { 841 | var self = this; 842 | function intervalHandler() { out._n(self.i++); } 843 | this.intervalID = setInterval(intervalHandler, this.period); 844 | }; 845 | Periodic.prototype._stop = function () { 846 | if (this.intervalID !== -1) 847 | clearInterval(this.intervalID); 848 | this.intervalID = -1; 849 | this.i = 0; 850 | }; 851 | return Periodic; 852 | }()); 853 | var Debug = (function () { 854 | function Debug(ins, arg) { 855 | this.type = 'debug'; 856 | this.ins = ins; 857 | this.out = NO; 858 | this.s = noop; 859 | this.l = ''; 860 | if (typeof arg === 'string') 861 | this.l = arg; 862 | else if (typeof arg === 'function') 863 | this.s = arg; 864 | } 865 | Debug.prototype._start = function (out) { 866 | this.out = out; 867 | this.ins._add(this); 868 | }; 869 | Debug.prototype._stop = function () { 870 | this.ins._remove(this); 871 | this.out = NO; 872 | }; 873 | Debug.prototype._n = function (t) { 874 | var u = this.out; 875 | if (u === NO) 876 | return; 877 | var s = this.s, l = this.l; 878 | if (s !== noop) { 879 | try { 880 | s(t); 881 | } 882 | catch (e) { 883 | u._e(e); 884 | } 885 | } 886 | else if (l) 887 | console.log(l + ':', t); 888 | else 889 | console.log(t); 890 | u._n(t); 891 | }; 892 | Debug.prototype._e = function (err) { 893 | var u = this.out; 894 | if (u === NO) 895 | return; 896 | u._e(err); 897 | }; 898 | Debug.prototype._c = function () { 899 | var u = this.out; 900 | if (u === NO) 901 | return; 902 | u._c(); 903 | }; 904 | return Debug; 905 | }()); 906 | var Drop = (function () { 907 | function Drop(max, ins) { 908 | this.type = 'drop'; 909 | this.ins = ins; 910 | this.out = NO; 911 | this.max = max; 912 | this.dropped = 0; 913 | } 914 | Drop.prototype._start = function (out) { 915 | this.out = out; 916 | this.dropped = 0; 917 | this.ins._add(this); 918 | }; 919 | Drop.prototype._stop = function () { 920 | this.ins._remove(this); 921 | this.out = NO; 922 | }; 923 | Drop.prototype._n = function (t) { 924 | var u = this.out; 925 | if (u === NO) 926 | return; 927 | if (this.dropped++ >= this.max) 928 | u._n(t); 929 | }; 930 | Drop.prototype._e = function (err) { 931 | var u = this.out; 932 | if (u === NO) 933 | return; 934 | u._e(err); 935 | }; 936 | Drop.prototype._c = function () { 937 | var u = this.out; 938 | if (u === NO) 939 | return; 940 | u._c(); 941 | }; 942 | return Drop; 943 | }()); 944 | var EndWhenListener = (function () { 945 | function EndWhenListener(out, op) { 946 | this.out = out; 947 | this.op = op; 948 | } 949 | EndWhenListener.prototype._n = function () { 950 | this.op.end(); 951 | }; 952 | EndWhenListener.prototype._e = function (err) { 953 | this.out._e(err); 954 | }; 955 | EndWhenListener.prototype._c = function () { 956 | this.op.end(); 957 | }; 958 | return EndWhenListener; 959 | }()); 960 | var EndWhen = (function () { 961 | function EndWhen(o, ins) { 962 | this.type = 'endWhen'; 963 | this.ins = ins; 964 | this.out = NO; 965 | this.o = o; 966 | this.oil = NO_IL; 967 | } 968 | EndWhen.prototype._start = function (out) { 969 | this.out = out; 970 | this.o._add(this.oil = new EndWhenListener(out, this)); 971 | this.ins._add(this); 972 | }; 973 | EndWhen.prototype._stop = function () { 974 | this.ins._remove(this); 975 | this.o._remove(this.oil); 976 | this.out = NO; 977 | this.oil = NO_IL; 978 | }; 979 | EndWhen.prototype.end = function () { 980 | var u = this.out; 981 | if (u === NO) 982 | return; 983 | u._c(); 984 | }; 985 | EndWhen.prototype._n = function (t) { 986 | var u = this.out; 987 | if (u === NO) 988 | return; 989 | u._n(t); 990 | }; 991 | EndWhen.prototype._e = function (err) { 992 | var u = this.out; 993 | if (u === NO) 994 | return; 995 | u._e(err); 996 | }; 997 | EndWhen.prototype._c = function () { 998 | this.end(); 999 | }; 1000 | return EndWhen; 1001 | }()); 1002 | var Filter = (function () { 1003 | function Filter(passes, ins) { 1004 | this.type = 'filter'; 1005 | this.ins = ins; 1006 | this.out = NO; 1007 | this.f = passes; 1008 | } 1009 | Filter.prototype._start = function (out) { 1010 | this.out = out; 1011 | this.ins._add(this); 1012 | }; 1013 | Filter.prototype._stop = function () { 1014 | this.ins._remove(this); 1015 | this.out = NO; 1016 | }; 1017 | Filter.prototype._n = function (t) { 1018 | var u = this.out; 1019 | if (u === NO) 1020 | return; 1021 | var r = _try(this, t, u); 1022 | if (r === NO || !r) 1023 | return; 1024 | u._n(t); 1025 | }; 1026 | Filter.prototype._e = function (err) { 1027 | var u = this.out; 1028 | if (u === NO) 1029 | return; 1030 | u._e(err); 1031 | }; 1032 | Filter.prototype._c = function () { 1033 | var u = this.out; 1034 | if (u === NO) 1035 | return; 1036 | u._c(); 1037 | }; 1038 | return Filter; 1039 | }()); 1040 | var FlattenListener = (function () { 1041 | function FlattenListener(out, op) { 1042 | this.out = out; 1043 | this.op = op; 1044 | } 1045 | FlattenListener.prototype._n = function (t) { 1046 | this.out._n(t); 1047 | }; 1048 | FlattenListener.prototype._e = function (err) { 1049 | this.out._e(err); 1050 | }; 1051 | FlattenListener.prototype._c = function () { 1052 | this.op.inner = NO; 1053 | this.op.less(); 1054 | }; 1055 | return FlattenListener; 1056 | }()); 1057 | var Flatten = (function () { 1058 | function Flatten(ins) { 1059 | this.type = 'flatten'; 1060 | this.ins = ins; 1061 | this.out = NO; 1062 | this.open = true; 1063 | this.inner = NO; 1064 | this.il = NO_IL; 1065 | } 1066 | Flatten.prototype._start = function (out) { 1067 | this.out = out; 1068 | this.open = true; 1069 | this.inner = NO; 1070 | this.il = NO_IL; 1071 | this.ins._add(this); 1072 | }; 1073 | Flatten.prototype._stop = function () { 1074 | this.ins._remove(this); 1075 | if (this.inner !== NO) 1076 | this.inner._remove(this.il); 1077 | this.out = NO; 1078 | this.open = true; 1079 | this.inner = NO; 1080 | this.il = NO_IL; 1081 | }; 1082 | Flatten.prototype.less = function () { 1083 | var u = this.out; 1084 | if (u === NO) 1085 | return; 1086 | if (!this.open && this.inner === NO) 1087 | u._c(); 1088 | }; 1089 | Flatten.prototype._n = function (s) { 1090 | var u = this.out; 1091 | if (u === NO) 1092 | return; 1093 | var _a = this, inner = _a.inner, il = _a.il; 1094 | if (inner !== NO && il !== NO_IL) 1095 | inner._remove(il); 1096 | (this.inner = s)._add(this.il = new FlattenListener(u, this)); 1097 | }; 1098 | Flatten.prototype._e = function (err) { 1099 | var u = this.out; 1100 | if (u === NO) 1101 | return; 1102 | u._e(err); 1103 | }; 1104 | Flatten.prototype._c = function () { 1105 | this.open = false; 1106 | this.less(); 1107 | }; 1108 | return Flatten; 1109 | }()); 1110 | var Fold = (function () { 1111 | function Fold(f, seed, ins) { 1112 | var _this = this; 1113 | this.type = 'fold'; 1114 | this.ins = ins; 1115 | this.out = NO; 1116 | this.f = function (t) { return f(_this.acc, t); }; 1117 | this.acc = this.seed = seed; 1118 | } 1119 | Fold.prototype._start = function (out) { 1120 | this.out = out; 1121 | this.acc = this.seed; 1122 | out._n(this.acc); 1123 | this.ins._add(this); 1124 | }; 1125 | Fold.prototype._stop = function () { 1126 | this.ins._remove(this); 1127 | this.out = NO; 1128 | this.acc = this.seed; 1129 | }; 1130 | Fold.prototype._n = function (t) { 1131 | var u = this.out; 1132 | if (u === NO) 1133 | return; 1134 | var r = _try(this, t, u); 1135 | if (r === NO) 1136 | return; 1137 | u._n(this.acc = r); 1138 | }; 1139 | Fold.prototype._e = function (err) { 1140 | var u = this.out; 1141 | if (u === NO) 1142 | return; 1143 | u._e(err); 1144 | }; 1145 | Fold.prototype._c = function () { 1146 | var u = this.out; 1147 | if (u === NO) 1148 | return; 1149 | u._c(); 1150 | }; 1151 | return Fold; 1152 | }()); 1153 | var Last = (function () { 1154 | function Last(ins) { 1155 | this.type = 'last'; 1156 | this.ins = ins; 1157 | this.out = NO; 1158 | this.has = false; 1159 | this.val = NO; 1160 | } 1161 | Last.prototype._start = function (out) { 1162 | this.out = out; 1163 | this.has = false; 1164 | this.ins._add(this); 1165 | }; 1166 | Last.prototype._stop = function () { 1167 | this.ins._remove(this); 1168 | this.out = NO; 1169 | this.val = NO; 1170 | }; 1171 | Last.prototype._n = function (t) { 1172 | this.has = true; 1173 | this.val = t; 1174 | }; 1175 | Last.prototype._e = function (err) { 1176 | var u = this.out; 1177 | if (u === NO) 1178 | return; 1179 | u._e(err); 1180 | }; 1181 | Last.prototype._c = function () { 1182 | var u = this.out; 1183 | if (u === NO) 1184 | return; 1185 | if (this.has) { 1186 | u._n(this.val); 1187 | u._c(); 1188 | } 1189 | else 1190 | u._e(new Error('last() failed because input stream completed')); 1191 | }; 1192 | return Last; 1193 | }()); 1194 | var MapOp = (function () { 1195 | function MapOp(project, ins) { 1196 | this.type = 'map'; 1197 | this.ins = ins; 1198 | this.out = NO; 1199 | this.f = project; 1200 | } 1201 | MapOp.prototype._start = function (out) { 1202 | this.out = out; 1203 | this.ins._add(this); 1204 | }; 1205 | MapOp.prototype._stop = function () { 1206 | this.ins._remove(this); 1207 | this.out = NO; 1208 | }; 1209 | MapOp.prototype._n = function (t) { 1210 | var u = this.out; 1211 | if (u === NO) 1212 | return; 1213 | var r = _try(this, t, u); 1214 | if (r === NO) 1215 | return; 1216 | u._n(r); 1217 | }; 1218 | MapOp.prototype._e = function (err) { 1219 | var u = this.out; 1220 | if (u === NO) 1221 | return; 1222 | u._e(err); 1223 | }; 1224 | MapOp.prototype._c = function () { 1225 | var u = this.out; 1226 | if (u === NO) 1227 | return; 1228 | u._c(); 1229 | }; 1230 | return MapOp; 1231 | }()); 1232 | var Remember = (function () { 1233 | function Remember(ins) { 1234 | this.type = 'remember'; 1235 | this.ins = ins; 1236 | this.out = NO; 1237 | } 1238 | Remember.prototype._start = function (out) { 1239 | this.out = out; 1240 | this.ins._add(out); 1241 | }; 1242 | Remember.prototype._stop = function () { 1243 | this.ins._remove(this.out); 1244 | this.out = NO; 1245 | }; 1246 | return Remember; 1247 | }()); 1248 | var ReplaceError = (function () { 1249 | function ReplaceError(replacer, ins) { 1250 | this.type = 'replaceError'; 1251 | this.ins = ins; 1252 | this.out = NO; 1253 | this.f = replacer; 1254 | } 1255 | ReplaceError.prototype._start = function (out) { 1256 | this.out = out; 1257 | this.ins._add(this); 1258 | }; 1259 | ReplaceError.prototype._stop = function () { 1260 | this.ins._remove(this); 1261 | this.out = NO; 1262 | }; 1263 | ReplaceError.prototype._n = function (t) { 1264 | var u = this.out; 1265 | if (u === NO) 1266 | return; 1267 | u._n(t); 1268 | }; 1269 | ReplaceError.prototype._e = function (err) { 1270 | var u = this.out; 1271 | if (u === NO) 1272 | return; 1273 | try { 1274 | this.ins._remove(this); 1275 | (this.ins = this.f(err))._add(this); 1276 | } 1277 | catch (e) { 1278 | u._e(e); 1279 | } 1280 | }; 1281 | ReplaceError.prototype._c = function () { 1282 | var u = this.out; 1283 | if (u === NO) 1284 | return; 1285 | u._c(); 1286 | }; 1287 | return ReplaceError; 1288 | }()); 1289 | var StartWith = (function () { 1290 | function StartWith(ins, val) { 1291 | this.type = 'startWith'; 1292 | this.ins = ins; 1293 | this.out = NO; 1294 | this.val = val; 1295 | } 1296 | StartWith.prototype._start = function (out) { 1297 | this.out = out; 1298 | this.out._n(this.val); 1299 | this.ins._add(out); 1300 | }; 1301 | StartWith.prototype._stop = function () { 1302 | this.ins._remove(this.out); 1303 | this.out = NO; 1304 | }; 1305 | return StartWith; 1306 | }()); 1307 | var Take = (function () { 1308 | function Take(max, ins) { 1309 | this.type = 'take'; 1310 | this.ins = ins; 1311 | this.out = NO; 1312 | this.max = max; 1313 | this.taken = 0; 1314 | } 1315 | Take.prototype._start = function (out) { 1316 | this.out = out; 1317 | this.taken = 0; 1318 | if (this.max <= 0) 1319 | out._c(); 1320 | else 1321 | this.ins._add(this); 1322 | }; 1323 | Take.prototype._stop = function () { 1324 | this.ins._remove(this); 1325 | this.out = NO; 1326 | }; 1327 | Take.prototype._n = function (t) { 1328 | var u = this.out; 1329 | if (u === NO) 1330 | return; 1331 | var m = ++this.taken; 1332 | if (m < this.max) 1333 | u._n(t); 1334 | else if (m === this.max) { 1335 | u._n(t); 1336 | u._c(); 1337 | } 1338 | }; 1339 | Take.prototype._e = function (err) { 1340 | var u = this.out; 1341 | if (u === NO) 1342 | return; 1343 | u._e(err); 1344 | }; 1345 | Take.prototype._c = function () { 1346 | var u = this.out; 1347 | if (u === NO) 1348 | return; 1349 | u._c(); 1350 | }; 1351 | return Take; 1352 | }()); 1353 | var Stream = (function () { 1354 | function Stream(producer) { 1355 | this._prod = producer || NO; 1356 | this._ils = []; 1357 | this._stopID = NO; 1358 | this._dl = NO; 1359 | this._d = false; 1360 | this._target = NO; 1361 | this._err = NO; 1362 | } 1363 | Stream.prototype._n = function (t) { 1364 | var a = this._ils; 1365 | var L = a.length; 1366 | if (this._d) 1367 | this._dl._n(t); 1368 | if (L == 1) 1369 | a[0]._n(t); 1370 | else if (L == 0) 1371 | return; 1372 | else { 1373 | var b = cp(a); 1374 | for (var i = 0; i < L; i++) 1375 | b[i]._n(t); 1376 | } 1377 | }; 1378 | Stream.prototype._e = function (err) { 1379 | if (this._err !== NO) 1380 | return; 1381 | this._err = err; 1382 | var a = this._ils; 1383 | var L = a.length; 1384 | this._x(); 1385 | if (this._d) 1386 | this._dl._e(err); 1387 | if (L == 1) 1388 | a[0]._e(err); 1389 | else if (L == 0) 1390 | return; 1391 | else { 1392 | var b = cp(a); 1393 | for (var i = 0; i < L; i++) 1394 | b[i]._e(err); 1395 | } 1396 | if (!this._d && L == 0) 1397 | throw this._err; 1398 | }; 1399 | Stream.prototype._c = function () { 1400 | var a = this._ils; 1401 | var L = a.length; 1402 | this._x(); 1403 | if (this._d) 1404 | this._dl._c(); 1405 | if (L == 1) 1406 | a[0]._c(); 1407 | else if (L == 0) 1408 | return; 1409 | else { 1410 | var b = cp(a); 1411 | for (var i = 0; i < L; i++) 1412 | b[i]._c(); 1413 | } 1414 | }; 1415 | Stream.prototype._x = function () { 1416 | if (this._ils.length === 0) 1417 | return; 1418 | if (this._prod !== NO) 1419 | this._prod._stop(); 1420 | this._err = NO; 1421 | this._ils = []; 1422 | }; 1423 | Stream.prototype._stopNow = function () { 1424 | // WARNING: code that calls this method should 1425 | // first check if this._prod is valid (not `NO`) 1426 | this._prod._stop(); 1427 | this._err = NO; 1428 | this._stopID = NO; 1429 | }; 1430 | Stream.prototype._add = function (il) { 1431 | var ta = this._target; 1432 | if (ta !== NO) 1433 | return ta._add(il); 1434 | var a = this._ils; 1435 | a.push(il); 1436 | if (a.length > 1) 1437 | return; 1438 | if (this._stopID !== NO) { 1439 | clearTimeout(this._stopID); 1440 | this._stopID = NO; 1441 | } 1442 | else { 1443 | var p = this._prod; 1444 | if (p !== NO) 1445 | p._start(this); 1446 | } 1447 | }; 1448 | Stream.prototype._remove = function (il) { 1449 | var _this = this; 1450 | var ta = this._target; 1451 | if (ta !== NO) 1452 | return ta._remove(il); 1453 | var a = this._ils; 1454 | var i = a.indexOf(il); 1455 | if (i > -1) { 1456 | a.splice(i, 1); 1457 | if (this._prod !== NO && a.length <= 0) { 1458 | this._err = NO; 1459 | this._stopID = setTimeout(function () { return _this._stopNow(); }); 1460 | } 1461 | else if (a.length === 1) { 1462 | this._pruneCycles(); 1463 | } 1464 | } 1465 | }; 1466 | // If all paths stemming from `this` stream eventually end at `this` 1467 | // stream, then we remove the single listener of `this` stream, to 1468 | // force it to end its execution and dispose resources. This method 1469 | // assumes as a precondition that this._ils has just one listener. 1470 | Stream.prototype._pruneCycles = function () { 1471 | if (this._hasNoSinks(this, [])) 1472 | this._remove(this._ils[0]); 1473 | }; 1474 | // Checks whether *there is no* path starting from `x` that leads to an end 1475 | // listener (sink) in the stream graph, following edges A->B where B is a 1476 | // listener of A. This means these paths constitute a cycle somehow. Is given 1477 | // a trace of all visited nodes so far. 1478 | Stream.prototype._hasNoSinks = function (x, trace) { 1479 | if (trace.indexOf(x) !== -1) 1480 | return true; 1481 | else if (x.out === this) 1482 | return true; 1483 | else if (x.out && x.out !== NO) 1484 | return this._hasNoSinks(x.out, trace.concat(x)); 1485 | else if (x._ils) { 1486 | for (var i = 0, N = x._ils.length; i < N; i++) 1487 | if (!this._hasNoSinks(x._ils[i], trace.concat(x))) 1488 | return false; 1489 | return true; 1490 | } 1491 | else 1492 | return false; 1493 | }; 1494 | Stream.prototype.ctor = function () { 1495 | return this instanceof MemoryStream ? MemoryStream : Stream; 1496 | }; 1497 | /** 1498 | * Adds a Listener to the Stream. 1499 | * 1500 | * @param {Listener} listener 1501 | */ 1502 | Stream.prototype.addListener = function (listener) { 1503 | listener._n = listener.next || noop; 1504 | listener._e = listener.error || noop; 1505 | listener._c = listener.complete || noop; 1506 | this._add(listener); 1507 | }; 1508 | /** 1509 | * Removes a Listener from the Stream, assuming the Listener was added to it. 1510 | * 1511 | * @param {Listener} listener 1512 | */ 1513 | Stream.prototype.removeListener = function (listener) { 1514 | this._remove(listener); 1515 | }; 1516 | /** 1517 | * Adds a Listener to the Stream returning a Subscription to remove that 1518 | * listener. 1519 | * 1520 | * @param {Listener} listener 1521 | * @returns {Subscription} 1522 | */ 1523 | Stream.prototype.subscribe = function (listener) { 1524 | this.addListener(listener); 1525 | return new StreamSub(this, listener); 1526 | }; 1527 | /** 1528 | * Add interop between most.js and RxJS 5 1529 | * 1530 | * @returns {Stream} 1531 | */ 1532 | Stream.prototype[symbol_observable_1.default] = function () { 1533 | return this; 1534 | }; 1535 | /** 1536 | * Creates a new Stream given a Producer. 1537 | * 1538 | * @factory true 1539 | * @param {Producer} producer An optional Producer that dictates how to 1540 | * start, generate events, and stop the Stream. 1541 | * @return {Stream} 1542 | */ 1543 | Stream.create = function (producer) { 1544 | if (producer) { 1545 | if (typeof producer.start !== 'function' 1546 | || typeof producer.stop !== 'function') 1547 | throw new Error('producer requires both start and stop functions'); 1548 | internalizeProducer(producer); // mutates the input 1549 | } 1550 | return new Stream(producer); 1551 | }; 1552 | /** 1553 | * Creates a new MemoryStream given a Producer. 1554 | * 1555 | * @factory true 1556 | * @param {Producer} producer An optional Producer that dictates how to 1557 | * start, generate events, and stop the Stream. 1558 | * @return {MemoryStream} 1559 | */ 1560 | Stream.createWithMemory = function (producer) { 1561 | if (producer) 1562 | internalizeProducer(producer); // mutates the input 1563 | return new MemoryStream(producer); 1564 | }; 1565 | /** 1566 | * Creates a Stream that does nothing when started. It never emits any event. 1567 | * 1568 | * Marble diagram: 1569 | * 1570 | * ```text 1571 | * never 1572 | * ----------------------- 1573 | * ``` 1574 | * 1575 | * @factory true 1576 | * @return {Stream} 1577 | */ 1578 | Stream.never = function () { 1579 | return new Stream({ _start: noop, _stop: noop }); 1580 | }; 1581 | /** 1582 | * Creates a Stream that immediately emits the "complete" notification when 1583 | * started, and that's it. 1584 | * 1585 | * Marble diagram: 1586 | * 1587 | * ```text 1588 | * empty 1589 | * -| 1590 | * ``` 1591 | * 1592 | * @factory true 1593 | * @return {Stream} 1594 | */ 1595 | Stream.empty = function () { 1596 | return new Stream({ 1597 | _start: function (il) { il._c(); }, 1598 | _stop: noop, 1599 | }); 1600 | }; 1601 | /** 1602 | * Creates a Stream that immediately emits an "error" notification with the 1603 | * value you passed as the `error` argument when the stream starts, and that's 1604 | * it. 1605 | * 1606 | * Marble diagram: 1607 | * 1608 | * ```text 1609 | * throw(X) 1610 | * -X 1611 | * ``` 1612 | * 1613 | * @factory true 1614 | * @param error The error event to emit on the created stream. 1615 | * @return {Stream} 1616 | */ 1617 | Stream.throw = function (error) { 1618 | return new Stream({ 1619 | _start: function (il) { il._e(error); }, 1620 | _stop: noop, 1621 | }); 1622 | }; 1623 | /** 1624 | * Creates a stream from an Array, Promise, or an Observable. 1625 | * 1626 | * @factory true 1627 | * @param {Array|PromiseLike|Observable} input The input to make a stream from. 1628 | * @return {Stream} 1629 | */ 1630 | Stream.from = function (input) { 1631 | if (typeof input[symbol_observable_1.default] === 'function') 1632 | return Stream.fromObservable(input); 1633 | else if (typeof input.then === 'function') 1634 | return Stream.fromPromise(input); 1635 | else if (Array.isArray(input)) 1636 | return Stream.fromArray(input); 1637 | throw new TypeError("Type of input to from() must be an Array, Promise, or Observable"); 1638 | }; 1639 | /** 1640 | * Creates a Stream that immediately emits the arguments that you give to 1641 | * *of*, then completes. 1642 | * 1643 | * Marble diagram: 1644 | * 1645 | * ```text 1646 | * of(1,2,3) 1647 | * 123| 1648 | * ``` 1649 | * 1650 | * @factory true 1651 | * @param a The first value you want to emit as an event on the stream. 1652 | * @param b The second value you want to emit as an event on the stream. One 1653 | * or more of these values may be given as arguments. 1654 | * @return {Stream} 1655 | */ 1656 | Stream.of = function () { 1657 | var items = []; 1658 | for (var _i = 0; _i < arguments.length; _i++) { 1659 | items[_i] = arguments[_i]; 1660 | } 1661 | return Stream.fromArray(items); 1662 | }; 1663 | /** 1664 | * Converts an array to a stream. The returned stream will emit synchronously 1665 | * all the items in the array, and then complete. 1666 | * 1667 | * Marble diagram: 1668 | * 1669 | * ```text 1670 | * fromArray([1,2,3]) 1671 | * 123| 1672 | * ``` 1673 | * 1674 | * @factory true 1675 | * @param {Array} array The array to be converted as a stream. 1676 | * @return {Stream} 1677 | */ 1678 | Stream.fromArray = function (array) { 1679 | return new Stream(new FromArray(array)); 1680 | }; 1681 | /** 1682 | * Converts a promise to a stream. The returned stream will emit the resolved 1683 | * value of the promise, and then complete. However, if the promise is 1684 | * rejected, the stream will emit the corresponding error. 1685 | * 1686 | * Marble diagram: 1687 | * 1688 | * ```text 1689 | * fromPromise( ----42 ) 1690 | * -----------------42| 1691 | * ``` 1692 | * 1693 | * @factory true 1694 | * @param {PromiseLike} promise The promise to be converted as a stream. 1695 | * @return {Stream} 1696 | */ 1697 | Stream.fromPromise = function (promise) { 1698 | return new Stream(new FromPromise(promise)); 1699 | }; 1700 | /** 1701 | * Converts an Observable into a Stream. 1702 | * 1703 | * @factory true 1704 | * @param {any} observable The observable to be converted as a stream. 1705 | * @return {Stream} 1706 | */ 1707 | Stream.fromObservable = function (obs) { 1708 | if (obs.endWhen) 1709 | return obs; 1710 | return new Stream(new FromObservable(obs)); 1711 | }; 1712 | /** 1713 | * Creates a stream that periodically emits incremental numbers, every 1714 | * `period` milliseconds. 1715 | * 1716 | * Marble diagram: 1717 | * 1718 | * ```text 1719 | * periodic(1000) 1720 | * ---0---1---2---3---4---... 1721 | * ``` 1722 | * 1723 | * @factory true 1724 | * @param {number} period The interval in milliseconds to use as a rate of 1725 | * emission. 1726 | * @return {Stream} 1727 | */ 1728 | Stream.periodic = function (period) { 1729 | return new Stream(new Periodic(period)); 1730 | }; 1731 | Stream.prototype._map = function (project) { 1732 | return new (this.ctor())(new MapOp(project, this)); 1733 | }; 1734 | /** 1735 | * Transforms each event from the input Stream through a `project` function, 1736 | * to get a Stream that emits those transformed events. 1737 | * 1738 | * Marble diagram: 1739 | * 1740 | * ```text 1741 | * --1---3--5-----7------ 1742 | * map(i => i * 10) 1743 | * --10--30-50----70----- 1744 | * ``` 1745 | * 1746 | * @param {Function} project A function of type `(t: T) => U` that takes event 1747 | * `t` of type `T` from the input Stream and produces an event of type `U`, to 1748 | * be emitted on the output Stream. 1749 | * @return {Stream} 1750 | */ 1751 | Stream.prototype.map = function (project) { 1752 | return this._map(project); 1753 | }; 1754 | /** 1755 | * It's like `map`, but transforms each input event to always the same 1756 | * constant value on the output Stream. 1757 | * 1758 | * Marble diagram: 1759 | * 1760 | * ```text 1761 | * --1---3--5-----7----- 1762 | * mapTo(10) 1763 | * --10--10-10----10---- 1764 | * ``` 1765 | * 1766 | * @param projectedValue A value to emit on the output Stream whenever the 1767 | * input Stream emits any value. 1768 | * @return {Stream} 1769 | */ 1770 | Stream.prototype.mapTo = function (projectedValue) { 1771 | var s = this.map(function () { return projectedValue; }); 1772 | var op = s._prod; 1773 | op.type = 'mapTo'; 1774 | return s; 1775 | }; 1776 | /** 1777 | * Only allows events that pass the test given by the `passes` argument. 1778 | * 1779 | * Each event from the input stream is given to the `passes` function. If the 1780 | * function returns `true`, the event is forwarded to the output stream, 1781 | * otherwise it is ignored and not forwarded. 1782 | * 1783 | * Marble diagram: 1784 | * 1785 | * ```text 1786 | * --1---2--3-----4-----5---6--7-8-- 1787 | * filter(i => i % 2 === 0) 1788 | * ------2--------4---------6----8-- 1789 | * ``` 1790 | * 1791 | * @param {Function} passes A function of type `(t: T) +> boolean` that takes 1792 | * an event from the input stream and checks if it passes, by returning a 1793 | * boolean. 1794 | * @return {Stream} 1795 | */ 1796 | Stream.prototype.filter = function (passes) { 1797 | var p = this._prod; 1798 | if (p instanceof Filter) 1799 | return new Stream(new Filter(and(p.f, passes), p.ins)); 1800 | return new Stream(new Filter(passes, this)); 1801 | }; 1802 | /** 1803 | * Lets the first `amount` many events from the input stream pass to the 1804 | * output stream, then makes the output stream complete. 1805 | * 1806 | * Marble diagram: 1807 | * 1808 | * ```text 1809 | * --a---b--c----d---e-- 1810 | * take(3) 1811 | * --a---b--c| 1812 | * ``` 1813 | * 1814 | * @param {number} amount How many events to allow from the input stream 1815 | * before completing the output stream. 1816 | * @return {Stream} 1817 | */ 1818 | Stream.prototype.take = function (amount) { 1819 | return new (this.ctor())(new Take(amount, this)); 1820 | }; 1821 | /** 1822 | * Ignores the first `amount` many events from the input stream, and then 1823 | * after that starts forwarding events from the input stream to the output 1824 | * stream. 1825 | * 1826 | * Marble diagram: 1827 | * 1828 | * ```text 1829 | * --a---b--c----d---e-- 1830 | * drop(3) 1831 | * --------------d---e-- 1832 | * ``` 1833 | * 1834 | * @param {number} amount How many events to ignore from the input stream 1835 | * before forwarding all events from the input stream to the output stream. 1836 | * @return {Stream} 1837 | */ 1838 | Stream.prototype.drop = function (amount) { 1839 | return new Stream(new Drop(amount, this)); 1840 | }; 1841 | /** 1842 | * When the input stream completes, the output stream will emit the last event 1843 | * emitted by the input stream, and then will also complete. 1844 | * 1845 | * Marble diagram: 1846 | * 1847 | * ```text 1848 | * --a---b--c--d----| 1849 | * last() 1850 | * -----------------d| 1851 | * ``` 1852 | * 1853 | * @return {Stream} 1854 | */ 1855 | Stream.prototype.last = function () { 1856 | return new Stream(new Last(this)); 1857 | }; 1858 | /** 1859 | * Prepends the given `initial` value to the sequence of events emitted by the 1860 | * input stream. The returned stream is a MemoryStream, which means it is 1861 | * already `remember()`'d. 1862 | * 1863 | * Marble diagram: 1864 | * 1865 | * ```text 1866 | * ---1---2-----3--- 1867 | * startWith(0) 1868 | * 0--1---2-----3--- 1869 | * ``` 1870 | * 1871 | * @param initial The value or event to prepend. 1872 | * @return {MemoryStream} 1873 | */ 1874 | Stream.prototype.startWith = function (initial) { 1875 | return new MemoryStream(new StartWith(this, initial)); 1876 | }; 1877 | /** 1878 | * Uses another stream to determine when to complete the current stream. 1879 | * 1880 | * When the given `other` stream emits an event or completes, the output 1881 | * stream will complete. Before that happens, the output stream will behaves 1882 | * like the input stream. 1883 | * 1884 | * Marble diagram: 1885 | * 1886 | * ```text 1887 | * ---1---2-----3--4----5----6--- 1888 | * endWhen( --------a--b--| ) 1889 | * ---1---2-----3--4--| 1890 | * ``` 1891 | * 1892 | * @param other Some other stream that is used to know when should the output 1893 | * stream of this operator complete. 1894 | * @return {Stream} 1895 | */ 1896 | Stream.prototype.endWhen = function (other) { 1897 | return new (this.ctor())(new EndWhen(other, this)); 1898 | }; 1899 | /** 1900 | * "Folds" the stream onto itself. 1901 | * 1902 | * Combines events from the past throughout 1903 | * the entire execution of the input stream, allowing you to accumulate them 1904 | * together. It's essentially like `Array.prototype.reduce`. The returned 1905 | * stream is a MemoryStream, which means it is already `remember()`'d. 1906 | * 1907 | * The output stream starts by emitting the `seed` which you give as argument. 1908 | * Then, when an event happens on the input stream, it is combined with that 1909 | * seed value through the `accumulate` function, and the output value is 1910 | * emitted on the output stream. `fold` remembers that output value as `acc` 1911 | * ("accumulator"), and then when a new input event `t` happens, `acc` will be 1912 | * combined with that to produce the new `acc` and so forth. 1913 | * 1914 | * Marble diagram: 1915 | * 1916 | * ```text 1917 | * ------1-----1--2----1----1------ 1918 | * fold((acc, x) => acc + x, 3) 1919 | * 3-----4-----5--7----8----9------ 1920 | * ``` 1921 | * 1922 | * @param {Function} accumulate A function of type `(acc: R, t: T) => R` that 1923 | * takes the previous accumulated value `acc` and the incoming event from the 1924 | * input stream and produces the new accumulated value. 1925 | * @param seed The initial accumulated value, of type `R`. 1926 | * @return {MemoryStream} 1927 | */ 1928 | Stream.prototype.fold = function (accumulate, seed) { 1929 | return new MemoryStream(new Fold(accumulate, seed, this)); 1930 | }; 1931 | /** 1932 | * Replaces an error with another stream. 1933 | * 1934 | * When (and if) an error happens on the input stream, instead of forwarding 1935 | * that error to the output stream, *replaceError* will call the `replace` 1936 | * function which returns the stream that the output stream will replicate. 1937 | * And, in case that new stream also emits an error, `replace` will be called 1938 | * again to get another stream to start replicating. 1939 | * 1940 | * Marble diagram: 1941 | * 1942 | * ```text 1943 | * --1---2-----3--4-----X 1944 | * replaceError( () => --10--| ) 1945 | * --1---2-----3--4--------10--| 1946 | * ``` 1947 | * 1948 | * @param {Function} replace A function of type `(err) => Stream` that takes 1949 | * the error that occurred on the input stream or on the previous replacement 1950 | * stream and returns a new stream. The output stream will behave like the 1951 | * stream that this function returns. 1952 | * @return {Stream} 1953 | */ 1954 | Stream.prototype.replaceError = function (replace) { 1955 | return new (this.ctor())(new ReplaceError(replace, this)); 1956 | }; 1957 | /** 1958 | * Flattens a "stream of streams", handling only one nested stream at a time 1959 | * (no concurrency). 1960 | * 1961 | * If the input stream is a stream that emits streams, then this operator will 1962 | * return an output stream which is a flat stream: emits regular events. The 1963 | * flattening happens without concurrency. It works like this: when the input 1964 | * stream emits a nested stream, *flatten* will start imitating that nested 1965 | * one. However, as soon as the next nested stream is emitted on the input 1966 | * stream, *flatten* will forget the previous nested one it was imitating, and 1967 | * will start imitating the new nested one. 1968 | * 1969 | * Marble diagram: 1970 | * 1971 | * ```text 1972 | * --+--------+--------------- 1973 | * \ \ 1974 | * \ ----1----2---3-- 1975 | * --a--b----c----d-------- 1976 | * flatten 1977 | * -----a--b------1----2---3-- 1978 | * ``` 1979 | * 1980 | * @return {Stream} 1981 | */ 1982 | Stream.prototype.flatten = function () { 1983 | var p = this._prod; 1984 | return new Stream(new Flatten(this)); 1985 | }; 1986 | /** 1987 | * Passes the input stream to a custom operator, to produce an output stream. 1988 | * 1989 | * *compose* is a handy way of using an existing function in a chained style. 1990 | * Instead of writing `outStream = f(inStream)` you can write 1991 | * `outStream = inStream.compose(f)`. 1992 | * 1993 | * @param {function} operator A function that takes a stream as input and 1994 | * returns a stream as well. 1995 | * @return {Stream} 1996 | */ 1997 | Stream.prototype.compose = function (operator) { 1998 | return operator(this); 1999 | }; 2000 | /** 2001 | * Returns an output stream that behaves like the input stream, but also 2002 | * remembers the most recent event that happens on the input stream, so that a 2003 | * newly added listener will immediately receive that memorised event. 2004 | * 2005 | * @return {MemoryStream} 2006 | */ 2007 | Stream.prototype.remember = function () { 2008 | return new MemoryStream(new Remember(this)); 2009 | }; 2010 | /** 2011 | * Returns an output stream that identically behaves like the input stream, 2012 | * but also runs a `spy` function fo each event, to help you debug your app. 2013 | * 2014 | * *debug* takes a `spy` function as argument, and runs that for each event 2015 | * happening on the input stream. If you don't provide the `spy` argument, 2016 | * then *debug* will just `console.log` each event. This helps you to 2017 | * understand the flow of events through some operator chain. 2018 | * 2019 | * Please note that if the output stream has no listeners, then it will not 2020 | * start, which means `spy` will never run because no actual event happens in 2021 | * that case. 2022 | * 2023 | * Marble diagram: 2024 | * 2025 | * ```text 2026 | * --1----2-----3-----4-- 2027 | * debug 2028 | * --1----2-----3-----4-- 2029 | * ``` 2030 | * 2031 | * @param {function} labelOrSpy A string to use as the label when printing 2032 | * debug information on the console, or a 'spy' function that takes an event 2033 | * as argument, and does not need to return anything. 2034 | * @return {Stream} 2035 | */ 2036 | Stream.prototype.debug = function (labelOrSpy) { 2037 | return new (this.ctor())(new Debug(this, labelOrSpy)); 2038 | }; 2039 | /** 2040 | * *imitate* changes this current Stream to emit the same events that the 2041 | * `other` given Stream does. This method returns nothing. 2042 | * 2043 | * This method exists to allow one thing: **circular dependency of streams**. 2044 | * For instance, let's imagine that for some reason you need to create a 2045 | * circular dependency where stream `first$` depends on stream `second$` 2046 | * which in turn depends on `first$`: 2047 | * 2048 | * 2049 | * ```js 2050 | * import delay from 'xstream/extra/delay' 2051 | * 2052 | * var first$ = second$.map(x => x * 10).take(3); 2053 | * var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); 2054 | * ``` 2055 | * 2056 | * However, that is invalid JavaScript, because `second$` is undefined 2057 | * on the first line. This is how *imitate* can help solve it: 2058 | * 2059 | * ```js 2060 | * import delay from 'xstream/extra/delay' 2061 | * 2062 | * var secondProxy$ = xs.create(); 2063 | * var first$ = secondProxy$.map(x => x * 10).take(3); 2064 | * var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); 2065 | * secondProxy$.imitate(second$); 2066 | * ``` 2067 | * 2068 | * We create `secondProxy$` before the others, so it can be used in the 2069 | * declaration of `first$`. Then, after both `first$` and `second$` are 2070 | * defined, we hook `secondProxy$` with `second$` with `imitate()` to tell 2071 | * that they are "the same". `imitate` will not trigger the start of any 2072 | * stream, it just binds `secondProxy$` and `second$` together. 2073 | * 2074 | * The following is an example where `imitate()` is important in Cycle.js 2075 | * applications. A parent component contains some child components. A child 2076 | * has an action stream which is given to the parent to define its state: 2077 | * 2078 | * 2079 | * ```js 2080 | * const childActionProxy$ = xs.create(); 2081 | * const parent = Parent({...sources, childAction$: childActionProxy$}); 2082 | * const childAction$ = parent.state$.map(s => s.child.action$).flatten(); 2083 | * childActionProxy$.imitate(childAction$); 2084 | * ``` 2085 | * 2086 | * Note, though, that **`imitate()` does not support MemoryStreams**. If we 2087 | * would attempt to imitate a MemoryStream in a circular dependency, we would 2088 | * either get a race condition (where the symptom would be "nothing happens") 2089 | * or an infinite cyclic emission of values. It's useful to think about 2090 | * MemoryStreams as cells in a spreadsheet. It doesn't make any sense to 2091 | * define a spreadsheet cell `A1` with a formula that depends on `B1` and 2092 | * cell `B1` defined with a formula that depends on `A1`. 2093 | * 2094 | * If you find yourself wanting to use `imitate()` with a 2095 | * MemoryStream, you should rework your code around `imitate()` to use a 2096 | * Stream instead. Look for the stream in the circular dependency that 2097 | * represents an event stream, and that would be a candidate for creating a 2098 | * proxy Stream which then imitates the target Stream. 2099 | * 2100 | * @param {Stream} target The other stream to imitate on the current one. Must 2101 | * not be a MemoryStream. 2102 | */ 2103 | Stream.prototype.imitate = function (target) { 2104 | if (target instanceof MemoryStream) 2105 | throw new Error('A MemoryStream was given to imitate(), but it only ' + 2106 | 'supports a Stream. Read more about this restriction here: ' + 2107 | 'https://github.com/staltz/xstream#faq'); 2108 | this._target = target; 2109 | for (var ils = this._ils, N = ils.length, i = 0; i < N; i++) 2110 | target._add(ils[i]); 2111 | this._ils = []; 2112 | }; 2113 | /** 2114 | * Forces the Stream to emit the given value to its listeners. 2115 | * 2116 | * As the name indicates, if you use this, you are most likely doing something 2117 | * The Wrong Way. Please try to understand the reactive way before using this 2118 | * method. Use it only when you know what you are doing. 2119 | * 2120 | * @param value The "next" value you want to broadcast to all listeners of 2121 | * this Stream. 2122 | */ 2123 | Stream.prototype.shamefullySendNext = function (value) { 2124 | this._n(value); 2125 | }; 2126 | /** 2127 | * Forces the Stream to emit the given error to its listeners. 2128 | * 2129 | * As the name indicates, if you use this, you are most likely doing something 2130 | * The Wrong Way. Please try to understand the reactive way before using this 2131 | * method. Use it only when you know what you are doing. 2132 | * 2133 | * @param {any} error The error you want to broadcast to all the listeners of 2134 | * this Stream. 2135 | */ 2136 | Stream.prototype.shamefullySendError = function (error) { 2137 | this._e(error); 2138 | }; 2139 | /** 2140 | * Forces the Stream to emit the "completed" event to its listeners. 2141 | * 2142 | * As the name indicates, if you use this, you are most likely doing something 2143 | * The Wrong Way. Please try to understand the reactive way before using this 2144 | * method. Use it only when you know what you are doing. 2145 | */ 2146 | Stream.prototype.shamefullySendComplete = function () { 2147 | this._c(); 2148 | }; 2149 | /** 2150 | * Adds a "debug" listener to the stream. There can only be one debug 2151 | * listener, that's why this is 'setDebugListener'. To remove the debug 2152 | * listener, just call setDebugListener(null). 2153 | * 2154 | * A debug listener is like any other listener. The only difference is that a 2155 | * debug listener is "stealthy": its presence/absence does not trigger the 2156 | * start/stop of the stream (or the producer inside the stream). This is 2157 | * useful so you can inspect what is going on without changing the behavior 2158 | * of the program. If you have an idle stream and you add a normal listener to 2159 | * it, the stream will start executing. But if you set a debug listener on an 2160 | * idle stream, it won't start executing (not until the first normal listener 2161 | * is added). 2162 | * 2163 | * As the name indicates, we don't recommend using this method to build app 2164 | * logic. In fact, in most cases the debug operator works just fine. Only use 2165 | * this one if you know what you're doing. 2166 | * 2167 | * @param {Listener} listener 2168 | */ 2169 | Stream.prototype.setDebugListener = function (listener) { 2170 | if (!listener) { 2171 | this._d = false; 2172 | this._dl = NO; 2173 | } 2174 | else { 2175 | this._d = true; 2176 | listener._n = listener.next || noop; 2177 | listener._e = listener.error || noop; 2178 | listener._c = listener.complete || noop; 2179 | this._dl = listener; 2180 | } 2181 | }; 2182 | return Stream; 2183 | }()); 2184 | /** 2185 | * Blends multiple streams together, emitting events from all of them 2186 | * concurrently. 2187 | * 2188 | * *merge* takes multiple streams as arguments, and creates a stream that 2189 | * behaves like each of the argument streams, in parallel. 2190 | * 2191 | * Marble diagram: 2192 | * 2193 | * ```text 2194 | * --1----2-----3--------4--- 2195 | * ----a-----b----c---d------ 2196 | * merge 2197 | * --1-a--2--b--3-c---d--4--- 2198 | * ``` 2199 | * 2200 | * @factory true 2201 | * @param {Stream} stream1 A stream to merge together with other streams. 2202 | * @param {Stream} stream2 A stream to merge together with other streams. Two 2203 | * or more streams may be given as arguments. 2204 | * @return {Stream} 2205 | */ 2206 | Stream.merge = function merge() { 2207 | var streams = []; 2208 | for (var _i = 0; _i < arguments.length; _i++) { 2209 | streams[_i] = arguments[_i]; 2210 | } 2211 | return new Stream(new Merge(streams)); 2212 | }; 2213 | /** 2214 | * Combines multiple input streams together to return a stream whose events 2215 | * are arrays that collect the latest events from each input stream. 2216 | * 2217 | * *combine* internally remembers the most recent event from each of the input 2218 | * streams. When any of the input streams emits an event, that event together 2219 | * with all the other saved events are combined into an array. That array will 2220 | * be emitted on the output stream. It's essentially a way of joining together 2221 | * the events from multiple streams. 2222 | * 2223 | * Marble diagram: 2224 | * 2225 | * ```text 2226 | * --1----2-----3--------4--- 2227 | * ----a-----b-----c--d------ 2228 | * combine 2229 | * ----1a-2a-2b-3b-3c-3d-4d-- 2230 | * ``` 2231 | * 2232 | * Note: to minimize garbage collection, *combine* uses the same array 2233 | * instance for each emission. If you need to compare emissions over time, 2234 | * cache the values with `map` first: 2235 | * 2236 | * ```js 2237 | * import pairwise from 'xstream/extra/pairwise' 2238 | * 2239 | * const stream1 = xs.of(1); 2240 | * const stream2 = xs.of(2); 2241 | * 2242 | * xs.combine(stream1, stream2).map( 2243 | * combinedEmissions => ([ ...combinedEmissions ]) 2244 | * ).compose(pairwise) 2245 | * ``` 2246 | * 2247 | * @factory true 2248 | * @param {Stream} stream1 A stream to combine together with other streams. 2249 | * @param {Stream} stream2 A stream to combine together with other streams. 2250 | * Multiple streams, not just two, may be given as arguments. 2251 | * @return {Stream} 2252 | */ 2253 | Stream.combine = function combine() { 2254 | var streams = []; 2255 | for (var _i = 0; _i < arguments.length; _i++) { 2256 | streams[_i] = arguments[_i]; 2257 | } 2258 | return new Stream(new Combine(streams)); 2259 | }; 2260 | exports.Stream = Stream; 2261 | var MemoryStream = (function (_super) { 2262 | __extends(MemoryStream, _super); 2263 | function MemoryStream(producer) { 2264 | var _this = _super.call(this, producer) || this; 2265 | _this._has = false; 2266 | return _this; 2267 | } 2268 | MemoryStream.prototype._n = function (x) { 2269 | this._v = x; 2270 | this._has = true; 2271 | _super.prototype._n.call(this, x); 2272 | }; 2273 | MemoryStream.prototype._add = function (il) { 2274 | var ta = this._target; 2275 | if (ta !== NO) 2276 | return ta._add(il); 2277 | var a = this._ils; 2278 | a.push(il); 2279 | if (a.length > 1) { 2280 | if (this._has) 2281 | il._n(this._v); 2282 | return; 2283 | } 2284 | if (this._stopID !== NO) { 2285 | if (this._has) 2286 | il._n(this._v); 2287 | clearTimeout(this._stopID); 2288 | this._stopID = NO; 2289 | } 2290 | else if (this._has) 2291 | il._n(this._v); 2292 | else { 2293 | var p = this._prod; 2294 | if (p !== NO) 2295 | p._start(this); 2296 | } 2297 | }; 2298 | MemoryStream.prototype._stopNow = function () { 2299 | this._has = false; 2300 | _super.prototype._stopNow.call(this); 2301 | }; 2302 | MemoryStream.prototype._x = function () { 2303 | this._has = false; 2304 | _super.prototype._x.call(this); 2305 | }; 2306 | MemoryStream.prototype.map = function (project) { 2307 | return this._map(project); 2308 | }; 2309 | MemoryStream.prototype.mapTo = function (projectedValue) { 2310 | return _super.prototype.mapTo.call(this, projectedValue); 2311 | }; 2312 | MemoryStream.prototype.take = function (amount) { 2313 | return _super.prototype.take.call(this, amount); 2314 | }; 2315 | MemoryStream.prototype.endWhen = function (other) { 2316 | return _super.prototype.endWhen.call(this, other); 2317 | }; 2318 | MemoryStream.prototype.replaceError = function (replace) { 2319 | return _super.prototype.replaceError.call(this, replace); 2320 | }; 2321 | MemoryStream.prototype.remember = function () { 2322 | return this; 2323 | }; 2324 | MemoryStream.prototype.debug = function (labelOrSpy) { 2325 | return _super.prototype.debug.call(this, labelOrSpy); 2326 | }; 2327 | return MemoryStream; 2328 | }(Stream)); 2329 | exports.MemoryStream = MemoryStream; 2330 | Object.defineProperty(exports, "__esModule", { value: true }); 2331 | exports.default = Stream; 2332 | 2333 | },{"symbol-observable":9}],14:[function(require,module,exports){ 2334 | var lib = require('../../lib/index'); 2335 | var run = require('@cycle/run').run; 2336 | var xstream = require('xstream').default; 2337 | 2338 | 2339 | var dropRepeats = require('xstream/extra/dropRepeats').default; 2340 | var equal = require('deep-equal'); 2341 | 2342 | 2343 | var makeGunDriver = lib.makeGunDriver; 2344 | 2345 | var assert = chai.assert; 2346 | 2347 | function sinkToGun(eventStream) { 2348 | return eventStream 2349 | .filter(function (event) { 2350 | return event.typeKey === 'out-gun'; 2351 | }) 2352 | .map(function (event) { 2353 | return function command(gunInstance) { 2354 | return gunInstance 2355 | .get('example/todo/data') 2356 | .get(event.payload.key) 2357 | .put(event.payload.value) 2358 | }; 2359 | }); 2360 | } 2361 | 2362 | var testArray = [{ 2363 | typeKey: 'out-gun', 2364 | payload: { 2365 | key: '1', 2366 | value: "test1" 2367 | } 2368 | }, 2369 | { 2370 | typeKey: 'out-gun', 2371 | payload: { 2372 | key: '2', 2373 | value: "test2" 2374 | } 2375 | }, 2376 | { 2377 | typeKey: 'out-gun', 2378 | payload: { 2379 | key: '3', 2380 | value: "test3" 2381 | } 2382 | }, 2383 | { 2384 | typeKey: 'out-gun', 2385 | payload: { 2386 | key: '4', 2387 | value: "test4" 2388 | } 2389 | } 2390 | ] 2391 | 2392 | // function main(sources) { 2393 | 2394 | 2395 | // var get$ = sources.gun.get(function (gunInstance) { 2396 | // return gunInstance.get('example/todo/data'); 2397 | // }).compose(dropRepeats(equal)) 2398 | // .debug('get') 2399 | 2400 | // get$.addListener({ 2401 | // next: function(event){ 2402 | // //console.log(event); 2403 | // } 2404 | // }) 2405 | 2406 | // var testPut$ = xstream.fromArray(testArray); 2407 | 2408 | // var gunSinkStream$ = sinkToGun(testPut$); 2409 | 2410 | // return { 2411 | // gun: gunSinkStream$ 2412 | // }; 2413 | // } 2414 | 2415 | // var drivers = { 2416 | // gun: makeGunDriver() 2417 | // } 2418 | 2419 | // cycle.run(main, drivers) 2420 | 2421 | 2422 | 2423 | 2424 | 2425 | 2426 | 2427 | 2428 | describe('MakeGunDriver Factory', function () { 2429 | 2430 | it('is a function', function () { 2431 | assert.strictEqual(typeof makeGunDriver, 'function'); 2432 | }); 2433 | 2434 | it('returns a function', function () { 2435 | 2436 | var gunDriver = makeGunDriver('http://a'); 2437 | assert.strictEqual(typeof gunDriver, 'function'); 2438 | }); 2439 | 2440 | }); 2441 | 2442 | 2443 | describe('cycle-gun driver instance', function () { 2444 | 2445 | 2446 | function main(sources) { 2447 | console.log('sources', sources) 2448 | 2449 | it('sources is an object', function () { 2450 | assert.strictEqual(typeof sources.gun, 'object'); 2451 | }); 2452 | 2453 | it('GunSource has select, shallow, each methods', function () { 2454 | 2455 | console.log(sources.gun); 2456 | assert.strictEqual(typeof sources.gun.select, 'function'); 2457 | assert.strictEqual(typeof sources.gun.shallow, 'function'); 2458 | assert.strictEqual(typeof sources.gun.each, 'function'); 2459 | }); 2460 | 2461 | it('gets inbound stream from gun', function () { 2462 | var get$ = sources.gun 2463 | .select('example').select('todo').select('data') 2464 | .shallow(); 2465 | 2466 | get$.addListener({ 2467 | next: function (event) { 2468 | console.log('get$ event', event) 2469 | assert.strictEqual(typeof event, 'object'); 2470 | } 2471 | }); 2472 | }); 2473 | 2474 | it('checks data elements are same as those sent', function () { 2475 | var get$ = sources.gun 2476 | .select('example').select('todo').select('data') 2477 | .shallow(); 2478 | 2479 | get$.addListener({ 2480 | next: function (event) { 2481 | console.log(event) 2482 | assert.strictEqual(event['1'], 'test1'); 2483 | assert.strictEqual(event['2'], 'test2'); 2484 | assert.strictEqual(event['3'], 'test3'); 2485 | assert.strictEqual(event['4'], 'test4'); 2486 | 2487 | } 2488 | }); 2489 | }); 2490 | 2491 | 2492 | 2493 | 2494 | 2495 | 2496 | 2497 | 2498 | 2499 | 2500 | 2501 | 2502 | 2503 | 2504 | var testPut$ = xstream.fromArray(testArray); 2505 | 2506 | const gunSinkStream$ = sinkToGun(testPut$); 2507 | 2508 | return { 2509 | gun: gunSinkStream$ 2510 | }; 2511 | } 2512 | 2513 | var drivers = { 2514 | gun: makeGunDriver({root: '/'}) 2515 | } 2516 | 2517 | run(main, drivers) 2518 | 2519 | }); 2520 | },{"../../lib/index":2,"@cycle/run":4,"deep-equal":5,"xstream":13,"xstream/extra/dropRepeats":12}]},{},[14]); 2521 | -------------------------------------------------------------------------------- /test/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mocha Tests 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 19 | 20 | 21 | 23 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /test/browser/index.js: -------------------------------------------------------------------------------- 1 | var lib = require('../../lib/index'); 2 | var run = require('@cycle/run').run; 3 | var xstream = require('xstream').default; 4 | 5 | 6 | var dropRepeats = require('xstream/extra/dropRepeats').default; 7 | var equal = require('deep-equal'); 8 | 9 | 10 | var makeGunDriver = lib.makeGunDriver; 11 | 12 | var assert = chai.assert; 13 | 14 | function sinkToGun(eventStream) { 15 | return eventStream 16 | .filter(function (event) { 17 | return event.typeKey === 'out-gun'; 18 | }) 19 | .map(function (event) { 20 | return function command(gunInstance) { 21 | return gunInstance 22 | .get('example/todo/data') 23 | .get(event.payload.key) 24 | .put(event.payload.value) 25 | }; 26 | }); 27 | } 28 | 29 | var testArray = [{ 30 | typeKey: 'out-gun', 31 | payload: { 32 | key: '1', 33 | value: "test1" 34 | } 35 | }, 36 | { 37 | typeKey: 'out-gun', 38 | payload: { 39 | key: '2', 40 | value: "test2" 41 | } 42 | }, 43 | { 44 | typeKey: 'out-gun', 45 | payload: { 46 | key: '3', 47 | value: "test3" 48 | } 49 | }, 50 | { 51 | typeKey: 'out-gun', 52 | payload: { 53 | key: '4', 54 | value: "test4" 55 | } 56 | } 57 | ] 58 | 59 | // function main(sources) { 60 | 61 | 62 | // var get$ = sources.gun.get(function (gunInstance) { 63 | // return gunInstance.get('example/todo/data'); 64 | // }).compose(dropRepeats(equal)) 65 | // .debug('get') 66 | 67 | // get$.addListener({ 68 | // next: function(event){ 69 | // //console.log(event); 70 | // } 71 | // }) 72 | 73 | // var testPut$ = xstream.fromArray(testArray); 74 | 75 | // var gunSinkStream$ = sinkToGun(testPut$); 76 | 77 | // return { 78 | // gun: gunSinkStream$ 79 | // }; 80 | // } 81 | 82 | // var drivers = { 83 | // gun: makeGunDriver() 84 | // } 85 | 86 | // cycle.run(main, drivers) 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | describe('MakeGunDriver Factory', function () { 96 | 97 | it('is a function', function () { 98 | assert.strictEqual(typeof makeGunDriver, 'function'); 99 | }); 100 | 101 | it('returns a function', function () { 102 | 103 | var gunDriver = makeGunDriver('http://a'); 104 | assert.strictEqual(typeof gunDriver, 'function'); 105 | }); 106 | 107 | }); 108 | 109 | 110 | describe('cycle-gun driver instance', function () { 111 | 112 | 113 | function main(sources) { 114 | console.log('sources', sources) 115 | 116 | it('sources is an object', function () { 117 | assert.strictEqual(typeof sources.gun, 'object'); 118 | }); 119 | 120 | it('GunSource has select, shallow, each methods', function () { 121 | 122 | console.log(sources.gun); 123 | assert.strictEqual(typeof sources.gun.select, 'function'); 124 | assert.strictEqual(typeof sources.gun.shallow, 'function'); 125 | assert.strictEqual(typeof sources.gun.each, 'function'); 126 | }); 127 | 128 | it('gets inbound stream from gun', function () { 129 | var get$ = sources.gun 130 | .select('example').select('todo').select('data') 131 | .shallow(); 132 | 133 | get$.addListener({ 134 | next: function (event) { 135 | console.log('get$ event', event) 136 | assert.strictEqual(typeof event, 'object'); 137 | } 138 | }); 139 | }); 140 | 141 | it('checks data elements are same as those sent', function () { 142 | var get$ = sources.gun 143 | .select('example').select('todo').select('data') 144 | .shallow(); 145 | 146 | get$.addListener({ 147 | next: function (event) { 148 | console.log(event) 149 | assert.strictEqual(event['1'], 'test1'); 150 | assert.strictEqual(event['2'], 'test2'); 151 | assert.strictEqual(event['3'], 'test3'); 152 | assert.strictEqual(event['4'], 'test4'); 153 | 154 | } 155 | }); 156 | }); 157 | 158 | var testPut$ = xstream.fromArray(testArray); 159 | 160 | const gunSinkStream$ = sinkToGun(testPut$); 161 | 162 | return { 163 | gun: gunSinkStream$ 164 | }; 165 | } 166 | 167 | var drivers = { 168 | gun: makeGunDriver({root: '/'}) 169 | } 170 | 171 | run(main, drivers) 172 | 173 | }); -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "sourceMap": true, 6 | "outDir": "lib/", 7 | "lib": [ 8 | "dom", 9 | "es5", 10 | "es6", 11 | "es2015" 12 | ] 13 | }, 14 | "include": [ 15 | "**/*.ts" 16 | ], 17 | "exclude": [ 18 | "node_modules", 19 | "**/*.spec.ts" 20 | ] 21 | } --------------------------------------------------------------------------------