{"action":"created","comment":{"url":"https://api.github.com/repos/politie/sherlock/pulls/comments/205710028","pull_request_review_id":141034714,"id":205710028,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIwNTcxMDAyOA==","diff_hunk":"@@ -0,0 +1,680 @@\n+import { _internal, atom, Derivable, DerivableAtom, State, transact } from '@politie/sherlock';\n+import { expect } from 'chai';\n+import { spy } from 'sinon';\n+import { controlFlow, ControlFlowOptions } from './control-flow';\n+\n+const { unresolved } = _internal.symbols;\n+\n+describe('sherlock-utils/filterUpdates', () => {\n+    let a$: DerivableAtom<string>;\n+\n+    beforeEach('create the base atom', () => { a$ = atom.unresolved(); });\n+\n+    context('not connected get with', () => {\n+        context('no options', () => {\n+            it('should always forward a get request when not connected', () => {\n+                spy(a$, 'getState');\n+                const f$ = controlFlow(a$);\n+                expect(a$.getState).to.not.have.been.called;\n+                expect(f$.resolved).to.be.false;\n+                expect(a$.getState).to.have.been.calledOnce;\n+                a$.set('boo');\n+                expect(f$.value).to.equal('boo');\n+                expect(a$.getState).to.have.been.calledTwice;\n+            });\n+\n+            it('should propagate errors', () => {\n+                const f$ = controlFlow(a$);\n+                a$.setError('my error');\n+                expect(f$.value).to.be.undefined;\n+                expect(f$.error).to.equal('my error');\n+                a$.set('a');\n+                expect(f$.value).to.equal('a');\n+                expect(f$.error).to.be.undefined;\n+            });\n+        });\n+\n+        describe('from', () => {\n+            it('should be unresolved if `from` is false', () => {\n+                a$.set('value');\n+                const f$ = controlFlow(a$, { from: false });\n+                expect(f$.resolved).to.be.false;\n+            });\n+\n+            it('should be unresolved while `from` is false', () => {\n+                a$.set('value');\n+                const from = atom(false);\n+                const f$ = controlFlow(a$, { from });\n+                expect(f$.resolved).to.be.false;\n+                from.set(true);\n+                expect(f$.value).to.equal('value');\n+                from.unset();\n+                expect(f$.resolved).to.be.false;\n+                from.set(false);\n+                expect(f$.resolved).to.be.false;\n+            });\n+\n+            it('should propagate errors iff `from` is true', () => {\n+                a$.setError('my error');\n+                const from = atom(false);\n+                const f$ = controlFlow(a$, { from });\n+                expect(f$.error).to.be.undefined;\n+                from.set(true);\n+                expect(f$.error).to.equal('my error');\n+                from.unset();\n+                expect(f$.error).to.be.undefined;\n+                from.set(false);\n+                expect(f$.error).to.be.undefined;\n+            });\n+        });\n+\n+        describe('until', () => {\n+            it('should be unresolved if `until` is true', () => {\n+                a$.set('value');\n+                const f$ = controlFlow(a$, { until: true });\n+                expect(f$.resolved).to.be.false;\n+            });\n+\n+            it('should be unresolved while `until` is true', () => {\n+                a$.set('value');\n+                const until = atom(false);\n+                const f$ = controlFlow(a$, { until });\n+                expect(f$.value).to.equal('value');\n+                until.set(true);\n+                expect(f$.resolved).to.be.false;\n+                until.unset();\n+                expect(f$.resolved).to.be.false;\n+                until.set(false);\n+                expect(f$.value).to.equal('value');\n+            });\n+\n+            it('should propagate errors iff `until` is false', () => {\n+                a$.setError('an error');\n+                const until = atom(false);\n+                const f$ = controlFlow(a$, { until });\n+                expect(f$.error).to.equal('an error');\n+                until.set(true);\n+                expect(f$.error).to.be.undefined;\n+                until.unset();\n+                expect(f$.error).to.be.undefined;\n+                until.set(false);\n+                expect(f$.error).to.equal('an error');\n+            });\n+        });\n+\n+        describe('when', () => {\n+            it('should be unresolved if `when` is false', () => {\n+                a$.set('value');\n+                const f$ = controlFlow(a$, { when: false });\n+                expect(f$.resolved).to.be.false;\n+            });\n+\n+            it('should be unresolved while `when` is false', () => {\n+                a$.set('value');\n+                const when = atom(false);\n+                const f$ = controlFlow(a$, { when });\n+                expect(f$.resolved).to.be.false;\n+                when.set(true);\n+                expect(f$.value).to.equal('value');\n+                when.unset();\n+                expect(f$.resolved).to.be.false;\n+                when.set(false);\n+                expect(f$.resolved).to.be.false;\n+            });\n+\n+            it('should propagate errors iff `when` is true', () => {\n+                a$.setError('foo');\n+                const when = atom(false);\n+                const f$ = controlFlow(a$, { when });\n+                expect(f$.error).to.be.undefined;\n+                when.set(true);\n+                expect(f$.error).to.equal('foo');\n+                when.unset();\n+                expect(f$.error).to.be.undefined;\n+                when.set(false);\n+                expect(f$.error).to.be.undefined;\n+            });\n+        });\n+\n+        describe('once', () => {\n+            it('should have no impact on the output', () => {\n+                a$.set('value');\n+                const f$ = controlFlow(a$, { once: true });\n+                expect(f$.value).to.equal('value');\n+                expect(f$.value).to.equal('value');\n+\n+                a$.setError('bar');\n+                expect(f$.error).to.equal('bar');\n+            });\n+        });\n+\n+        describe('skipFirst', () => {\n+            it('should always be unresolved', () => {\n+                a$.set('value');\n+                const f$ = controlFlow(a$, { skipFirst: true });\n+                expect(f$.resolved).to.be.false;\n+                expect(f$.resolved).to.be.false;\n+\n+                a$.setError('baz');\n+                expect(f$.resolved).to.be.false;\n+            });\n+        });\n+    });\n+\n+    for (const includeUnresolved of [false, true]) {\n+        context(`connected, with { includeUnresolved: ${includeUnresolved} }, using`, () => {\n+\n+            describe('no options', () => {\n+                it(`should ${includeUnresolved ? '' : 'not '}return to unresolved while connected`, () => {\n+                    startTest();\n+\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    a$.set('a');\n+\n+                    shouldHaveReactedOnce('a');\n+\n+                    a$.unset();\n+\n+                    shouldNotHaveReacted(includeUnresolved ? unresolved : 'a');\n+                });\n+\n+                it('should always return to unresolved when disconnected', () => {\n+                    startTest();\n+                    a$.set('a');\n+                    shouldHaveReactedOnce('a');\n+                    a$.unset();\n+                    shouldNotHaveReacted(includeUnresolved ? unresolved : 'a');\n+                    stopTest();\n+                    shouldNotHaveReacted(unresolved);\n+                });\n+\n+                it('should disconnect when the reactor disconnects', () => {\n+                    startTest();\n+                    expect(a$.connected).to.be.true;\n+                    stopTest();\n+                    expect(a$.connected).to.be.false;\n+                });\n+            });\n+\n+            describe('from', () => {\n+                let from: DerivableAtom<boolean>;\n+                beforeEach(() => { from = atom.unresolved<boolean>(); });\n+\n+                it('should not start updating until `from` becomes true', () => {\n+                    startTest({ from });\n+\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    a$.setError('error');\n+                    a$.set('a');\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    from.set(true);\n+                    shouldHaveReactedOnce('a');\n+\n+                    // No impact anymore:\n+                    from.set(false);\n+\n+                    a$.set('b');\n+                    shouldHaveReactedOnce('b');\n+\n+                    a$.setError('error');\n+                    shouldHaveReactedOnce(new _internal.ErrorWrapper('error'));\n+                    shouldNotHaveReacted(new _internal.ErrorWrapper('error'));\n+                });\n+\n+                it('should disconnect from the `from` derivable when it becomes true', () => {\n+                    from.set(false);\n+                    startTest({ from });\n+\n+                    expect(a$.connected).to.be.false;\n+                    expect(from.connected).to.be.true;\n+\n+                    from.set(true);\n+\n+                    expect(a$.connected).to.be.true;\n+                    expect(from.connected).to.be.false;\n+\n+                    stopTest();\n+\n+                    expect(a$.connected).to.be.false;\n+                });\n+\n+                context('inside transactions', () => {\n+                    it('should be live', () => {\n+                        from.set(false);\n+                        a$.set('a');\n+                        const f$ = startTest({ from });\n+\n+                        transact(() => {\n+                            expect(f$.resolved).to.be.false;\n+\n+                            // Works as expected:\n+                            from.set(true);\n+                            expect(f$.value).to.equal('a');\n+\n+                            // But we can undo our work because we are inside a transaction.\n+                            from.set(false);\n+                            expect(f$.resolved).to.be.false;\n+                        });\n+\n+                        expect(f$.resolved).to.be.false;\n+                    });\n+\n+                    it('should be consistent', () => {\n+                        from.set(false);\n+                        a$.set('a');\n+                        startTest({ from });\n+\n+                        shouldNotHaveReacted(unresolved);\n+\n+                        transact(() => {\n+                            from.set(true);\n+                            a$.set('b');\n+                            a$.set('c');\n+                            from.set(false);\n+                        });\n+\n+                        shouldNotHaveReacted(unresolved);\n+                    });\n+                });\n+            });\n+\n+            describe('until', () => {\n+                let until: DerivableAtom<boolean>;\n+                beforeEach(() => { until = atom.unresolved<boolean>(); });\n+\n+                it('should update until the `until` derivable becomes true', () => {\n+                    startTest({ until });\n+\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    a$.set('a');\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    until.set(false);\n+                    shouldHaveReactedOnce('a');\n+\n+                    a$.setError('my error');\n+                    shouldHaveReactedOnce(new _internal.ErrorWrapper('my error'));\n+\n+                    a$.set('b');\n+                    shouldHaveReactedOnce('b');\n+\n+                    until.set(true);\n+                    shouldNotHaveReacted('b');\n+\n+                    // No impact\n+                    a$.set('c');\n+                    shouldNotHaveReacted('b');\n+                });\n+\n+                it('should disconnect from the base when `until` becomes true', () => {\n+                    until.set(false);\n+                    startTest({ until });\n+\n+                    expect(a$.connected).to.be.true;\n+                    expect(until.connected).to.be.true;\n+\n+                    until.set(true);\n+\n+                    expect(a$.connected).to.be.false;\n+                    expect(until.connected).to.be.false;\n+                });\n+\n+                it('should support derived `until` option', () => {\n+                    startTest({ until: d => d.is('stop now') });\n+\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    a$.set('abc');\n+                    shouldHaveReactedOnce('abc');\n+\n+                    a$.set('def');\n+                    shouldHaveReactedOnce('def');\n+\n+                    a$.set('stop now');\n+                    shouldNotHaveReacted('def');\n+                });\n+\n+                context('inside transactions', () => {\n+                    it('should be live', () => {\n+                        until.set(false);\n+                        a$.set('a');\n+                        const f$ = startTest({ until });\n+\n+                        transact(() => {\n+                            expect(f$.value).to.equal('a');\n+\n+                            a$.set('b');\n+                            expect(f$.value).to.equal('b');\n+\n+                            // Always represents state that should be visible after the transaction:\n+                            until.set(true);\n+                            a$.set('c');\n+                            expect(f$.value).to.equal('a');\n+\n+                            // But we can undo everything because we are inside a transaction.\n+                            until.set(false);\n+                            expect(f$.value).to.equal('c');\n+\n+                            until.set(true);\n+                        });\n+\n+                        expect(f$.value).to.equal('a');\n+                    });\n+\n+                    it('should be consistent', () => {\n+                        until.set(false);\n+                        a$.set('a');\n+                        startTest({ until });\n+\n+                        shouldHaveReactedOnce('a');\n+\n+                        transact(() => {\n+                            a$.set('b');\n+                            a$.set('c');\n+                            until.set(true);\n+                        });\n+\n+                        shouldNotHaveReacted('a');\n+                    });\n+                });\n+            });\n+\n+            describe('when', () => {\n+                let when: DerivableAtom<boolean>;\n+                beforeEach(() => { when = atom.unresolved<boolean>(); });\n+\n+                it('should only update when `when` is true', () => {\n+                    startTest({ when });\n+\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    a$.set('a');\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    when.set(false);\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    when.set(true);\n+                    shouldHaveReactedOnce('a');\n+\n+                    a$.setError('my error');\n+                    shouldHaveReactedOnce(new _internal.ErrorWrapper('my error'));\n+\n+                    a$.set('b');\n+                    shouldHaveReactedOnce('b');\n+\n+                    when.set(false);\n+                    shouldNotHaveReacted('b');\n+\n+                    a$.set('c');\n+                    shouldNotHaveReacted('b');\n+\n+                    when.set(true);\n+                    shouldHaveReactedOnce('c');\n+                });\n+\n+                it('should disconnect from the base when `when` is false', () => {\n+                    when.set(true);\n+                    startTest({ when });\n+\n+                    expect(a$.connected).to.be.true;\n+                    expect(when.connected).to.be.true;\n+\n+                    when.set(false);\n+\n+                    expect(a$.connected).to.be.false;\n+                    expect(when.connected).to.be.true;\n+\n+                    stopTest();\n+\n+                    expect(when.connected).to.be.false;\n+                });\n+\n+                context('inside transactions', () => {\n+                    it('should be live', () => {\n+                        a$.set('a');\n+                        const f$ = startTest({ when });\n+\n+                        when.set(true);\n+                        expect(f$.value).to.equal('a');\n+\n+                        transact(() => {\n+                            a$.set('b');\n+                            expect(f$.value).to.equal('b');\n+\n+                            // Always represents state that should be visible after the transaction:\n+                            when.set(false);\n+                            expect(f$.value).to.equal('a');\n+\n+                            when.set(true);\n+                            expect(f$.value).to.equal('b');\n+\n+                            when.set(false);\n+                        });\n+\n+                        expect(f$.value).to.equal('a');\n+                    });\n+\n+                    it('should be consistent', () => {\n+                        when.set(true);\n+                        a$.set('a');\n+                        startTest({ when });\n+\n+                        shouldHaveReactedOnce('a');\n+\n+                        when.set(false);\n+\n+                        transact(() => {\n+                            when.set(true);\n+                            a$.set('b');\n+                            a$.set('c');\n+                            when.set(false);\n+                        });\n+\n+                        shouldNotHaveReacted('a');\n+                    });\n+\n+                    it('should also work with derived `when` option', () => {\n+                        const f$ = startTest({ when: d => d.getOr('').length > 3 });\n+\n+                        shouldNotHaveReacted(unresolved);\n+\n+                        a$.set('abc');\n+                        expect(f$.value).to.be.undefined;\n+                        a$.set('abcd');\n+                        expect(f$.value).to.be.equal('abcd');\n+\n+                        transact(() => {\n+                            a$.set('abcde');\n+                            expect(f$.value).to.be.equal('abcde');\n+                            a$.set('ab');\n+                            expect(f$.value).to.be.equal('abcd');\n+                            a$.unset();\n+                            expect(f$.value).to.be.equal('abcd');\n+                        });\n+\n+                        expect(f$.value).to.be.equal('abcd');\n+                    });\n+                });\n+            });\n+\n+            describe('once', () => {\n+                it('should update only once and keep the value after that', () => {\n+                    startTest({ once: true });\n+                    shouldNotHaveReacted(unresolved);\n+                    a$.set('a');\n+\n+                    // `includeUnresolved` is awkward in combination with `once`.\n+                    if (includeUnresolved) {\n+                        shouldNotHaveReacted(unresolved);\n+                        a$.set('b');\n+                        shouldNotHaveReacted(unresolved);\n+                    } else {\n+                        shouldHaveReactedOnce('a');\n+                        a$.set('b');\n+                        shouldNotHaveReacted('a');\n+                    }\n+                });\n+\n+                it('should count an error as an update and thus stop after the first', () => {\n+                    startTest({ once: true });\n+                    shouldNotHaveReacted(unresolved);\n+\n+                    a$.setError('my error');\n+                    includeUnresolved\n+                        ? shouldNotHaveReacted(unresolved)\n+                        : shouldHaveReactedOnce(new _internal.ErrorWrapper('my error'));\n+\n+                    a$.setError('another error');\n+                    shouldNotHaveReacted(includeUnresolved ? unresolved : new _internal.ErrorWrapper('my error'));\n+\n+                    a$.set('a');\n+                    shouldNotHaveReacted(includeUnresolved ? unresolved : new _internal.ErrorWrapper('my error'));\n+                    a$.set('b');\n+                    shouldNotHaveReacted(includeUnresolved ? unresolved : new _internal.ErrorWrapper('my error'));\n+                });\n+\n+                it('should support a synchronous `once` without maintaining garbage', () => {\n+                    a$.set('synchronous value');\n+                    let connectionChanges = 0;\n+                    a$.connected$.react(() => connectionChanges++, { skipFirst: true });\n+\n+                    const f$ = startTest({ once: true });\n+\n+                    expect((f$ as any)._baseConnectionStopper).to.be.undefined;\n+\n+                    expect(connectionChanges).to.equal(2);\n+                    expect(f$.get()).to.equal('synchronous value');\n+                    expect(connectionChanges).to.equal(2);\n+                });\n+\n+                it('should disconnect after the first value', () => {\n+                    let connectionChanges = 0;\n+                    a$.connected$.react(() => connectionChanges++, { skipFirst: true });\n+\n+                    const f$ = startTest({ once: true });\n+\n+                    expect(f$.resolved).to.be.false;\n+\n+                    if (includeUnresolved) {\n+\n+                        expect(connectionChanges).to.equal(2);\n+                        expect((f$ as any)._baseConnectionStopper).to.be.undefined;\n+\n+                        a$.set('asynchronous value');\n+\n+                        expect(f$.resolved).to.be.false;\n+                        expect(connectionChanges).to.equal(2);\n+\n+                    } else {\n+\n+                        expect(connectionChanges).to.equal(1);\n+                        expect((f$ as any)._baseConnectionStopper).to.be.a('function');\n+\n+                        a$.set('asynchronous value');\n+\n+                        expect(connectionChanges).to.equal(2);\n+                        expect((f$ as any)._baseConnectionStopper).to.be.undefined;\n+\n+                        expect(f$.get()).to.equal('asynchronous value');\n+                        expect(connectionChanges).to.equal(2);\n+                    }\n+                });\n+\n+                it('should consider a transaction as one big update', () => {\n+                    const f$ = startTest({ once: true });\n+\n+                    transact(() => {\n+                        a$.set('a');\n+                        expect(f$.value).to.equal('a');\n+                        a$.set('b');\n+                        expect(f$.value).to.equal('b');\n+                        a$.set('c');\n+                        expect(f$.value).to.equal('c');\n+                    });\n+\n+                    includeUnresolved\n+                        ? shouldNotHaveReacted(unresolved)\n+                        : shouldHaveReactedOnce('c');\n+                });\n+            });\n+\n+            describe('skipFirst', () => {","path":"extensions/sherlock-utils/src/control-flow.spec.ts","position":606,"original_position":606,"commit_id":"0cbb080d8ddbdfd2a1384f808c66627f272be85e","original_commit_id":"0cbb080d8ddbdfd2a1384f808c66627f272be85e","user":{"login":"njirem","id":9287286,"node_id":"MDQ6VXNlcjkyODcyODY=","avatar_url":"https://avatars2.githubusercontent.com/u/9287286?v=4","gravatar_id":"","url":"https://api.github.com/users/njirem","html_url":"https://github.com/njirem","followers_url":"https://api.github.com/users/njirem/followers","following_url":"https://api.github.com/users/njirem/following{/other_user}","gists_url":"https://api.github.com/users/njirem/gists{/gist_id}","starred_url":"https://api.github.com/users/njirem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/njirem/subscriptions","organizations_url":"https://api.github.com/users/njirem/orgs","repos_url":"https://api.github.com/users/njirem/repos","events_url":"https://api.github.com/users/njirem/events{/privacy}","received_events_url":"https://api.github.com/users/njirem/received_events","type":"User","site_admin":false},"body":"Should `skipFirst` not also consider a transaction as 'one big update'?","created_at":"2018-07-27T09:00:14Z","updated_at":"2018-07-27T09:03:07Z","html_url":"https://github.com/politie/sherlock/pull/106#discussion_r205710028","pull_request_url":"https://api.github.com/repos/politie/sherlock/pulls/106","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/politie/sherlock/pulls/comments/205710028"},"html":{"href":"https://github.com/politie/sherlock/pull/106#discussion_r205710028"},"pull_request":{"href":"https://api.github.com/repos/politie/sherlock/pulls/106"}}},"pull_request":{"url":"https://api.github.com/repos/politie/sherlock/pulls/106","id":203546591,"node_id":"MDExOlB1bGxSZXF1ZXN0MjAzNTQ2NTkx","html_url":"https://github.com/politie/sherlock/pull/106","diff_url":"https://github.com/politie/sherlock/pull/106.diff","patch_url":"https://github.com/politie/sherlock/pull/106.patch","issue_url":"https://api.github.com/repos/politie/sherlock/issues/106","number":106,"state":"open","locked":false,"title":"Adds controlFlow operator","user":{"login":"pavadeli","id":5168053,"node_id":"MDQ6VXNlcjUxNjgwNTM=","avatar_url":"https://avatars3.githubusercontent.com/u/5168053?v=4","gravatar_id":"","url":"https://api.github.com/users/pavadeli","html_url":"https://github.com/pavadeli","followers_url":"https://api.github.com/users/pavadeli/followers","following_url":"https://api.github.com/users/pavadeli/following{/other_user}","gists_url":"https://api.github.com/users/pavadeli/gists{/gist_id}","starred_url":"https://api.github.com/users/pavadeli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pavadeli/subscriptions","organizations_url":"https://api.github.com/users/pavadeli/orgs","repos_url":"https://api.github.com/users/pavadeli/repos","events_url":"https://api.github.com/users/pavadeli/events{/privacy}","received_events_url":"https://api.github.com/users/pavadeli/received_events","type":"User","site_admin":false},"body":"","created_at":"2018-07-24T14:27:57Z","updated_at":"2018-07-27T09:03:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"54c9bf34e64a9df72e3a06bcd072b1e4468dc505","assignee":{"login":"njirem","id":9287286,"node_id":"MDQ6VXNlcjkyODcyODY=","avatar_url":"https://avatars2.githubusercontent.com/u/9287286?v=4","gravatar_id":"","url":"https://api.github.com/users/njirem","html_url":"https://github.com/njirem","followers_url":"https://api.github.com/users/njirem/followers","following_url":"https://api.github.com/users/njirem/following{/other_user}","gists_url":"https://api.github.com/users/njirem/gists{/gist_id}","starred_url":"https://api.github.com/users/njirem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/njirem/subscriptions","organizations_url":"https://api.github.com/users/njirem/orgs","repos_url":"https://api.github.com/users/njirem/repos","events_url":"https://api.github.com/users/njirem/events{/privacy}","received_events_url":"https://api.github.com/users/njirem/received_events","type":"User","site_admin":false},"assignees":[{"login":"njirem","id":9287286,"node_id":"MDQ6VXNlcjkyODcyODY=","avatar_url":"https://avatars2.githubusercontent.com/u/9287286?v=4","gravatar_id":"","url":"https://api.github.com/users/njirem","html_url":"https://github.com/njirem","followers_url":"https://api.github.com/users/njirem/followers","following_url":"https://api.github.com/users/njirem/following{/other_user}","gists_url":"https://api.github.com/users/njirem/gists{/gist_id}","starred_url":"https://api.github.com/users/njirem/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/njirem/subscriptions","organizations_url":"https://api.github.com/users/njirem/orgs","repos_url":"https://api.github.com/users/njirem/repos","events_url":"https://api.github.com/users/njirem/events{/privacy}","received_events_url":"https://api.github.com/users/njirem/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"wvanderdeijl","id":7952432,"node_id":"MDQ6VXNlcjc5NTI0MzI=","avatar_url":"https://avatars1.githubusercontent.com/u/7952432?v=4","gravatar_id":"","url":"https://api.github.com/users/wvanderdeijl","html_url":"https://github.com/wvanderdeijl","followers_url":"https://api.github.com/users/wvanderdeijl/followers","following_url":"https://api.github.com/users/wvanderdeijl/following{/other_user}","gists_url":"https://api.github.com/users/wvanderdeijl/gists{/gist_id}","starred_url":"https://api.github.com/users/wvanderdeijl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wvanderdeijl/subscriptions","organizations_url":"https://api.github.com/users/wvanderdeijl/orgs","repos_url":"https://api.github.com/users/wvanderdeijl/repos","events_url":"https://api.github.com/users/wvanderdeijl/events{/privacy}","received_events_url":"https://api.github.com/users/wvanderdeijl/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[{"id":731736002,"node_id":"MDU6TGFiZWw3MzE3MzYwMDI=","url":"https://api.github.com/repos/politie/sherlock/labels/enhancement","name":"enhancement","color":"84b6eb","default":true}],"milestone":{"url":"https://api.github.com/repos/politie/sherlock/milestones/1","html_url":"https://github.com/politie/sherlock/milestone/1","labels_url":"https://api.github.com/repos/politie/sherlock/milestones/1/labels","id":3336053,"node_id":"MDk6TWlsZXN0b25lMzMzNjA1Mw==","number":1,"title":"2.0","description":"Second generation Sherlock with support for asynchronous initialisation and several API improvements.","creator":{"login":"pavadeli","id":5168053,"node_id":"MDQ6VXNlcjUxNjgwNTM=","avatar_url":"https://avatars3.githubusercontent.com/u/5168053?v=4","gravatar_id":"","url":"https://api.github.com/users/pavadeli","html_url":"https://github.com/pavadeli","followers_url":"https://api.github.com/users/pavadeli/followers","following_url":"https://api.github.com/users/pavadeli/following{/other_user}","gists_url":"https://api.github.com/users/pavadeli/gists{/gist_id}","starred_url":"https://api.github.com/users/pavadeli/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pavadeli/subscriptions","organizations_url":"https://api.github.com/users/pavadeli/orgs","repos_url":"https://api.github.com/users/pavadeli/repos","events_url":"https://api.github.com/users/pavadeli/events{/privacy}","received_events_url":"https://api.github.com/users/pavadeli/received_events","type":"User","site_admin":false},"open_issues":3,"closed_issues":26,"state":"open","created_at":"2018-05-10T13:44:40Z","updated_at":"2018-07-24T14:28:07Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/politie/sherlock/pulls/106/commits","review_comments_url":"https://api.github.com/repos/politie/sherlock/pulls/106/comments","review_comment_url":"https://api.github.com/repos/politie/sherlock/pulls/comments{/number}","comments_url":"https://api.github.com/repos/politie/sherlock/issues/106/comments","statuses_url":"https://api.github.com/repos/politie/sherlock/statuses/0cbb080d8ddbdfd2a1384f808c66627f272be85e","head":{"label":"politie:adds-retain-value-operator","ref":"adds-retain-value-operator","sha":"0cbb080d8ddbdfd2a1384f808c66627f272be85e","user":{"login":"politie","id":5601263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU2MDEyNjM=","avatar_url":"https://avatars0.githubusercontent.com/u/5601263?v=4","gravatar_id":"","url":"https://api.github.com/users/politie","html_url":"https://github.com/politie","followers_url":"https://api.github.com/users/politie/followers","following_url":"https://api.github.com/users/politie/following{/other_user}","gists_url":"https://api.github.com/users/politie/gists{/gist_id}","starred_url":"https://api.github.com/users/politie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/politie/subscriptions","organizations_url":"https://api.github.com/users/politie/orgs","repos_url":"https://api.github.com/users/politie/repos","events_url":"https://api.github.com/users/politie/events{/privacy}","received_events_url":"https://api.github.com/users/politie/received_events","type":"Organization","site_admin":false},"repo":{"id":108414113,"node_id":"MDEwOlJlcG9zaXRvcnkxMDg0MTQxMTM=","name":"sherlock","full_name":"politie/sherlock","owner":{"login":"politie","id":5601263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU2MDEyNjM=","avatar_url":"https://avatars0.githubusercontent.com/u/5601263?v=4","gravatar_id":"","url":"https://api.github.com/users/politie","html_url":"https://github.com/politie","followers_url":"https://api.github.com/users/politie/followers","following_url":"https://api.github.com/users/politie/following{/other_user}","gists_url":"https://api.github.com/users/politie/gists{/gist_id}","starred_url":"https://api.github.com/users/politie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/politie/subscriptions","organizations_url":"https://api.github.com/users/politie/orgs","repos_url":"https://api.github.com/users/politie/repos","events_url":"https://api.github.com/users/politie/events{/privacy}","received_events_url":"https://api.github.com/users/politie/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/politie/sherlock","description":"A reactive programming library for JavaScript applications, built with TypeScript.","fork":false,"url":"https://api.github.com/repos/politie/sherlock","forks_url":"https://api.github.com/repos/politie/sherlock/forks","keys_url":"https://api.github.com/repos/politie/sherlock/keys{/key_id}","collaborators_url":"https://api.github.com/repos/politie/sherlock/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/politie/sherlock/teams","hooks_url":"https://api.github.com/repos/politie/sherlock/hooks","issue_events_url":"https://api.github.com/repos/politie/sherlock/issues/events{/number}","events_url":"https://api.github.com/repos/politie/sherlock/events","assignees_url":"https://api.github.com/repos/politie/sherlock/assignees{/user}","branches_url":"https://api.github.com/repos/politie/sherlock/branches{/branch}","tags_url":"https://api.github.com/repos/politie/sherlock/tags","blobs_url":"https://api.github.com/repos/politie/sherlock/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/politie/sherlock/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/politie/sherlock/git/refs{/sha}","trees_url":"https://api.github.com/repos/politie/sherlock/git/trees{/sha}","statuses_url":"https://api.github.com/repos/politie/sherlock/statuses/{sha}","languages_url":"https://api.github.com/repos/politie/sherlock/languages","stargazers_url":"https://api.github.com/repos/politie/sherlock/stargazers","contributors_url":"https://api.github.com/repos/politie/sherlock/contributors","subscribers_url":"https://api.github.com/repos/politie/sherlock/subscribers","subscription_url":"https://api.github.com/repos/politie/sherlock/subscription","commits_url":"https://api.github.com/repos/politie/sherlock/commits{/sha}","git_commits_url":"https://api.github.com/repos/politie/sherlock/git/commits{/sha}","comments_url":"https://api.github.com/repos/politie/sherlock/comments{/number}","issue_comment_url":"https://api.github.com/repos/politie/sherlock/issues/comments{/number}","contents_url":"https://api.github.com/repos/politie/sherlock/contents/{+path}","compare_url":"https://api.github.com/repos/politie/sherlock/compare/{base}...{head}","merges_url":"https://api.github.com/repos/politie/sherlock/merges","archive_url":"https://api.github.com/repos/politie/sherlock/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/politie/sherlock/downloads","issues_url":"https://api.github.com/repos/politie/sherlock/issues{/number}","pulls_url":"https://api.github.com/repos/politie/sherlock/pulls{/number}","milestones_url":"https://api.github.com/repos/politie/sherlock/milestones{/number}","notifications_url":"https://api.github.com/repos/politie/sherlock/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/politie/sherlock/labels{/name}","releases_url":"https://api.github.com/repos/politie/sherlock/releases{/id}","deployments_url":"https://api.github.com/repos/politie/sherlock/deployments","created_at":"2017-10-26T13:19:42Z","updated_at":"2018-07-25T07:05:04Z","pushed_at":"2018-07-27T08:31:27Z","git_url":"git://github.com/politie/sherlock.git","ssh_url":"git@github.com:politie/sherlock.git","clone_url":"https://github.com/politie/sherlock.git","svn_url":"https://github.com/politie/sherlock","homepage":null,"size":572,"stargazers_count":17,"watchers_count":17,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":8,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":3,"open_issues":8,"watchers":17,"default_branch":"master"}},"base":{"label":"politie:master","ref":"master","sha":"c220fcfe2f11c885cc51d24f6137b60cd56ed93b","user":{"login":"politie","id":5601263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU2MDEyNjM=","avatar_url":"https://avatars0.githubusercontent.com/u/5601263?v=4","gravatar_id":"","url":"https://api.github.com/users/politie","html_url":"https://github.com/politie","followers_url":"https://api.github.com/users/politie/followers","following_url":"https://api.github.com/users/politie/following{/other_user}","gists_url":"https://api.github.com/users/politie/gists{/gist_id}","starred_url":"https://api.github.com/users/politie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/politie/subscriptions","organizations_url":"https://api.github.com/users/politie/orgs","repos_url":"https://api.github.com/users/politie/repos","events_url":"https://api.github.com/users/politie/events{/privacy}","received_events_url":"https://api.github.com/users/politie/received_events","type":"Organization","site_admin":false},"repo":{"id":108414113,"node_id":"MDEwOlJlcG9zaXRvcnkxMDg0MTQxMTM=","name":"sherlock","full_name":"politie/sherlock","owner":{"login":"politie","id":5601263,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU2MDEyNjM=","avatar_url":"https://avatars0.githubusercontent.com/u/5601263?v=4","gravatar_id":"","url":"https://api.github.com/users/politie","html_url":"https://github.com/politie","followers_url":"https://api.github.com/users/politie/followers","following_url":"https://api.github.com/users/politie/following{/other_user}","gists_url":"https://api.github.com/users/politie/gists{/gist_id}","starred_url":"https://api.github.com/users/politie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/politie/subscriptions","organizations_url":"https://api.github.com/users/politie/orgs","repos_url":"https://api.github.com/users/politie/repos","events_url":"https://api.github.com/users/politie/events{/privacy}","received_events_url":"https://api.github.com/users/politie/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/politie/sherlock","description":"A reactive programming library for JavaScript applications, built with TypeScript.","fork":false,"url":"https://api.github.com/repos/politie/sherlock","forks_url":"https://api.github.com/repos/politie/sherlock/forks","keys_url":"https://api.github.com/repos/politie/sherlock/keys{/key_id}","collaborators_url":"https://api.github.com/repos/politie/sherlock/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/politie/sherlock/teams","hooks_url":"https://api.github.com/repos/politie/sherlock/hooks","issue_events_url":"https://api.github.com/repos/politie/sherlock/issues/events{/number}","events_url":"https://api.github.com/repos/politie/sherlock/events","assignees_url":"https://api.github.com/repos/politie/sherlock/assignees{/user}","branches_url":"https://api.github.com/repos/politie/sherlock/branches{/branch}","tags_url":"https://api.github.com/repos/politie/sherlock/tags","blobs_url":"https://api.github.com/repos/politie/sherlock/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/politie/sherlock/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/politie/sherlock/git/refs{/sha}","trees_url":"https://api.github.com/repos/politie/sherlock/git/trees{/sha}","statuses_url":"https://api.github.com/repos/politie/sherlock/statuses/{sha}","languages_url":"https://api.github.com/repos/politie/sherlock/languages","stargazers_url":"https://api.github.com/repos/politie/sherlock/stargazers","contributors_url":"https://api.github.com/repos/politie/sherlock/contributors","subscribers_url":"https://api.github.com/repos/politie/sherlock/subscribers","subscription_url":"https://api.github.com/repos/politie/sherlock/subscription","commits_url":"https://api.github.com/repos/politie/sherlock/commits{/sha}","git_commits_url":"https://api.github.com/repos/politie/sherlock/git/commits{/sha}","comments_url":"https://api.github.com/repos/politie/sherlock/comments{/number}","issue_comment_url":"https://api.github.com/repos/politie/sherlock/issues/comments{/number}","contents_url":"https://api.github.com/repos/politie/sherlock/contents/{+path}","compare_url":"https://api.github.com/repos/politie/sherlock/compare/{base}...{head}","merges_url":"https://api.github.com/repos/politie/sherlock/merges","archive_url":"https://api.github.com/repos/politie/sherlock/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/politie/sherlock/downloads","issues_url":"https://api.github.com/repos/politie/sherlock/issues{/number}","pulls_url":"https://api.github.com/repos/politie/sherlock/pulls{/number}","milestones_url":"https://api.github.com/repos/politie/sherlock/milestones{/number}","notifications_url":"https://api.github.com/repos/politie/sherlock/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/politie/sherlock/labels{/name}","releases_url":"https://api.github.com/repos/politie/sherlock/releases{/id}","deployments_url":"https://api.github.com/repos/politie/sherlock/deployments","created_at":"2017-10-26T13:19:42Z","updated_at":"2018-07-25T07:05:04Z","pushed_at":"2018-07-27T08:31:27Z","git_url":"git://github.com/politie/sherlock.git","ssh_url":"git@github.com:politie/sherlock.git","clone_url":"https://github.com/politie/sherlock.git","svn_url":"https://github.com/politie/sherlock","homepage":null,"size":572,"stargazers_count":17,"watchers_count":17,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":8,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":3,"open_issues":8,"watchers":17,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/politie/sherlock/pulls/106"},"html":{"href":"https://github.com/politie/sherlock/pull/106"},"issue":{"href":"https://api.github.com/repos/politie/sherlock/issues/106"},"comments":{"href":"https://api.github.com/repos/politie/sherlock/issues/106/comments"},"review_comments":{"href":"https://api.github.com/repos/politie/sherlock/pulls/106/comments"},"review_comment":{"href":"https://api.github.com/repos/politie/sherlock/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/politie/sherlock/pulls/106/commits"},"statuses":{"href":"https://api.github.com/repos/politie/sherlock/statuses/0cbb080d8ddbdfd2a1384f808c66627f272be85e"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"njirem"}}