npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wildix/xbees-connect

v1.3.19

Published

This library provides easy communication between x-bees and integrated web applications

Readme

x-bees-connect client

This package is the Community plan edition of the client for UI integration applications.

Installation

Install the package in your project directory with:

pnpm add @wildix/xbees-connect
npm install @wildix/xbees-connect

Work Variants

The integration can be launched in different modes via the v URL parameter:

  • ui - Standard UI mode (default)
  • no-ui / daemon - Data-only mode, no UI shown
  • d / dialog - Dialog/setup mode
  • f - Fullsize mode, integration takes full viewport dimensions

You can check the current mode using:

const client = Client.getInstance();

client.showsUi();       // Returns true for UI modes (ui, d, f)
client.isDataOnly();    // Returns true for no-ui / daemon mode
client.isSetupDialog(); // Returns true for dialog mode (d / dialog)
client.isFullsize();    // Returns true for fullsize mode (f)

Usage

import Client from "@wildix/xbees-connect";

const xBeesClient = Client.getInstance();

console.log(xBeesClient.version());

API

Class helpers

Client.getInstance(): ConnectClient

Returns the singleton Client instance. Prefer this over new Client() to avoid duplicate message listeners.

const client = Client.getInstance();

Client.initialize(renderer: () => Promise<void>): void

Calls renderer only when the integration runs in a UI mode (showsUi() === true). Use this as the entry point to conditionally boot your React/Vue tree.

Client.initialize(async () => {
  ReactDOM.render(<App />, document.getElementById('root'));
});

Initialization

ready(props?: SupportedPlatformVariant | ReadyExtendedProps): Promise<ResponseMessage>

Sends the signal to x-bees that the iFrame is ready to be shown. Call this once when the application starts and is fully initialised. Accepts an optional platform variant string or an extended props object (e.g. templateId, analyticTitle).

isAuthorized(): Promise<ResponseMessage>

Sends the message to x-bees that the user is authorized and no more actions are required.

isNotAuthorized(): Promise<ResponseMessage>

Sends the message to x-bees that the user is not authorized and interaction is required.


Identity and user data

version(): string

Returns the version string of the xbees-connect package.

getUserEmail(): string

Returns the email of the currently authenticated x-bees user, taken from URL parameters at construction time.

getUserPbxToken(): string

Returns the current PBX token. The token is updated automatically whenever the PBX_TOKEN event fires. The initial value is an empty string until the first token event is received.

getPbxDomain(): string

Returns the current PBX domain. Populated after user data is fetched from x-bees.

getUserExtension(): string | null

Returns the PBX extension of the current user, or null if not available.

getXBeesUser(): XBeesUser | null

Returns a cached XBeesUser object ({ id, email, extension, domain, name }) or null if the data has not been fetched yet. Triggers a background fetch on first call.

Deprecated behaviour: this method does not wait for the fetch to complete. If you need the user data before rendering, use getXBeesUserAsync() instead.

getXBeesUserAsync(): Promise<XBeesUser | null>

Asynchronous version of getXBeesUser. Waits for the user data to be fetched from x-bees before returning. Prefer this over the synchronous variant when the user object is required immediately.

const user = await client.getXBeesUserAsync();
if (user) {
  console.log(user.name, user.email);
}

getReferrer(): string

Returns the URL of the x-bees app that opened this integration, taken from URL parameters at construction time.

getBackToAppUrl(): string

Returns the deep-link URL that navigates the user back to this integration inside the x-bees app. The format differs between native and web platforms.

getStartPage(): StartPage | null

Returns the StartPage enum value parsed from the URL, or null if not present.

getProduct(): Product | null

Returns the Product enum value indicating from which x-bees product the integration was opened (e.g. contacts, conversations), or null if not specified.


Environment and platform

isPlatformNative(): boolean

Returns true when x-bees is running inside a React Native WebView.

isPlatformWeb(): boolean

