{"_id":"@bunch-of-friends/observable","_rev":"9-9676afb0974421d28a3e6f720bce6757","name":"@bunch-of-friends/observable","dist-tags":{"latest":"1.4.1","alpha":"1.1.0"},"versions":{"1.0.0":{"name":"@bunch-of-friends/observable","version":"1.0.0","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint --fix 'src/**/*.ts{,x}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^22.1.3","jest":"^22.3.0","rimraf":"^2.6.2","ts-jest":"^22.0.4","tslint":"^5.9.1","tslint-config-bunch-of-friends":"^1.0.1","tslint-eslint-rules":"^5.0.0","typescript":"^2.7.2"},"gitHead":"075b46188836414b3e73a995c2111848468e9389","_id":"@bunch-of-friends/observable@1.0.0","_npmVersion":"5.6.0","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-VEdhWP5PLRWD9EBA/mZD7vevV1VboHvEHjv5VmxzCdoYXhLPwFEvr4uO9Bi1Ok+5gG0Euysi23QXALZs7o2A6Q==","shasum":"ce046a2a7c2fd028a68cc5ad60f83b6ded2c2d32","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.0.0.tgz","fileCount":15,"unpackedSize":15722,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/zwwKEzwpDI+Fn1peuCMLuJFKLVu2q1bADyFB7mhECAIhAN6DLyWJM96M5l6373McBdaqvJ2QPJddLBwBhx7WKYbx"}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.0.0_1519584805832_0.0878164534355459"},"_hasShrinkwrap":false},"1.1.0":{"name":"@bunch-of-friends/observable","version":"1.1.0","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint --fix 'src/**/*.ts{,x}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^22.1.3","jest":"^22.3.0","rimraf":"^2.6.2","ts-jest":"^22.0.4","tslint":"^5.9.1","tslint-config-bunch-of-friends":"^1.0.1","tslint-eslint-rules":"^5.0.0","typescript":"^2.7.2"},"readme":"# @bunch-of-friends/observable\n\n[![License](https://img.shields.io/github/license/mashape/apistatus.svg?style=flat-square)](https://github.com/bunch-of-friends/lerna-typescript-jest-boilerplate/blob/master/LICENSE)\n[![npm version](https://badge.fury.io/js/%40bunch-of-friends%2Fobservable.svg)](https://badge.fury.io/js/%40bunch-of-friends%2Fobservable)\n[![CircleCI](https://circleci.com/gh/bunch-of-friends/observable.svg?style=svg)](https://circleci.com/gh/bunch-of-friends/observable)\n\nA simple implementation of the [observer pattern](https://en.wikipedia.org/wiki/Observer_pattern) written in TypeScript, usable in JavaScript as well.\n\n## Key objects\nThere are three key objects: [Subject](https://github.com/bunch-of-friends/observable/blob/master/src/subject.ts), [Observable](https://github.com/bunch-of-friends/observable/blob/master/src/observable.ts) and [Observer](https://github.com/bunch-of-friends/observable/blob/master/src/observer.ts).\n\n### Observer\nA function, which gets called on a change.\n```ts\nexport interface Observer<T> {\n    (newState: T, previousState?: T): void;\n}\n```\n\n### Subject\nObject responsible for maintaining a list of observers, keeping track of the state and notifying its changes.\nSubject is intended to be used internally and shouldn't be exposed outside of the object using it.\n```ts\nexport interface Subject<T> {\n    registerObserver(observer: Observer<T>, owner: Object): Observer<T>;\n    unregisterObserver(observer: Observer<T>): void;\n    unregisterObserversOfOwner(owner: Object): void;\n    unregisterAllObservers(): void;\n    notifyObservers(newState?: T): void;\n    getCurrentState(): T;\n}\n```\n\n### Observable\nObservable is a subset of Subject and is intended to be exposed outside of the object using it. Users of the Observable can freely register and unregister, but cannot notify changes.\n```ts\nexport interface Observable<T> {\n    register: (observer: Observer<T>) => Observer<T>;\n    unregister: (observer: Observer<T>) => void;\n    unregisterAll: () => void;\n}\n```\n\n## Usage\nThe library is published to npm as commonjs ES5 module. It is intended to be used in browser, but requires a module bundler.\nThe library comes with embedded TypeScript types, so it is easy to use in TypeScript, but it can be used as well in JavaScript.\n\n```bash\nnpm install @bunch-of-friends/observable --save\n```\n\nUse the `createSubject` function to create an instance of Subject:\n```ts\nimport { createSubject } from '@bunch-of-friends/observable';\n\nconst subject = createSubject<T>(); //replace `T` with type of the object that the observers will be notified with\n\nsubject.registerObserver(currentState => /* ... */ );\n\nsubject.notifyChanges({ /* ... */ }); // the argument of notifyChanges is of type `T`\n```\n\nTo create an observable that can be used for registering and unregistering observers only, use the `createObservable` function:\n```ts\nimport { createObservable } from '@bunch-of-friends/observable';\n\nconst observable = createObservable(subject); // as created earlier\n\nobservable.register(currentState => /* ... */ );\n```\n\nYou can also create an observable that only filters only changes that match a specific values, use the `createObservableForValue` function:\n```ts\nimport { createSubject, createObservableForValue } from '@bunch-of-friends/observable';\n\nenum State {\n    Loading,\n    Loaded\n}\n\nconst subject = createSubject<State>();\nconst observable = createObservableForValue(subject, State.Loaded);\nobservable.registerObserver(() => console.log('state changed to loaded'))\n\nsubject.notifyChanges(State.Loading); // this will not call the observer\nsubject.notifyChanges(State.Loaded); // this will call the observer\n\n```\n\n## Example\nA simple example demonstrating the intended use:\n```ts\nimport { createSubject, createObservable, createObservableForValue } from '@bunch-of-friends/observable';\n\nenum State {\n    Loading,\n    Loaded\n}\n\nclass Component {\n    private stateSubject = createSubject<State>();\n\n    // use this to subscribe to any state change\n    public onStateChanged = createObservable(stateSubject);\n\n    // shorthand if you only want to subscribe to the state chaning to Stopped\n    public onLoaded = createObservableForValue(stateSubject, State.Stopped);\n\n    constructor() {\n        // notifyChanges would usually be called by some more reasonable code\n        setTimeout(() => this.stateSubject.notifyChanges(State.Loading), 1000);\n        setTimeout(() => this.stateSubject.notifyChanges(State.Loaded), 2000);\n    }\n\n    public dispose() {\n        this.stateSubject.unregisterAllObservers();\n    }\n}\n\nclass ComponentConsumer {\n    constructor(component: Component) {\n        component.onStateChanged.register((state) => console.log('current state is: ' + state));\n        component.onLoaded.register(() => console.log('component loaded'));\n    }\n}\n```\n\n## Classes vs closures\nWhy are the `Subject` and `Observable` not ES6 classes?\nThe reason is that the classes would have private fields, for example `Subject` would have private field `registeredObservers`. The TypeScript complier doesn't allow other TypeScript code to acess it, but in plain JavaScript, the private fields will be accessible and that will violate the open/close principle.\n\nIn the example above, we use ES6 class, try running similar code. You will be able to access the private field `stateSubject`, which is not inteded, in TypeScript it is marked as private.\n\nTherefore the `createSubject` and `createObservable` act as constructors and and we use closures instead of hide the private variables from the users.\n","readmeFilename":"README.md","gitHead":"c3fa4e67901c0ac47a3dffadc0279ee096e36115","_id":"@bunch-of-friends/observable@1.1.0","_npmVersion":"5.8.0","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-HJ0gJK2gcHflMfnbZVfQ5AEV8aNoS6o6z6ZSUG2Sz8Df+fgFHVooIBKLs1x+9arXEWCjtmjiz66ERYV6uosiOg==","shasum":"73a322ff4591dac83db14581b03b5a6605ed7104","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.1.0.tgz","fileCount":15,"unpackedSize":18212,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCTg0df8iqMg9KldUcu0L0ZBnXpEPpeC/mcd15Vw/Fn0gIgKmKyYJse86FX5pDzv8cokamNa3/A4RFhBWeoL9BkLqo="}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.1.0_1522510883023_0.6269693656684441"},"_hasShrinkwrap":false},"1.1.1":{"name":"@bunch-of-friends/observable","version":"1.1.1","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint --fix 'src/**/*.ts{,x}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^22.1.3","jest":"^22.3.0","rimraf":"^2.6.2","ts-jest":"^22.0.4","tslint":"^5.9.1","tslint-config-bunch-of-friends":"^1.0.1","tslint-eslint-rules":"^5.0.0","typescript":"^2.7.2"},"gitHead":"c3fa4e67901c0ac47a3dffadc0279ee096e36115","_id":"@bunch-of-friends/observable@1.1.1","_npmVersion":"5.8.0","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-Yzklv8UwymR/u+9E06ERhO6JH7glHXxMmrNyxTA+TsCWdYrH1XBOd+bGO71WzV+Fbe9ov73hFYzrqs7HWZrj/Q==","shasum":"c6c58a9b817f9705043a19d0c5e0584ec3e39b71","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.1.1.tgz","fileCount":15,"unpackedSize":16430,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCNFnzskx7kXy1L95MtUOaL/O8UgRCOgAFjkjQy2o8PeQIhAIo43UTqqdKwH3SiNpojwvxC4oF1p5JwB6aROhuvt+UE"}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.1.1_1522511352411_0.061478819129402895"},"_hasShrinkwrap":false},"1.1.2":{"name":"@bunch-of-friends/observable","version":"1.1.2","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint --fix 'src/**/*.ts{,x}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^22.1.3","jest":"^22.3.0","rimraf":"^2.6.2","ts-jest":"^22.0.4","tslint":"^5.9.1","tslint-config-bunch-of-friends":"^1.0.1","tslint-eslint-rules":"^5.0.0","typescript":"^2.7.2"},"gitHead":"c3fa4e67901c0ac47a3dffadc0279ee096e36115","_id":"@bunch-of-friends/observable@1.1.2","_npmVersion":"5.8.0","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-wyBb+1EC2rqIFAulSbuMIWkoaP7mop6PLzdho4nOkYcHzFQYlgqPg1IDJUM0Ix+Of+C6IsYvPN5xM/chDkAgdg==","shasum":"b4c4d4d1e225bb0bcb3180a3d8be58c59d6db64b","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.1.2.tgz","fileCount":15,"unpackedSize":16164,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICFv42UsL8Fel71QjHZS2pkz3Cr2JaEa1oEDM33QgFChAiAy8I97Sg3UFX9G68KHscAhfT0IA6Te6JmfkPEv5Oifxw=="}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.1.2_1522511592519_0.6439503673114411"},"_hasShrinkwrap":false},"1.2.0":{"name":"@bunch-of-friends/observable","version":"1.2.0","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint --fix 'src/**/*.ts{,x}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^22.1.3","jest":"^22.3.0","rimraf":"^2.6.2","ts-jest":"^22.0.4","tslint":"^5.9.1","tslint-config-bunch-of-friends":"^1.0.1","tslint-eslint-rules":"^5.0.0","typescript":"^2.7.2"},"gitHead":"c3e20ef83ce8e6a6ce53afcffbdb1ffbe52c8ef3","_id":"@bunch-of-friends/observable@1.2.0","_npmVersion":"5.8.0","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-LZu2dXO/9z0+sikSyQKwjv6ScvwRhtiZ6WU4LaQYQLbVQR74LBL6ykr0lUuV2Ye1zZSA+0dswuJ6ai2X2lqd6g==","shasum":"ea4f619aa3238292b20a66eda670f87c20a68b65","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.2.0.tgz","fileCount":15,"unpackedSize":17095,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBZuS25JEfSecI54q71V9ViP1HrlTsry9Oo2gu5v7sGrAiEA90sLWN5NXW+OHs95O2CJoHl8Q2ij5DxKD1neAMgl1DY="}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.2.0_1522666825765_0.2464679885865657"},"_hasShrinkwrap":false},"1.3.0":{"name":"@bunch-of-friends/observable","version":"1.3.0","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint --fix 'src/**/*.ts{,x}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^22.1.3","jest":"^22.3.0","rimraf":"^2.6.2","ts-jest":"^22.0.4","tslint":"^5.9.1","tslint-config-bunch-of-friends":"^1.0.1","tslint-eslint-rules":"^5.0.0","typescript":"^2.7.2"},"gitHead":"08a980ef71c58ec9e655405a6036a9cae1ed4de6","_id":"@bunch-of-friends/observable@1.3.0","_npmVersion":"5.8.0","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-M6YmkACWxcbOYUdIB9JtPIAGvWrgwax9Bz30zEqKm8wBI/WJ738ml3XwswBj4M7f/mP7yrcf9UA9t4+FMFyCXA==","shasum":"f08381b5232029b2ed55c2a5b8fd7c0965c9d713","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.3.0.tgz","fileCount":15,"unpackedSize":17177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa26lLCRA9TVsSAnZWagAADdwP/iKBWdkV+EM5JhCmtO6N\nfa6PlgYtRuutlviKxgzgJZ4vGGZ5xaoHI1etpQN0dLbxqyg3Ytd94OszXgXq\nmAagzF1pWagbMf2Ow56+hXG3OX+XDHlX+UDLetljqT7njbboR+Y2KSkNxDzX\nDch3RUho2qkk04eiivIlDVxuOdBR6CGZTSP5Y6YBGhjfHPKkg0dAXM9xJbHU\neK80ey3gKtbjsDbQBRoasTop+UL6V546rYQBOPoNGaI9njtgbBDyYKmY4juG\ngyiP8QxLrSXXJlFtKoc59kkSAjkjZMcxsWYIMUGJs4NQQr6reKnoQ6un46oY\nMWSxGBsluvDBT9ta0WQuBeXcx8UGhtcR3bPcvOOCcVSLZT8EYTDkl6ERvO45\nhy0BStRcIfDDRWWzTqbTk3YdYA57Q0+8bwhXdv3cdM5dVvOve6MeoaZk5aV4\nfQy2naGb0QpjAR0N/zv5slfMnilZh2nAVAWRDPRi5xNvdfTQBJxcK3m7ROBg\nzZ+cGO57W1U+llSAvAUq17ASGgvBVlWK31vAJ0BurWn0My4Sd6jlrf+TajEz\n2Opod0/MXE8FFJkTXhZ0D4JbyGC6iEY46Bb8mNI2cxFPgv9QtQ/Ya+ineMHf\nJNhdJMvzCc3yZc9vBqPzMw4C0DAN1C5t2vjVVsiT0mwhlrIkfbCBt1SOTfDZ\nGfPK\r\n=ZF9F\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFhTR9ysCnvtnIaj/W/G6a/PRX6y2XsFUHbC556vimMKAiB5mcsx/yGeysqT0aftVSKWEHqxzyqfJsZOiop4BMJGSw=="}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.3.0_1524345162702_0.774280145865051"},"_hasShrinkwrap":false},"1.4.0":{"name":"@bunch-of-friends/observable","version":"1.4.0","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint --fix 'src/**/*.ts{,x}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^23.3.10","jest":"^23.6.0","rimraf":"^2.6.2","ts-jest":"^23.10.5","tslint":"^5.9.1","tslint-config-bunch-of-friends":"^1.0.1","tslint-eslint-rules":"^5.0.0","typescript":"^3.2.2"},"gitHead":"58b0278aa58f089d7f353a94c36386bdf776a1d4","_id":"@bunch-of-friends/observable@1.4.0","_npmVersion":"6.4.1","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-Ro3LpVN+QW3ZTrBt9egI1JyCOBr3lsI6z+wtFZ6QrZFzpngyiJdcdS2PzIlBzOPwli3ni8iwuaweksbTfSOUlQ==","shasum":"917b125b27af92ca11d57afd86dfeff52cbf6496","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.4.0.tgz","fileCount":15,"unpackedSize":17179,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcDXNlCRA9TVsSAnZWagAAnj4P/iUjmnEBfGmbGMZYFdnl\n66IFjSqxYUw5R8K8ZP7iqJaX4ZQkK9VoFyVjklT2HvlSAG1lUBV6TN1cl7kv\nUVuq14oT6iFuZqRv+hyqmcTEbtUCseWf6MtgPPXTxU1NrVDtA8v8DAkcGeBu\n9erTLfgnSqXPPa3lc/5fey3uANKS1lijnJyZk7Ezc5vcQiyqNGIH87uNbNif\nXFrafi6t0TgUmzPu2/zM2AUSNiTrAE9lsVlYPOVCVxh3/PjfAtr0pkhZvN3t\nhEfs37x2bNJEpQKU+YhE99BAFzD3SbFSiVY64rx9puF0LG4mcspKwOiZQ5Cz\nAkX/FzLL6vAuTn5d+hUiDw8YReP3GP7tqFcC08qZqR9GPO7krVZwOc7oOQub\n8uP2a3B+SEcjUOffwcNZ2tzZ1EoWFUThQb1QMhfBGKW/XhBXjXEZC7bxzWif\nVD/7g8A777xNx/CQPxd9kbcjPfF+Nt3XxKJzgy9FL2P+KzpM4CN8k5OcTJZS\n0XpvWJhaSqDp0b3wK+MiXcQVnFk2p/HABHGPChLY3KzohcWP2w5jxSgbgZrF\n6AFIlUZA/5PUfOqTGsZWlLqmMxxZO8leMIjNq1bZUp3TLMgF1ury0zCS1So2\nk36Kj9WYPw/b+Ecc3bDcCPBCb+/BUohYUU8g6LqwtafC5THYJp7W43jrq6hH\nExQv\r\n=jLtt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC/k0uRR1uc5p8lXUegE/9UoDW8ojTvodrLOkZ68dIDAAiEArFD6d+ekYc88bqcIGNvor+Q5be6KX1RbLPaZxEa6K7M="}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.4.0_1544385380404_0.6175746370322024"},"_hasShrinkwrap":false},"1.4.1":{"name":"@bunch-of-friends/observable","version":"1.4.1","description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","main":"dist/index.js","types":"dist/index.d.ts","license":"MIT","maitainers":[{"name":"David Bohunek","email":"bohunek@gmail.com"}],"keywords":["observer","observable","typescript","simple"],"scripts":{"test":"jest --config ./jest.config.json","build":"npm run cleanup && tsc","build:watch":"npm run cleanup && tsc -w","cleanup":"rimraf -rf dist coverage","lint":"tslint '**/*.ts{,x}' -e '**/**/*d.ts' -e '**/node_modules/**'","prettier":"prettier --write '**/**/*.{ts,tsx,css}'","prepublish":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"homepage":"https://github.com/bunch-of-friends/observable#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^23.3.10","jest":"^23.6.0","rimraf":"^2.6.2","prettier":"^1.15.3","ts-jest":"^23.10.5","tslint":"^5.11.0","tslint-config-bunch-of-friends":"^1.0.3","tslint-config-prettier":"^1.17.0","tslint-eslint-rules":"^5.4.0","tslint-plugin-prettier":"^2.0.1","typescript":"^3.2.2"},"gitHead":"ec73488ea3e220249335ca36eb1692be87c2c9e4","_id":"@bunch-of-friends/observable@1.4.1","_npmVersion":"6.4.1","_nodeVersion":"8.9.1","_npmUser":{"name":"david-bohunek","email":"bohunek@gmail.com"},"dist":{"integrity":"sha512-OhplB90WSXhAPXa8FnZ/MeX+6mMx7OhD4FXsrX6YsFVkGYMi7GMSCH9B8whu4JPdGy6P1kKdGw+34iTEZvUF5w==","shasum":"17a5ce610a27e773dc8b4df127e7be6f3c316bcb","tarball":"https://registry.npmjs.org/@bunch-of-friends/observable/-/observable-1.4.1.tgz","fileCount":15,"unpackedSize":17400,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcDXffCRA9TVsSAnZWagAA2SkP/RijDgGcNivW1cj/z9yn\nqyUAR0IP781u6Dx5N2Euv3YdRJDhng6lNKORj7RYvgNesBC26Tzq1i6Gba1b\nqpeqeqv6FVtC5WwlI9hRRAHMjlIZZ/VAtTTvB75p9c2ZeuYYlNUqZ8TCr6vR\ne+kIJ28rr3+Zo1eLcoC4FjeYtWhdsj1Qwvn4Q12ALHfbqff2q1P95KtirLZD\n2uYmI1agk/p7W5aQuKmH5qJSakjm6PR9MJy+2beDYccJfEv2Otrb54LCiGup\nppKlupdBMITkCwx2wFKf8bDVZR+ma1fArQiZev6Mgxhe1ptSyspkUJZ/e3pp\n+KiDXh6IY/69zEhl8S7uAjK4YxBbbp9cTD7mLdqfb6Ik7PNQGnYeu0ATcPND\n1SnPsH16n1uoZJ53j8q+GKv11MD3QGPjoQsnHcNYzjO7cVzhIKSnNzufOidp\n6w8kmsL770im/ttvcMhgI1tWFwNSiK9lGIJ/Gn5boeSsnfMcG8r2H5Ac6QNc\nb/wSOES4aFjd5VNilohWo5F6HXy1oZlsPHQopUsUzsP9z74JSBAeAnBvEjdM\nlYCnkr09oMcukj1nR7cVknuBytFcGlWZKEAZhVDhduX1i9dL/JiK/YIhlrEs\nq/+iy/NRmHWMZKgI2DhF6Hh1JiMH905DH+VrJZqygheRjMHWePnk5bALOH2t\n7ccJ\r\n=prZo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEKXoFepAleuwU9dwCpmLr3YPD397mW5WUXxkr+tmOfQIgSvEP9qr2erBDnlOXRCFTod9NhqI2JTqYEnVVh/mXT4I="}]},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/observable_1.4.1_1544386526394_0.6247229678333004"},"_hasShrinkwrap":false}},"time":{"created":"2018-02-25T18:53:25.774Z","1.0.0":"2018-02-25T18:53:25.905Z","modified":"2022-04-04T21:05:33.674Z","1.1.0":"2018-03-31T15:41:23.111Z","1.1.1":"2018-03-31T15:49:12.966Z","1.1.2":"2018-03-31T15:53:12.614Z","1.2.0":"2018-04-02T11:00:25.847Z","1.3.0":"2018-04-21T21:12:42.801Z","1.4.0":"2018-12-09T19:56:20.575Z","1.4.1":"2018-12-09T20:15:26.533Z"},"maintainers":[{"name":"david-bohunek","email":"bohunek@gmail.com"}],"description":"A simple implementation of the observer pattern written in TypeScript, usable in JavaScript as well.","homepage":"https://github.com/bunch-of-friends/observable#readme","keywords":["observer","observable","typescript","simple"],"repository":{"type":"git","url":"git+https://github.com/bunch-of-friends/observable.git"},"bugs":{"url":"https://github.com/bunch-of-friends/observable/issues"},"license":"MIT","readme":"# @bunch-of-friends/observable\n\n[![License](https://img.shields.io/github/license/mashape/apistatus.svg?style=flat-square)](https://github.com/bunch-of-friends/lerna-typescript-jest-boilerplate/blob/master/LICENSE)\n[![npm version](https://badge.fury.io/js/%40bunch-of-friends%2Fobservable.svg)](https://badge.fury.io/js/%40bunch-of-friends%2Fobservable)\n[![CircleCI](https://circleci.com/gh/bunch-of-friends/observable.svg?style=svg)](https://circleci.com/gh/bunch-of-friends/observable)\n\nA simple implementation of the [observer pattern](https://en.wikipedia.org/wiki/Observer_pattern) written in TypeScript, usable in JavaScript as well.\n\n## Key objects\nThere are three key objects: [Subject](https://github.com/bunch-of-friends/observable/blob/master/src/subject.ts), [Observable](https://github.com/bunch-of-friends/observable/blob/master/src/observable.ts) and [Observer](https://github.com/bunch-of-friends/observable/blob/master/src/observer.ts).\n\n### Observer\nA function, which gets called on a change. Observers can return a promise, see [Async observers](#async-observers) below.\n```ts\nexport interface Observer<T> {\n    (newState: T, previousState?: T): void | Promise<void>;\n}\n```\n\n### Subject\nObject responsible for maintaining a list of observers, keeping track of the state and notifying its changes.\nSubject is intended to be used internally and shouldn't be exposed outside of the object using it.\n```ts\nexport interface Subject<T> {\n    registerObserver(observer: Observer<T>, owner: Object): Observer<T>;\n    unregisterObserver(observer: Observer<T>): void;\n    unregisterObserversOfOwner(owner: Object): void;\n    unregisterAllObservers(): void;\n    notifyObservers(newState?: T): Promise<void>;\n    getCurrentState(): T;\n}\n```\n\n### Observable\nObservable is a subset of Subject and is intended to be exposed outside of the object using it. Users of the Observable can freely register and unregister, but cannot notify changes.\n```ts\nexport interface Observable<T> {\n    register: (observer: Observer<T>) => Observer<T>;\n    unregister: (observer: Observer<T>) => void;\n    unregisterAllObservers: () => void;\n    getCurrentState(): T;\n}\n```\n\n## Usage\nThe library is published to npm as commonjs ES5 module. It is intended to be used in browser, but requires a module bundler.\nThe library comes with embedded TypeScript types, so it is easy to use in TypeScript, but it can be used as well in JavaScript.\n\n```bash\nnpm install @bunch-of-friends/observable --save\n```\n\nUse the `createSubject` function to create an instance of Subject:\n```ts\nimport { createSubject } from '@bunch-of-friends/observable';\n\nconst subject = createSubject<T>(); //replace `T` with type of the object that the observers will be notified with\n\nsubject.registerObserver(currentState => /* ... */ );\n\nsubject.notifyChanges({ /* ... */ }); // the argument of notifyChanges is of type `T`\n```\n\nTo create an observable that can be used for registering and unregistering observers only, use the `createObservable` function:\n```ts\nimport { createObservable } from '@bunch-of-friends/observable';\n\nconst observable = createObservable(subject); // as created earlier\n\nobservable.register(currentState => /* ... */ );\n```\n\nYou can also create an observable that only filters only changes that match a specific values, use the `createObservableForValue` function:\n```ts\nimport { createSubject, createObservableForValue } from '@bunch-of-friends/observable';\n\nenum State {\n    Loading,\n    Loaded\n}\n\nconst subject = createSubject<State>();\nconst observable = createObservableForValue(subject, State.Loaded);\nobservable.registerObserver(() => console.log('state changed to loaded'))\n\nsubject.notifyChanges(State.Loading); // this will not call the observer\nsubject.notifyChanges(State.Loaded); // this will call the observer\n\n```\n\n## Example\nA simple example demonstrating the intended use:\n```ts\nimport { createSubject, createObservable, createObservableForValue } from '@bunch-of-friends/observable';\n\nenum State {\n    Loading,\n    Loaded\n}\n\nclass Component {\n    private stateSubject = createSubject<State>();\n\n    // use this to subscribe to any state change\n    public onStateChanged = createObservable(stateSubject);\n\n    // shorthand if you only want to subscribe to the state changing to Loaded\n    public onLoaded = createObservableForValue(stateSubject, State.Loaded);\n\n    constructor() {\n        // notifyChanges would usually be called by some more reasonable code\n        setTimeout(() => this.stateSubject.notifyChanges(State.Loading), 1000);\n        setTimeout(() => this.stateSubject.notifyChanges(State.Loaded), 2000);\n    }\n\n    public dispose() {\n        this.stateSubject.unregisterAllObservers();\n    }\n}\n\nclass ComponentConsumer {\n    constructor(component: Component) {\n        component.onStateChanged.register((state) => console.log('current state is: ' + state));\n        component.onLoaded.register(() => console.log('component loaded'));\n    }\n}\n```\n\n## Async observers\nThe `Observer` function can return a promise. When `Subject` is notified of changes by the `notifyObservers` function, it will wait for all observers that return a promise and it will resolve, when all observers resolve or reject. `notifyObservers` will never reject, it catches all rejections. Errors are expected to be handled by the observers.\n\n## Classes vs closures\nWhy are the `Subject` and `Observable` not ES6 classes?\nThe reason is that the classes would have private fields, for example `Subject` would have private field `registeredObservers`. The TypeScript complier doesn't allow other TypeScript code to acess it, but in plain JavaScript, the private fields will be accessible and that will violate the open/close principle.\n\nIn the example above, we use ES6 class, try running similar code. You will be able to access the private field `stateSubject`, which is not inteded, in TypeScript it is marked as private.\n\nTherefore the `createSubject` and `createObservable` act as constructors and and we use closures instead of hide the private variables from the users.\n","readmeFilename":"README.md"}