├── .gitignore ├── .travis.yml ├── LICENSE ├── index.js ├── package-lock.json ├── package.json ├── readme.md ├── test.js └── types.d.ts /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | index.cjs.js 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "node" 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 André Staltz(staltz.com) 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 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const interval = period => (start, sink) => { 2 | if (start !== 0) return; 3 | let i = 0; 4 | const id = setInterval(() => { 5 | sink(1, i++); 6 | }, period); 7 | sink(0, t => { 8 | if (t === 2) clearInterval(id); 9 | }); 10 | }; 11 | 12 | export default interval; 13 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "callbag-interval", 3 | "version": "1.2.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/estree": { 8 | "version": "0.0.39", 9 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", 10 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 11 | "dev": true 12 | }, 13 | "@types/node": { 14 | "version": "10.5.2", 15 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.2.tgz", 16 | "integrity": "sha512-m9zXmifkZsMHZBOyxZWilMwmTlpC8x5Ty360JKTiXvlXZfBWYpsg9ZZvP/Ye+iZUh+Q+MxDLjItVTWIsfwz+8Q==", 17 | "dev": true 18 | }, 19 | "balanced-match": { 20 | "version": "1.0.0", 21 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 22 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 23 | "dev": true 24 | }, 25 | "brace-expansion": { 26 | "version": "1.1.8", 27 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 28 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 29 | "dev": true, 30 | "requires": { 31 | "balanced-match": "^1.0.0", 32 | "concat-map": "0.0.1" 33 | } 34 | }, 35 | "callbag": { 36 | "version": "1.1.0", 37 | "resolved": "https://registry.npmjs.org/callbag/-/callbag-1.1.0.tgz", 38 | "integrity": "sha512-JVZp2vA53+THwOOan8eedGhS7xwzwR1u8HFK02WDMI9pITGoQ42j2sYP742qs7yddtEjIDGgNe1Y6DN90w3oIQ==" 39 | }, 40 | "concat-map": { 41 | "version": "0.0.1", 42 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 43 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 44 | "dev": true 45 | }, 46 | "deep-equal": { 47 | "version": "1.0.1", 48 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", 49 | "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", 50 | "dev": true 51 | }, 52 | "define-properties": { 53 | "version": "1.1.2", 54 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", 55 | "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", 56 | "dev": true, 57 | "requires": { 58 | "foreach": "^2.0.5", 59 | "object-keys": "^1.0.8" 60 | } 61 | }, 62 | "defined": { 63 | "version": "1.0.0", 64 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", 65 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", 66 | "dev": true 67 | }, 68 | "es-abstract": { 69 | "version": "1.10.0", 70 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", 71 | "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", 72 | "dev": true, 73 | "requires": { 74 | "es-to-primitive": "^1.1.1", 75 | "function-bind": "^1.1.1", 76 | "has": "^1.0.1", 77 | "is-callable": "^1.1.3", 78 | "is-regex": "^1.0.4" 79 | } 80 | }, 81 | "es-to-primitive": { 82 | "version": "1.1.1", 83 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", 84 | "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", 85 | "dev": true, 86 | "requires": { 87 | "is-callable": "^1.1.1", 88 | "is-date-object": "^1.0.1", 89 | "is-symbol": "^1.0.1" 90 | } 91 | }, 92 | "for-each": { 93 | "version": "0.3.2", 94 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", 95 | "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", 96 | "dev": true, 97 | "requires": { 98 | "is-function": "~1.0.0" 99 | } 100 | }, 101 | "foreach": { 102 | "version": "2.0.5", 103 | "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", 104 | "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", 105 | "dev": true 106 | }, 107 | "fs.realpath": { 108 | "version": "1.0.0", 109 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 110 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 111 | "dev": true 112 | }, 113 | "function-bind": { 114 | "version": "1.1.1", 115 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 116 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 117 | "dev": true 118 | }, 119 | "glob": { 120 | "version": "7.1.2", 121 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 122 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 123 | "dev": true, 124 | "requires": { 125 | "fs.realpath": "^1.0.0", 126 | "inflight": "^1.0.4", 127 | "inherits": "2", 128 | "minimatch": "^3.0.4", 129 | "once": "^1.3.0", 130 | "path-is-absolute": "^1.0.0" 131 | } 132 | }, 133 | "has": { 134 | "version": "1.0.1", 135 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", 136 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", 137 | "dev": true, 138 | "requires": { 139 | "function-bind": "^1.0.2" 140 | } 141 | }, 142 | "inflight": { 143 | "version": "1.0.6", 144 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 145 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 146 | "dev": true, 147 | "requires": { 148 | "once": "^1.3.0", 149 | "wrappy": "1" 150 | } 151 | }, 152 | "inherits": { 153 | "version": "2.0.3", 154 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 155 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 156 | "dev": true 157 | }, 158 | "is-callable": { 159 | "version": "1.1.3", 160 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", 161 | "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", 162 | "dev": true 163 | }, 164 | "is-date-object": { 165 | "version": "1.0.1", 166 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", 167 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", 168 | "dev": true 169 | }, 170 | "is-function": { 171 | "version": "1.0.1", 172 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", 173 | "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", 174 | "dev": true 175 | }, 176 | "is-regex": { 177 | "version": "1.0.4", 178 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", 179 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", 180 | "dev": true, 181 | "requires": { 182 | "has": "^1.0.1" 183 | } 184 | }, 185 | "is-symbol": { 186 | "version": "1.0.1", 187 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", 188 | "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", 189 | "dev": true 190 | }, 191 | "minimatch": { 192 | "version": "3.0.4", 193 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 194 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 195 | "dev": true, 196 | "requires": { 197 | "brace-expansion": "^1.1.7" 198 | } 199 | }, 200 | "minimist": { 201 | "version": "1.2.6", 202 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 203 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", 204 | "dev": true 205 | }, 206 | "object-inspect": { 207 | "version": "1.3.0", 208 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.3.0.tgz", 209 | "integrity": "sha512-OHHnLgLNXpM++GnJRyyhbr2bwl3pPVm4YvaraHrRvDt/N3r+s/gDVHciA7EJBTkijKXj61ssgSAikq1fb0IBRg==", 210 | "dev": true 211 | }, 212 | "object-keys": { 213 | "version": "1.0.11", 214 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", 215 | "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", 216 | "dev": true 217 | }, 218 | "once": { 219 | "version": "1.4.0", 220 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 221 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 222 | "dev": true, 223 | "requires": { 224 | "wrappy": "1" 225 | } 226 | }, 227 | "path-is-absolute": { 228 | "version": "1.0.1", 229 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 230 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 231 | "dev": true 232 | }, 233 | "path-parse": { 234 | "version": "1.0.5", 235 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 236 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 237 | "dev": true 238 | }, 239 | "resolve": { 240 | "version": "1.4.0", 241 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", 242 | "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", 243 | "dev": true, 244 | "requires": { 245 | "path-parse": "^1.0.5" 246 | } 247 | }, 248 | "resumer": { 249 | "version": "0.0.0", 250 | "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", 251 | "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", 252 | "dev": true, 253 | "requires": { 254 | "through": "~2.3.4" 255 | } 256 | }, 257 | "rollup": { 258 | "version": "0.63.4", 259 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.63.4.tgz", 260 | "integrity": "sha512-IGTH7u0P6bmu7cXL0g11UDYTR9WKku70cYlqVyOYdqLoQopBGmCbGC3SMeheqHymnehHe/5yf6BJ6BEoxQBVTQ==", 261 | "dev": true, 262 | "requires": { 263 | "@types/estree": "0.0.39", 264 | "@types/node": "*" 265 | } 266 | }, 267 | "string.prototype.trim": { 268 | "version": "1.1.2", 269 | "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", 270 | "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", 271 | "dev": true, 272 | "requires": { 273 | "define-properties": "^1.1.2", 274 | "es-abstract": "^1.5.0", 275 | "function-bind": "^1.0.2" 276 | } 277 | }, 278 | "tape": { 279 | "version": "4.8.0", 280 | "resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz", 281 | "integrity": "sha512-TWILfEnvO7I8mFe35d98F6T5fbLaEtbFTG/lxWvid8qDfFTxt19EBijWmB4j3+Hoh5TfHE2faWs73ua+EphuBA==", 282 | "dev": true, 283 | "requires": { 284 | "deep-equal": "~1.0.1", 285 | "defined": "~1.0.0", 286 | "for-each": "~0.3.2", 287 | "function-bind": "~1.1.0", 288 | "glob": "~7.1.2", 289 | "has": "~1.0.1", 290 | "inherits": "~2.0.3", 291 | "minimist": "~1.2.0", 292 | "object-inspect": "~1.3.0", 293 | "resolve": "~1.4.0", 294 | "resumer": "~0.0.0", 295 | "string.prototype.trim": "~1.1.2", 296 | "through": "~2.3.8" 297 | } 298 | }, 299 | "through": { 300 | "version": "2.3.8", 301 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 302 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 303 | "dev": true 304 | }, 305 | "wrappy": { 306 | "version": "1.0.2", 307 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 308 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 309 | "dev": true 310 | } 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "callbag-interval", 3 | "version": "1.2.0", 4 | "description": "A callbag listenable source that sends incremental numbers every x milliseconds", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/staltz/callbag-interval.git" 8 | }, 9 | "main": "index.cjs.js", 10 | "module": "index.js", 11 | "types": "types.d.ts", 12 | "scripts": { 13 | "build": "rollup $npm_package_module -o $npm_package_main --f cjs", 14 | "pretest": "npm run build", 15 | "test": "tape test.js", 16 | "prepare": "npm test" 17 | }, 18 | "author": "staltz.com", 19 | "license": "MIT", 20 | "keywords": [ 21 | "callbag" 22 | ], 23 | "devDependencies": { 24 | "rollup": "^0.63.4", 25 | "tape": "^4.8.0" 26 | }, 27 | "dependencies": { 28 | "callbag": "^1.1.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # callbag-interval 2 | 3 | A callbag listenable source that sends incremental numbers every x milliseconds. 4 | 5 | `npm install callbag-interval` 6 | 7 | ## example 8 | 9 | ```js 10 | const interval = require('callbag-interval'); 11 | const observe = require('callbag-observe'); 12 | 13 | const source = interval(1000); 14 | 15 | observe(x => console.log(x))(source); // 0 16 | // 1 17 | // 2 18 | // 3 19 | // ... 20 | ``` 21 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape'); 2 | const interval = require('.'); 3 | 4 | test('interval(50) sends 5 times then we dispose it', function(t) { 5 | t.plan(5); 6 | 7 | const expected = [0, 1, 2, 3, 4]; 8 | 9 | let talkback; 10 | function observe(type, data) { 11 | if (type === 0) { 12 | talkback = data; 13 | return; 14 | } 15 | if (type === 1) { 16 | t.equals(data, expected.shift(), 'interval sent data'); 17 | if (expected.length === 0) { 18 | talkback(2); 19 | } 20 | return; 21 | } 22 | } 23 | 24 | interval(50)(0, observe); 25 | }); 26 | 27 | test('interval(1000) can be disposed before anything is sent', function(t) { 28 | t.plan(1); 29 | 30 | let talkback; 31 | function observe(type, data) { 32 | if (type === 0) { 33 | talkback = data; 34 | setTimeout(() => { 35 | talkback(2); 36 | t.pass('disposed'); 37 | }, 200); 38 | return; 39 | } 40 | if (type === 1) { 41 | t.fail('data should not be sent'); 42 | return; 43 | } 44 | } 45 | 46 | interval(1000)(0, observe); 47 | }); 48 | -------------------------------------------------------------------------------- /types.d.ts: -------------------------------------------------------------------------------- 1 | import { Source } from 'callbag'; 2 | declare const interval: (period: number) => Source; 3 | export default interval 4 | --------------------------------------------------------------------------------