Returns true when x-bees is running in a web browser (iFrame).

isOpenedFromXBees(): boolean

Returns true when the integration is running inside an x-bees iFrame or a React Native WebView. Returns false in standalone/dev mode; all send* calls will be no-ops in that case.

isVisible(): boolean

Returns true when the UI iFrame is currently active (visible to the user). Updated automatically via the VISIBILITY event.


UI state and launch mode

showsUi(): boolean

Returns true for all modes that render UI (ui, d, f). Opposite of isDataOnly().

isDataOnly(): boolean

Returns true when the integration is launched in no-ui or daemon mode (no UI rendered).

isSetupDialog(): boolean

Returns true when the integration is launched in dialog/setup mode (d or dialog).

isFullsize(): boolean

Returns true when the integration is launched in fullsize mode (f).

isActivationOnly(): boolean

Returns true when the integration is opened for activation/authorization purposes only (URL contains the authorize parameter).

isCloudBackendEnabled(): boolean

Returns true when cloud backend is enabled for this integration. Reads the cbi URL parameter at construction time (cbi=1true, cbi=0 or missing → false).


Context

getContext(): Promise<ResponseMessage>

Retrieves the current x-bees context data. The shape of the payload depends on the active context (e.g. contact view, conversation view).

getCurrentContact(): Promise<ResponseMessage>

Retrieves the contact data currently open in x-bees.

getCurrentConversation(): Promise<ResponseMessage>

Retrieves the conversation data ({ id, type }) currently open in x-bees. Resolves with undefined payload if the conversation is temporary.

getAvailableContactData(): Promise<ResponseMessage>

Retrieves contact data that x-bees has available for the current context (phone numbers, emails, etc.). Useful to pre-populate integration forms.


Theme

getThemeMode(): Promise<ResponseMessage>

Retrieves the current theme mode ('light' or 'dark').

getTheme(): Promise<ResponseMessage>

Retrieves the full theme object including mode and theme options (typography, palette).

onThemeChange(callback: (theme: IPayloadThemeChange) => void): RemoveEventListener

Starts listening for theme-change events. Invokes callback whenever the user changes the x-bees theme. Returns an unsubscribe function.


Token

getXBeesToken(): Promise<ResponseMessage>

Requests the current x-bees authentication token from x-bees. Use this when you need the token for API calls to x-bees services.

onPbxTokenChange(callback: (token: string) => void): RemoveEventListener

Starts listening for PBX token change events. Invokes callback with the new token value. Returns an unsubscribe function.


Calls

startCall(phoneNumber: string): Promise<ResponseMessage>

Sends a request to x-bees to initiate a call to the given phone number.

onCallStarted(callback: (info: IPayloadCallStartedInfo) => void): RemoveEventListener

Starts listening for the event fired when a call starts. Returns an unsubscribe function.

onCallEnded(callback: () => void): RemoveEventListener

Starts listening for the event fired when a call ends. Returns an unsubscribe function.

onDaemonCallStarted(callback: (info: IPayloadDaemonCallStarted) => void): RemoveEventListener

Starts listening for daemon-specific call start events. This event is independent from onCallStarted and carries daemon payload.

onDaemonCallFinished(callback: (info: IPayloadDaemonCallFinished) => void): RemoveEventListener

Starts listening for daemon-specific call finish events. This event is independent from onCallEnded and carries daemon payload.


Contacts

contactUpdated(query: ContactQuery, contact: Contact): Promise<ResponseMessage>

Notifies x-bees that a contact was created or updated. query identifies the contact ({ id?, email?, phone? }); contact contains the updated data.

contactMatchUpdated(query: ContactQuery, contact: Contact): Promise<ResponseMessage>

Notifies x-bees that a contact match was updated. Used when the integration resolves a contact lookup initiated by x-bees.

onSuggestContacts(callback: (query: string, resolve: SuggestContactsResolver, reject: Reject) => void): RemoveEventListener

