{"id":12718,"library":"bidc","title":"Bidirectional Channel for JavaScript","description":"BIDC is a JavaScript library designed for establishing robust, asynchronous, bidirectional communication channels between different JavaScript execution contexts, such as web workers, iframes, and service workers. Unlike traditional `postMessage` APIs, BIDC abstracts away the complexities of message passing, providing full support for promises, async functions, and a wide range of complex data types (e.g., Date, RegExp, Map, Set, ArrayBuffer). It features an automatic handshake mechanism to establish and re-establish connections seamlessly, even if one side reloads, and buffers messages until the recipient is ready. Currently at version 0.0.4, the library is in an early development stage, focusing on foundational features for secure and efficient cross-context communication. Its primary differentiators are automatic connection management, comprehensive data type serialization, and first-class async/await support, streamlining RPC-style interactions. It ships with TypeScript types, enhancing developer experience and type safety.","status":"active","version":"0.0.4","language":"javascript","source_language":"en","source_url":null,"tags":["javascript","bidirectional","channel","communication","rpc","async","cross-context","postmessage","typescript"],"install":[{"cmd":"npm install bidc","lang":"bash","label":"npm"},{"cmd":"yarn add bidc","lang":"bash","label":"yarn"},{"cmd":"pnpm add bidc","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"BIDC is primarily an ESM-first library. While some bundlers might transpile CommonJS 'require', using ESM 'import' is the recommended and native approach for modern JavaScript environments.","wrong":"const { createChannel } = require('bidc')","symbol":"createChannel","correct":"import { createChannel } from 'bidc'"},{"note":"The 'Channel' type refers to the interface returned by 'createChannel'. It should be imported as a type for TypeScript, not as a runtime value.","wrong":"import { Channel } from 'bidc'","symbol":"Channel","correct":"import type { Channel } from 'bidc'"},{"note":"While 'Payload' is not directly exported for consumption in the same way 'createChannel' is, understanding and defining custom payload types for your channel messages is crucial for robust communication. You would typically define your specific message interfaces that extend or align with BIDC's internal 'Payload' structure for type safety in your `send` and `receive` handlers.","symbol":"Payload","correct":"import type { Payload } from 'bidc'"}],"quickstart":{"code":"import { createChannel } from 'bidc';\n\n// --- Parent window code ---\nasync function parentContext() {\n  const iframe = document.createElement('iframe');\n  document.body.appendChild(iframe);\n\n  // Wait for iframe to load for contentWindow to be available\n  await new Promise(resolve => iframe.onload = resolve);\n\n  const { send } = createChannel(iframe.contentWindow);\n\n  // Send a simple message to the iframe and await its response\n  const result = await send({ value: 'Hello, iframe from parent!' });\n  console.log('Parent received:', result);\n  console.assert(result === 'HELLO, IFRAME FROM PARENT!');\n}\n\n// --- Inside the iframe (hypothetical, or simulated for demo) ---\n// In a real scenario, this would be in the iframe's HTML or JS file.\nfunction iframeContext() {\n  // Omitting the target here will create a channel to the parent window by default\n  const { receive } = createChannel(); // Equivalent to createChannel(window.parent)\n\n  // Handle incoming messages from the parent and return a response\n  receive((payload) => {\n    console.log('Iframe received:', payload);\n    if (typeof payload.value === 'string') {\n      return payload.value.toUpperCase();\n    }\n    return 'Invalid payload';\n  });\n}\n\n// For demonstration, call both, but in reality they run in separate contexts.\nparentContext();\niframeContext(); // This would typically be loaded by the iframe itself.","lang":"typescript","description":"This quickstart demonstrates basic one-way data transfer and response handling between a parent window and an iframe using `createChannel`, showing both sending and receiving sides."},"warnings":[{"fix":"Monitor releases and review changelogs for new minor versions before upgrading in production environments. Pin exact versions for critical applications.","message":"As of version 0.0.4, BIDC is in early development. While the core API (`createChannel`, `send`, `receive`) is stable, minor versions may introduce breaking changes to less common features or internal protocols. Major version 1.0.0 is expected to stabilize the API.","severity":"breaking","affected_versions":"<1.0.0"},{"fix":"Always explicitly provide a target (e.g., `iframe.contentWindow`, `worker`, `otherWindow`) to `createChannel(target)` unless you specifically intend to connect to `window.parent`.","message":"When using `createChannel()` without specifying a target, it defaults to `window.parent`. This behavior is useful for iframes/workers communicating with their creators but can lead to unexpected connections if used in a top-level window without explicit targeting.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"For every message you intend to send, ensure there's a corresponding `receive` handler on the other side of the channel to process it and, if desired, return a response.","message":"Ensure both ends of the channel are calling either `send` or `receive` (or both) to establish and maintain communication. If only one side attempts to `send` without a `receive` handler on the other, messages will be buffered but never processed.","severity":"gotcha","affected_versions":">=0.0.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Use ESM import syntax: `import { createChannel } from 'bidc'`. Ensure your project's `package.json` specifies `\"type\": \"module\"` or your build system correctly handles ESM.","cause":"Attempting to use CommonJS `require` syntax with an ESM-only package or a misconfigured bundler.","error":"TypeError: createChannel is not a function"},{"fix":"Ensure that the data being sent directly as a payload consists of clonable JavaScript primitives or objects that BIDC explicitly supports for serialization. For DOM elements or functions, consider an RPC pattern where the function is executed remotely or only send serializable identifiers.","cause":"While BIDC generally handles complex types, certain non-clonable or non-transferable objects (e.g., DOM elements, functions not wrapped by BIDC's async support) might still fail if directly sent in a payload without proper serialization or remote execution context.","error":"Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Window': An object could not be cloned."}],"ecosystem":"npm"}