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 🙏

© 2024 – Pkg Stats / Ryan Hefner

interlocking-iframe-messenger

v5.0.0

Published

Post messages to a child iframe while accounting for race conditions.

Downloads

803

Readme

interlocking-iframe-messenger

Post messages to a child iframe while accounting for race conditions.

Potential race conditions that are handled include:

  • [x] waiting for the iframe to load
  • [x] waiting for the iframe content to finish loading (yes, this is different from the condition above)
  • [x] any lag in the iframe content from scripts
  • [x] anything else that may cause an iframe to miss a message

Currently this only works as the parent content being the communication initiator. The child only responds to messages from the parent, it doesn't send messages of its own accord. If the parent is ready for specific data from the child, it must send a message to request that data.

See a simple live demo at electrovir.github.io/interlocking-iframe-messenger.

install

npm i interlocking-iframe-messenger

usage

Follow the headings below in order for a full usage example.

setup

First, setup an iframeMessenger. Make sure to provide a list of allowed origins for security purposes. (If you do not provide any, warnings will be logged in your console.)

Make sure to provide a generic type to createIframeMessenger so that your message data is typed. The given type should match a similar structure to MessageData shown below.

import {createIframeMessenger, MessageDirectionEnum} from 'interlocking-iframe-messenger';

export enum MessageTypeEnum {
    RequestDataFromChild = 'request-data-from-child',
    SendDataToChild = 'send-data-to-child',
}

export type MessageData = {
    [MessageTypeEnum.RequestDataFromChild]: {
        [MessageDirectionEnum.FromParent]: undefined;
        [MessageDirectionEnum.FromChild]: string;
    };
    [MessageTypeEnum.SendDataToChild]: {
        [MessageDirectionEnum.FromParent]: string;
        [MessageDirectionEnum.FromChild]: undefined;
    };
};

export const myIframeMessenger = createIframeMessenger<MessageData>();

send a message to the child iframe

Use the .sendMessageToChild() method on IframeMessenger to send messages to the child iframe.

Based on the given message type, if data is expected from the child iframe, a verifyChildData function must be provided. This will get called internally by sendMessageToChild and if verifyChildData returns false, sendMessageToChild will fail.

import {MessageTypeEnum, myIframeMessenger} from './messenger-setup.example';

async function sendMyMessage(iframeElement: HTMLIFrameElement) {
    const childValue: string = (
        await myIframeMessenger.sendMessageToChild({
            iframeElement,
            childOrigin: 'https://example.com',
            type: MessageTypeEnum.RequestDataFromChild,
            data: undefined,
            // if data is expected from the child, a verifyChildData function must be provided
            verifyChildData(childData) {
                return typeof childData === 'string';
            },
        })
    ).data;

    // this will end up logging the string value that the child generated
    console.log({childValue});
}

sendMyMessage(
    // pass in a reference to your iframe
    document.querySelector('iframe')!,
);

listen to messages from the parent

Use .listenForParentMessages() in the child iframe source code to properly handle parent messages and respond when required. Notice that, in the example below, when the parent is expecting a response (when the type is MessageTypeEnum.RequestDataFromChild), the listener directly returns the data which the parent is expecting and waiting for.

import {MessageTypeEnum, myIframeMessenger} from './messenger-setup.example';

myIframeMessenger.listenForParentMessages({
    parentOrigin: 'https://example.com',
    listener: (message) => {
        if (message.type === MessageTypeEnum.RequestDataFromChild) {
            // send the data that the parent is expecting
            return 'some string from the child';
        } else if (message.type === MessageTypeEnum.SendDataToChild) {
            const parentData = message.data;

            // process parentData here
        }

        return undefined;
    },
});