Starts listening for contact auto-suggest requests from x-bees. When the user types in a contact search field, x-bees calls callback with the search string. Call resolve(contacts) to return results.

Client.getInstance().onSuggestContacts(async (query, resolve) => {
  try {
    const contacts = await fetchContacts(query);
    resolve(contacts);
  } catch (error) {
    console.log('catch', error);
  }
});

onLookupAndMatchContact(callback: (query: ContactQuery, resolve: LookupAndMatchContactsResolver, reject: Reject) => void): RemoveEventListener

Starts listening for single-contact lookup requests. x-bees supplies a ContactQuery and expects a single matched Contact via resolve.

Client.getInstance().onLookupAndMatchContact(async (query, resolve) => {
  try {
    const contact = await fetchContactAndMatch(query);
    resolve(contact);
  } catch (error) {
    console.log('catch', error);
  }
});

onLookupAndMatchBatchContacts(callback: (queries: ContactQuery[], returnResults: LookupAndMatchBatchContactsResolver) => void): RemoveEventListener

Starts listening for batch contact lookup requests. x-bees sends an array of ContactQuery objects. Call returnResults with a Map<ContactQuery, Contact | null | undefined> mapping each query to its result.

Client.getInstance().onLookupAndMatchBatchContacts(async (queries, returnResults) => {
  const resultsMap = new Map<ContactQuery, Contact | null>();
  for (const query of queries) {
    resultsMap.set(query, await fetchContact(query));
  }
  returnResults(resultsMap);
});

onIntegrationProxyRequest(callback: (request, resolve, reject) => void): RemoveEventListener

Registers a handler for read-only Salesforce REST proxy requests from x-bees. Subscribe during app startup (same pattern as contact flows). On registration, x-bees is notified that the integration supports this flow (INTEGRATION_PROXY_REQUEST_IS_SUPPORTED).

  • Request (IntegrationProxyRequest): path (relative Salesforce URL only), optional query, optional requestId.
  • Resolve (IntegrationProxyRequestResolver): pass IntegrationProxyResponse with ok, path, optional requestId / data / error, and required meta: { source: 'salesforce', validated, validationWarnings? }. Structured domain errors use error.code (e.g. NOT_AUTHORIZED, INVALID_PATH, PATH_NOT_ALLOWED, MISSING_QUERY_PARAM, INVALID_QUERY_PARAM, EXECUTION_FAILED).
  • If response.error?.code === 'NOT_AUTHORIZED', the client calls isNotAuthorized() before sending the proxy response to x-bees.
  • Reject (Reject): use only for unexpected runtime exceptions (string reason).

Scope (first iteration): read-only calls only. Use relative paths such as /services/data/v59.0/sobjects/Contact/003... or /services/data/v59.0/query with query: { q: 'SELECT ...' }. No composite, tooling, OAuth, create, update, or delete.

Client.getInstance().onIntegrationProxyRequest(async (request, resolve, reject) => {
  try {
    const response = await handleIntegrationProxyRequest(request);
    resolve(response);
  } catch (error) {
    reject(String(error));
  }
});

createContactIsSupported(): Promise<ResponseMessage>

Sends a signal to x-bees indicating that this integration supports creating contacts. Call once during initialization if your integration handles contact creation.

createContactHasNoPermission(): Promise<ResponseMessage>

Sends a signal to x-bees indicating that the current user does not have permission to create contacts.


Navigation

onRedirectQuery(callback: Callback<EventType.REDIRECT_QUERY>): RemoveEventListener

Starts listening for redirect query events. Fires when the user opens the app via a deep-link that targets this integration. Returns an unsubscribe function.

onStartRedirectToEntityPage(callback: Callback<EventType.START_REDIRECT_TO_ENTITY_PAGE>): RemoveEventListener

Deprecated. Use addEventListener(EventType.START_REDIRECT_TO_ENTITY_PAGE, callback) instead.

