{"id":20950128,"url":"https://github.com/richie765/pg-query-observer","last_synced_at":"2025-10-11T14:41:15.839Z","repository":{"id":57322632,"uuid":"71402457","full_name":"Richie765/pg-query-observer","owner":"Richie765","description":"Observe PostgreSQL query for changes.","archived":false,"fork":false,"pushed_at":"2017-06-29T10:33:23.000Z","size":19,"stargazers_count":3,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-02T22:04:11.377Z","etag":null,"topics":["observer","postgresql"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Richie765.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-19T21:53:13.000Z","updated_at":"2022-04-25T13:03:25.000Z","dependencies_parsed_at":"2022-08-25T21:01:19.776Z","dependency_job_id":null,"html_url":"https://github.com/Richie765/pg-query-observer","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Richie765/pg-query-observer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richie765%2Fpg-query-observer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richie765%2Fpg-query-observer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richie765%2Fpg-query-observer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richie765%2Fpg-query-observer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Richie765","download_url":"https://codeload.github.com/Richie765/pg-query-observer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Richie765%2Fpg-query-observer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269970120,"owners_count":24505466,"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","status":"online","status_checked_at":"2025-08-11T02:00:10.019Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["observer","postgresql"],"created_at":"2024-11-19T00:45:45.591Z","updated_at":"2025-10-11T14:41:10.788Z","avatar_url":"https://github.com/Richie765.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pg-query-observer\nObserve PostgreSQL query for changes.\n\nRequires PostgresSQL version 9.3 or above.\n\n# Usage\n```javascript\nvar pgp = require('pg-promise')();\n\nimport PgQueryObserver from 'pg-query-observer';\n\n\nconst connection = 'postgres://localhost/db';\n\nasync function start() {\n  try {\n    let db = await pgp(connection);\n\n    let query_observer = new PgQueryObserver(db, 'myapp');\n\n    async function cleanupAndExit() {\n      await query_observer.cleanup();\n      pgp.end();\n      process.exit();\n    }\n\n    process.on('SIGTERM', cleanupAndExit);\n    process.on('SIGINT', cleanupAndExit);\n\n    // Show notifications\n\n    let query = 'SELECT id AS _id, * FROM test';\n    let params = [];\n\n    function triggers(change) {\n      console.log('triggers', change);\n      return true;\n    }\n\n    let handle = await query_observer.notify(query, params, triggers, diff =\u003e {\n      console.log(diff);\n    });\n\n    console.log('initial rows', handle.getRows());\n\n    // ... when finished observing the query\n\n    // await handle.stop();\n\n    // ... when finished observing altogether\n\n    // await query_observer.cleanup();\n    // await pgp.end();\n  }\n  catch(err) {\n    console.error(err);\n  }\n}\n\nprocess.on('unhandledRejection', (err, p) =\u003e console.log(err.stack));\n\nstart();\n```\n\n# constructor(db, channel, [options])\n\nParameter | Description\n--------- | -----------\n`db` | PostgreSQL db to use\n`channel` | Channel for LISTEN/NOTIFY on the PostgreSQL database, cannot be used by more than one application on the same database.\n`options` | Optional object containing options. See below.\n\nOption | Description\n------ | -----------\n`trigger_delay` | (default 200ms): passed through to PgTableObserver.\n`keyfield` | (default \\_id): field to use as a unique keyfield to determine the differences.\n`initial_cached` | (default true): If a query is already being observed with the same `query/params` combination, if will use the cached rows as the initial rows (e.g. with `handle.getRows()`). If your `triggers` are correctly defined this should be fine. Turn this option off to load fresh rows from the database for the initial dataset to be sure they are up to date.\n\n# let handle = async notify(query, params, triggers, callback)\n\nParameter | Description\n--------- | -----------\n`query` | SELECT query to run and observe. May contain placeholders following `pg-promise`\n`params` | The parameters to the query, following `pg-promise`. Single values will be `$1`. Array elements will be `$1`..`$n`. Object properties will be `$*property*` where `**` is one of `()`, `[]`, `{}` or `//`. See `pg-promise` for details.\n`triggers` | function(change). The trigger function, see below.\n`callback` | Callback function, see below.\n\n## triggers function\n\nThis function will be called whenever there is a change to one of the underlying tables of the query.\nYou should determine if this change requires a rerun of the query. If so, you should return `true`.\n\nOne parameter is passed, `change`. It contains the following fields:\n\nField | Description\n-------------- | -----------\n`table` | String, name of the table that changed. ***This will always be in lowercase.***\n`insert` | For INSERT, `true`\n`delete` | For DELETE, `true`\n`update` | For UPDATE, an object that contains the old and new values of each changed column. If a column `score` changed from 10 to 20, `change.update.score.from` would be 10 and `change.update.score.to` would be 20.\n`row` | The row values, for UPDATE, the NEW row values\n`old` | For UPDATE, the OLD row values\n\n## callback function\n\nWhenever observer is triggered, the query will be reran. The callback will be called with one parameter, `diff`.\nIt will contain only the difference between the last time the query was run.\n\nDiff will contain thee fields:\n\nField | Description\n----- | -----------\n`added` | array of rows that are in `new_rows`, but not in `old_rows`\n`changed` | array of rows from `new_rows` existed in `old_rows` but have changed\n`deleted` | array if the key's from the rows from `old_rows` that don't exist in `new_rows`\n\n## return value\n\nOn success, returns an object with the following fields.\n\nField | Description\n----- | -----------\n`async stop()` | async function(). Call to stop the observer.\n`async refresh()` | async function(). Call to refresh the query.\n`getRows()` | Get current full set of rows.\n\n# async cleanup()\n\nStop observing and cleanup triggers from the database.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichie765%2Fpg-query-observer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frichie765%2Fpg-query-observer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichie765%2Fpg-query-observer/lists"}