{"id":13447797,"url":"https://github.com/rapid7/tabtalk","last_synced_at":"2025-03-22T01:31:24.039Z","repository":{"id":65513936,"uuid":"144874439","full_name":"rapid7/tabtalk","owner":"rapid7","description":"Secure, encrypted cross-tab communication in the browser","archived":true,"fork":false,"pushed_at":"2018-09-18T12:53:35.000Z","size":100,"stargazers_count":21,"open_issues_count":0,"forks_count":4,"subscribers_count":62,"default_branch":"master","last_synced_at":"2025-03-13T04:32:44.941Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/rapid7.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":"2018-08-15T16:02:23.000Z","updated_at":"2025-03-13T02:56:32.000Z","dependencies_parsed_at":"2023-01-26T20:55:18.461Z","dependency_job_id":null,"html_url":"https://github.com/rapid7/tabtalk","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Ftabtalk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Ftabtalk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Ftabtalk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Ftabtalk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rapid7","download_url":"https://codeload.github.com/rapid7/tabtalk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244893452,"owners_count":20527595,"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":[],"created_at":"2024-07-31T05:01:27.105Z","updated_at":"2025-03-22T01:31:23.792Z","avatar_url":"https://github.com/rapid7.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# tabtalk\n\nSimple, secure cross-origin communication between browser tabs\n\n## Table of contents\n\n- [Usage](#usage)\n- [createTab](#createtab)\n  - [config](#config)\n- [TabTalk instance API](#tabtalk-instance-api)\n  - [open](#open)\n  - [close](#close)\n  - [sendToChild](#sendtochild)\n  - [sendToChildren](#sendtochildren)\n  - [sendToParent](#sendtoparent)\n\n## Usage\n\n```javascript\nimport createTab from 'tabtalk';\n\nconst tabtalk = createTab({\n  onChildCommunication(message) {\n    console.log('message from child', message);\n  },\n  onChildRegister(childTab) {\n    tabtalk.sendToChild(childTab.id, 'Hello my child!');\n  },\n  onRegister() {\n    console.log('ready to go!');\n  },\n});\n\ntabtalk.open({url: 'http://www.example.com'});\n```\n\nMessages are sent by `postMessage`, allowing for cross-origin usage (with the use of custom `config` properties), and the data in the message is encrypted with `krip` under the hood.\n\n## createTab\n\n```javascript\ncreateTab([config: Object]): TabTalk\n```\n\nCreates a new `TabTalk` instance where the window it is executed in (itself) is the tab. The instance returned allows you to open children, and will automatically glean its parent if it was opened from another `TabTalk` instance.\n\n#### config\n\n`createTab` optionally accepts a `config` object which has the following shape:\n\n```javascript\n{\n  // custom key to be used by krip for encryption / decription\n  // HIGHLY RECOMMENDED\n  encryptionKey: string,\n\n  // called when child closes\n  onChildClose: (child: TabTalk) =\u003e void,\n\n  // called when child sends message to self\n  onChildCommunication: (message: any, eventTime: number) =\u003e void,\n\n  // called when child registers with parent\n  onChildRegister: (child: TabTalk) =\u003e void,\n\n  // called when self is closed\n  onClose: () =\u003e void,\n\n  // called when parent is closed\n  onParentClose: () =\u003e void,\n\n  // called when parent sends message to self\n  onParentCommunication: (message: any, eventTime: number) =\u003e void,\n\n  // called when self registers\n  onRegister: (self: TabTalk) =\u003e void,\n\n  // the origin to use for cross-tab validation\n  origin: string = window.origin || document.domain || '*',\n\n  // the delay to wait when a tab doesn't check in but has already checked in\n  pingCheckinBuffer: number = 5000,\n\n  // the delay to wait before the next check if tab is checking in\n  pingInterval: number = 5000,\n\n  // the delay to wait when a tab doesn't check in and has never checked in\n  registrationBuffer: number = 10000,\n\n  // should the tab be removed as a child when closed\n  removeOnClose: boolean = false,\n}\n```\n\n## TabTalk instance API\n\n#### open\n\nOpens a new child `TabTalk` instance and stores it as a child in the opener's `TabTalk` instance. Resolves the child instance.\n\n```javascript\nopen(options: Object): Promise\u003cTabTalk\u003e\n```\n\nExample:\n\n```javascript\nconst openChild = async config =\u003e {\n  const child = await tabtalk.open({\n    config,\n    url: 'http://www.example.com/',\n  });\n\n  return child;\n};\n```\n\n`open()` accepts the following options:\n\n```javascript\n{\n  // the config to pass through to createTab for the child\n  config: Object = self.config,\n\n  // the destination to open\n  url: string,\n\n  // any windowFeatures to apply to the opened window\n  windowFeatures: string,\n}\n```\n\nFor more information on `windowFeatures`, [see the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Window/open#Parameters).\n\n#### close\n\nCloses the `TabTalk` instance, or if an ID is passed then closes that matching child `TabTalk` instance.\n\n```javascript\nclose([id: string]) =\u003e void\n```\n\nExample:\n\n```javascript\ntabtalk.close(); // closes self\n\ntabtalk.close(child.id); // closes specific child\n```\n\n#### sendToChild\n\nSend data to a specific child. The promise resolved is empty, it's mainly to have control flow over a successful message sent.\n\n```javascript\nsendToChild(id: string, data: any): Promise\u003cnull\u003e\n```\n\nExample:\n\n```javascript\ntabtalk.sendToChild(child.id, {\n  message: 'Special message',\n  total: 1234.56,\n});\n```\n\n**NOTE**: Data can be anything that is serializable by `JSON.stringify`.\n\n#### sendToChildren\n\nSend data to all children. The promise resolved is empty, it's mainly to have control flow over a successful message sent.\n\n```javascript\nsendToChildren(data: any): Promise\u003cnull\u003e\n```\n\nExample:\n\n```javascript\ntabtalk.sendToChildren({\n  message: 'Special message',\n  total: 1234.56,\n});\n```\n\n**NOTE**: Data can be anything that is serializable by `JSON.stringify`.\n\n#### sendToParent\n\nSend data to the parent. The promise resolved is empty, it's mainly to have control flow over a successful message sent.\n\n```javascript\nsendToParent(data: any): Promise\u003cnull\u003e\n```\n\nExample:\n\n```javascript\ntabtalk.sendToParent({\n  message: 'Special message',\n  total: 1234.56,\n});\n```\n\n**NOTE**: Data can be anything that is serializable by `JSON.stringify`.\n\n## Support\n\nSupport is mainly driven by `krip` support, as `postMessage` works correctly back to IE8.\n\n- Chrome 37+\n- Firefox 34+\n- Edge (all versions)\n- Opera 24+\n- IE 11+\n  - Requires polyfills for `Promise`, `TextDecoder`, and `TextEncoder`\n- Safari 7.1+\n- iOS 8+\n- Android 5+\n\n## Development\n\nStandard stuff, clone the repo and `npm install` dependencies. The npm scripts available:\n\n- `build` =\u003e run `rollup` to build browser and node versions\n  - standard versions to top-level directory, minified versions to `dist` folder\n- `clean:dist` =\u003e run `rimraf` on `dist` folder\n- `dev` =\u003e run `webpack` dev server to run example app / playground\n- `dist` =\u003e run `clean:dist`, `build`\n- `lint` =\u003e run `eslint` against all files in the `src` folder\n- `lint:fix` =\u003e run `lint`, fixing issues when possible\n- `prepublish` =\u003e runs `prepublish:compile` when publishing\n- `prepublish:compile` =\u003e run `lint`, `test:coverage`, `build`\n- `start` =\u003e run `dev`\n- `test` =\u003e run AVA test functions with `NODE_ENV=test`\n- `test:coverage` =\u003e run `test` but with `nyc` for coverage checker\n- `test:watch` =\u003e run `test`, but with persistent watcher\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Ftabtalk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frapid7%2Ftabtalk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Ftabtalk/lists"}