Starts listening for the event that signals x-bees is navigating to an entity page (e.g. conversation). The payload contains { conversationId, pageName }. Returns an unsubscribe function.

onCancelRedirectToEntityPage(callback: Callback<EventType.CANCEL_REDIRECT_TO_ENTITY_PAGE>): RemoveEventListener

Deprecated. Use addEventListener(EventType.CANCEL_REDIRECT_TO_ENTITY_PAGE, callback) instead.

Starts listening for the event that signals a pending redirect to an entity page was cancelled. The payload contains { conversationId }. Returns an unsubscribe function.


Visibility and lifecycle

onVisibilityChange(callback: (isVisible: boolean) => void): RemoveEventListener

Starts listening for iframe visibility changes. callback receives true when the iFrame becomes active and false when it is hidden. Returns an unsubscribe function.

reboot(): Promise<ResponseMessage>

Sends a request to x-bees to restart the iFrame and reload it with the latest parameters and token.

onLogout(callback: Callback<EventType.LOGOUT>): RemoveEventListener

Starts listening for the logout event. Notifies x-bees that the integration supports logout. callback is invoked when x-bees requests a logout action.


Contact events

onContactWeightUpdate(callback: Callback<EventType.CONTACT_WEIGHT_UPDATE>): RemoveEventListener

Starts listening for contact weight update events. Fires when x-bees recalculates the relevance weight of a contact. The payload contains { id, query }. Returns an unsubscribe function.

onContactRefresh(callback: Callback<EventType.CONTACT_REFRESH>): RemoveEventListener

Starts listening for contact refresh events. Fires when a contact was updated in the x-bees daemon and the open integration should re-fetch its data. Returns an unsubscribe function.


UI utilities

showToast(message: string, severity?: ToastSeverity): Promise<ResponseMessage>

Displays a toast notification inside the x-bees UI. severity defaults to 'INFO'. Accepted values: 'INFO', 'WARNING', 'ERROR', 'SUCCESS', 'NOTICE'.

client.showToast('Contact saved', 'SUCCESS');

setViewport(payload: { height: number | string; width: number | string }): Promise<ResponseMessage>

Sends a request to x-bees to resize the iFrame to the specified dimensions.

toClipboard(payload: string): Promise<ResponseMessage>

Sends a request to x-bees to write the given string to the user's clipboard.


Event listeners (generic)

addEventListener<T extends EventType>(eventName: T, callback: Callback<T>): RemoveEventListener

Starts listening for any x-bees event by name. Returns an unsubscribe function. Prefer the typed convenience methods (onThemeChange, onCallStarted, etc.) when available.

removeEventListener<T extends EventType>(eventName: T, callback: Callback<T>): void

Stops listening for the specified event with the given callback reference.

off(callback: Callback | StorageEventCallback): void

Removes the given callback from all event listeners, including local storage listeners registered via onStorage.


Analytics

sendAnalytics(eventName: string, params?: Record<string, string>): void

Sends an analytics event to x-bees for tracking. params is an optional map of string key-value pairs.

client.sendAnalytics('contact_viewed', { contactId: '123' });

Local storage

These methods read and write to the browser's localStorage, namespaced per integration.

saveToStorage<T>(key: string, value: T): void

Saves a value to localStorage under the given key. The value is serialized to JSON automatically.

getFromStorage<T>(key: string): T | null

Retrieves and deserializes a value from localStorage. Returns null if the key does not exist.

deleteFromStorage(key: string): void

Removes the entry with the given key from localStorage.

setIntegrationStorageKey(integrationKey: string): void

Switches the localStorage namespace to the specified parent integration key. Use this when the integration inherits storage from a parent integration.

onStorage(listener: StorageEventCallback): () => void

Registers a listener for localStorage change events (native StorageEvent). Returns an unsubscribe function.

const unsubscribe = client.onStorage((event) => {
  console.log('Storage changed:', event.key, event.newValue);
});

