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

@evilkiwi/embed

v1.3.0

Published

Vue 3 Utility Hook for cross-origin iFrame IPC

Downloads

227

Readme

@evilkiwi/embed provides a single Vue 3 hook which can be used to communicate between an iFrame and its parent via postMessage IPC.

  • sync/async messaging/responses
  • Configurable timeouts
  • Bi-directional communication
  • Cross-origin support
  • Same usage/API for both Host & Client
  • Support for enforcing origins for increased security
  • No limit to number of instances you can use/create at any given time
  • TypeScript
  • Tiny (1.73kb)

Installation

This package is available via NPM:

yarn add @evilkiwi/embed

# or

npm install @evilkiwi/embed

Usage

For this example, we'll assume the host is a webpage (example.com) and the client is a webpage embedded in an iFrame (frame.example.com). The only difference between a host and a client is that the host requires an iFrame ref for binding and sending the messages.

/** * Host */
<template>
  <iframe src="https://frame.example.com" ref="iframe" sandbox="allow-scripts" />
</template>

<script lang="ts" setup>
import { useEmbed } from '@evilkiwi/embed';
import { onMounted, ref } from 'vue';

const iframe = ref<InstanceType<typeof HTMLIFrame>>();

const { send, events } = useEmbed('host', {
  id: 'shared-id',
  iframe,
  remote: 'https://frame.example.com',
});

// Listen for any synchronous events being emitted over IPC
events.on('yay', payload => {
  console.log(payload);
});

onMounted(async () => {
  // Send an event to the iFrame and wait for a response.
  const response = await send('hello-world', {
    hello: 'world',
  });
});
</script>

/** * Client */
<template>
  <button @click.prevent="submit">Click me!</button>
</template>

<script lang="ts" setup>
import { useEmbed } from '@evilkiwi/embed';

const { handle, post } = useEmbed('client', {
  id: 'shared-id',
  remote: 'https://example.com',
});

// Resolves incoming (a)synchronous operations.
handle('hello-world', async payload => {
  if (payload.hello === 'world') {
    return 'hey';
  }

  return 'go away';
});

const submit = () => {
  // Send a synchronous event to the host
  post('yay', { test: 123 });
};
</script>

This example shows:

  • Initializing the Host and Client
  • Sending and waiting for asynchronous events
  • Sending and receiving synchronous events

Since communication is bi-directional, you can use any of the methods on either Host or Client. For example, asynchronous operations aren't limited to Host -> Client, the Client can also call asynchronous operations and the Host can register handlers/resolvers.

| Option | Default | Type | Description | | ---------- | ----------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------- | | id | [Required] | string | The Host and Client that you want to talk to each other should share the _same_ ID. | | timeout | 15000 | number | Configures the global timeout for all asynchronous operations against this ID pair. | | iframe | [Required for Host] | Ref<InstanceType<typeof HTMLIFrame>> | A Vue 3 ref for a Template reference. | | remote | * | string | A remote URL to limit who can recieve/process Events over this Host/Client pair. | | debug | false | boolean | Whether to print Debug messages to the console, providing an overview of the IPC process. |

Security Note

By default, if you don't supply a remote, the library will process all incoming messages and send events that any party can recieve. By setting this to a URL (See above example), you can limit this and hugely reduce the impact it has on security.

To-do

  • Add a test suite