{"id":23745095,"url":"https://github.com/cedmandocdoc/redefining-observable","last_synced_at":"2025-06-17T10:09:45.097Z","repository":{"id":40765202,"uuid":"265092712","full_name":"cedmandocdoc/redefining-observable","owner":"cedmandocdoc","description":"A shift of perspective on Observable","archived":false,"fork":false,"pushed_at":"2023-01-06T08:31:41.000Z","size":868,"stargazers_count":2,"open_issues_count":13,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-01T02:57:47.573Z","etag":null,"topics":["observable","observable-pattern","observable-properties","reactive-programming"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cedmandocdoc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-18T23:56:11.000Z","updated_at":"2022-07-05T02:43:28.000Z","dependencies_parsed_at":"2023-02-05T17:15:30.758Z","dependency_job_id":null,"html_url":"https://github.com/cedmandocdoc/redefining-observable","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cedmandocdoc/redefining-observable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedmandocdoc%2Fredefining-observable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedmandocdoc%2Fredefining-observable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedmandocdoc%2Fredefining-observable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedmandocdoc%2Fredefining-observable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cedmandocdoc","download_url":"https://codeload.github.com/cedmandocdoc/redefining-observable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cedmandocdoc%2Fredefining-observable/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260336342,"owners_count":22993740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["observable","observable-pattern","observable-properties","reactive-programming"],"created_at":"2024-12-31T12:53:22.368Z","updated_at":"2025-06-17T10:09:40.084Z","avatar_url":"https://github.com/cedmandocdoc.png","language":"JavaScript","readme":"# Redefining Observable\n\n_A shift of perspective on Observable_\n\nThis article is a shift of perspective to what an Observable is. It discusses the current model of Observable and dissects its properties in the hope to define what it is at its core.\n\nObservable has been defined as a function that propagates values to an observer and returns a means to cancel that propagation. This model has two fundamental properties: propagation and cancellation.\n\nPropagation is the act of an Observable to send data to an observer. On the basic level, this be can done through a simple callback function.\n\n```javascript\nconst observable = callback =\u003e {\n  // connects the callback to something\n  // that produces values\n  window.addEventListener(\"scroll\", e =\u003e callback(e));\n};\n\nconst observer = data =\u003e console.log(data);\n\nobservable(observer);\n```\n\nThe code shows that the Observable connects the `callback` to an event listener which produces a scroll event and when it gets called it transfers the data to the observer. This process is called propagation, it exists on all kinds of Observable and fundamentally intertwined with its definition and cannot be separated. This what makes the Observable \"observable\" - a capability of being observed.\n\nThe last property from the current model is the cancellation. This property enables the Observable to stop the data propagation to the observer. This is normally done through a cleanup function which is returned by the Observable.\n\n```javascript\nconst observable = callback =\u003e {\n  const listener = e =\u003e callback(e);\n\n  window.addEventListener(\"scroll\", listener);\n\n  // return a clean up function\n  return () =\u003e window.removeEventListener(\"scroll\", listener);\n};\n\nconst cleanup = observable(e =\u003e console.log(e));\n\n// run cleanup after a second\nsetTimeout(() =\u003e cleanup(), 1000);\n```\n\nCancellation seems like it is a fundamental part of Observable but more likely it is an emergent property simply because it doesn't exist to all kinds of Observable. It just emerges to some because of the need for it. Some observer doesn't care about cancellation they just want to listen as long as the Observable emits data.\n\nCancellation is just a part of an infinite number of emergent properties because the need for it depends on the logic of the application and logic could demand more, for instance a logic that demands pause in an Observable timer or an Observable that implements data pulling like iterables.\n\nEmergent properties act as a medium to notify an Observable. The process is similar to what Observable does, it propagates data to an entity, which in this case the source of data is reversed, the observer is the one that sends it and the observable is the one that listens to it. From the perspective of how they work, it implies that these emergent properties are indeed an Observable.\n\n```javascript\nconst scrollObservable = (callback, external) =\u003e {\n  const listener = e =\u003e callback(e);\n\n  // listen for a\n  // cancellation token\n  external(data =\u003e {\n    if (data === \"CANCEL\") window.removeEventListener(\"scroll\", listener);\n  });\n\n  window.addEventListener(\"scroll\", listener);\n};\n\nconst cancelObservable = callback =\u003e {\n  // after a second sends\n  // a cancellation token\n  setTimeout(() =\u003e callback(\"CANCEL\"), 1000);\n};\n\nscrollObservable(e =\u003e console.log(e), cancelObservable);\n```\n\nThe code shows that the Observable now accepts another parameter named `external` which is also another Observable that is provided from the outside. As the Observable propagates data, it also listens to the `external` for a cancellation token named `CANCEL` which stops the propagation. This enables the Observable to react accordingly with the entity outside. This approach serves better both the Observable and outside entity, it provides concrete communication between them.\n\nWith all that in mind, Observable, therefore, has the natural ability to propagate data and also to listen to the outside entity and react accordingly. It brings two fundamental properties: propagation and interaction. With this idea, we can generalized all, if not most, existing kinds of Observable like iterable and asynchronous. For a complete implementation of the idea, check out [Observable.js](https://github.com/cedmandocdoc/redefining-observable/blob/master/Observable.js) and for actual usage, check [examples](https://github.com/cedmandocdoc/redefining-observable/tree/master/examples) folder.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcedmandocdoc%2Fredefining-observable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcedmandocdoc%2Fredefining-observable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcedmandocdoc%2Fredefining-observable/lists"}