x-bees storage

These methods persist data in x-bees' own server-side storage, not in the browser's localStorage. Data stored here survives browser clears and is available across devices.

saveInXbeesStorage<T>(key: string, value: T): void

Saves a value to the x-bees storage. The value is serialized to a JSON string before sending.

getFromXbeesStorage(key: string): Promise<ResponseMessage>

Requests a stored value from x-bees storage by key. Resolves with a ResponseMessage whose payload contains the stored value.

removeFromXbeesStorage(key: string): void

Removes the entry with the given key from x-bees storage.


Custom events

sendCustomEvent({ type: string, payload?: JSONValue }): void

Sends a custom event to x-bees with an arbitrary type string and optional JSON-serializable payload. Use this for integration-specific communication not covered by the built-in event types.

client.sendCustomEvent({ type: 'my_action', payload: { foo: 'bar' } });

sendDropdownVisibilityEvent(dropdownVisibilityStatus: boolean): void

Legacy: prefer sendCustomEvent for new integrations.

Notifies x-bees when a dropdown inside the integration opens or closes, which allows x-bees to enable nested scrolling on Android WebView.


Chat connections

setChatToOpen(chatId: string): void

Tells x-bees which chat or conversation should be opened (brought into focus). The integration sends ClientEventType.SET_CHAT_TO_OPEN (xBeesSetChatToOpen) with payload { chatId }. The call returns immediately; x-bees applies the navigation when it handles the message.

client.setChatToOpen('chat_id');

getChannelsByEmailOrPhone(payload: IPayloadGetChannelsByEmailOrPhone): Promise<ResponseMessage>

Asks x-bees to look up chat channels for an email address or phone number. The integration sends ClientEventType.GET_CHANNELS_BY_EMAIL_OR_PHONE (xBeesGetChannelsByEmailOrPhone) with payload { value, type }, where type is 'email' or 'phone'. Resolves with a ResponseMessage whose payload contains the matching channels returned by x-bees.

const { payload } = await client.getChannelsByEmailOrPhone({ value: '[email protected]', type: 'email' });

Route synchronization

sendRouteChange(route: string, options?: { replace?: boolean }): void

Sends a local route change to the connected parent or iframe. Pass the route as a full app-relative string, including path, search, and hash when needed, for example /contacts/123?tab=info#notes.

Pass { replace: true } to ask the host to update the current browser history entry instead of pushing a new one. Omit replace (or set it to false) to keep the default push behavior. Use replace for load-time sync and intermediate/tab transitions that should not appear in back/forward history.

client.sendRouteChange('/contacts/123');
client.sendRouteChange('/contacts/123?tab=info', {replace: true});

onExternalRouteChange(callback: Callback<EventType.EXTERNAL_ROUTE_CHANGE>): RemoveEventListener

Starts listening for route changes from the connected parent or iframe. Returns an unsubscribe function. The callback receives IPayloadRouteChange ({ route, replace? }).

Use the same pair on both sides of the bridge:

// Parent route changed.
parentClient.sendRouteChange('/contacts/123?tab=info');
iframeClient.onExternalRouteChange(({route, replace}) => {
  syncIframeRouter(route, {replace});
});

// Iframe route changed.
iframeClient.sendRouteChange('/contacts/456');
parentClient.onExternalRouteChange(({route, replace}) => {
  syncParentRouter(route, {replace});
});

When handling a route received through onExternalRouteChange, avoid sending the same value back with sendRouteChange. Compare it with the current local route before applying it to prevent synchronization loops.


Technical support

getTechnicalSupport(): TechnicalSupport

Returns the TechnicalSupport singleton, which provides utilities for reporting diagnostic information to x-bees support.


Known issues

The below function can fix cases when String.replaceAll() does not work in the mobile version. Most likely, this is some kind of WebView bug.

function replaceAll(str: string, search: string, replace: string) {
  return str.split(search).join(replace);
}