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

frame-subscriber

v0.0.9

Published

Subscribe to messages from different iframes

Downloads

3

Readme

frame-subscriber

基于postMessage 在不同iframe之间的通信

基本用法

一个iframe下只有一个client 总线实例,所以initializeClient返回的总是同一个对象

// 首先在所有的iframe中使用 frame-subscriber

// iframe one
import initializeClient, {subscriber} from 'frame-subscriber'

let client = initializeClient()
client.on('say', function(payload){
    console.log('say ', payload.data, payload.from)
})
// iframe two
import initializeClient from 'frame-subscriber'

let client = initializeClient()
client.emit('say', 'hello')

// iframe one 将打印 'say hello'

订阅事件

import initializeClient from 'frame-subscriber'

let client = initializeClient()

client.on('some-event', function (payload) {
    console.log('some event fired', payload.data)
})

// 仅触发一次
client.once('some-event', function (payload) {
    console.log('only run once', payload.data)
})
/**
 * 所有监听了'foo' 的iframe订阅器都将调用
 */
client.emit('foo', 'hello')

// 主要方法都可以链式使用
client.once('some-event', handler)
.on('other-event', handler)
.emit('my-emit', 'hello')

指定订阅


// 有时候,我们需要指定某些iframe的事件被触发,而不仅仅是根据事件名,这里就需要用到订阅器

let sub = subscriber({namespace: 'cool'})
// 现在这个namespace 为cool的订阅器仅仅会在emit指定相同的namespace时才会被触发

sub.on('test', handler)
// 其他iframe下,这样才能触发上一个订阅器的cool事件
client.emit('test', 'realy cool', { namespace: 'cool'})
/**
 * 仅namespace为'awesome'的订阅器的foo事件会被触发
 */
client.emit('foo', 'hello', {namespace: 'awesome'})


function handler(payload){
    console.log(`${payload.type} fired`, payload.data, payload.from, payload.to)
}
// on方法也有指定订阅功能
// 仅为namespace
client.on('foo', handler, {namespace: 'love'})

// other iframe
// 上一个指定namespace love 的订阅监听将会触发,并且payload.to也会有数据
client.emit('foo', 'hello', { namespace: 'love'})

高级用法

自定义处理client的事件

import {Events} from 'frame-subscriber'

client.on(Events.ORIGIN_RECEIVE, function customHandlerEvent(payload){
    if(['foo','bar'].include(payload.from.namespace)){
        console.log(payload.data)
    }
})
// Events事件常量还有其他内部事件,
client.on(Events.CREATED, handler)
.on(Events.EXPECT_RECEIVE,handler)
.on(Events.DECLINE.handler)

Client

initializeClient(options?: ClientOptions): Client 事件总线

Type

ClientOptions

{
    /**
     * client唯一标识,你可以指定它,否则将自动生成
     */
    unique?: string
    /**
     * client的命名空间
     */
    namespace?: string
    /**
     * client允许被通信的origin
     */
    origin?: string
    /**
     * emit方法使用的默认option
     */
     emit?: BaseOptions
     /**
     * 控制是否接收消息,返回false则不接收
     */
    shouldReceive?: (payload: Payload) => boolean
}

let client = initializeClient({
    unique: 'foo',
    namespace: 'bar'
})
 

Method

on<T = any>(type: string, listener: EventHandler<T>, options?: SubscriberOptions): Client

监听事件,如果提供了有效options,内部会创建对应的Subscriber,更推荐手动创建Subscriber去监听对应事件,这更利于管理

once<T = any>(type: string, listener: EventHandler<T>, options?: SubscriberOptions): Client

类似于on,但只监听一次

off(type: string, listener?: EventHandler, options?: BaseOptions): Client

移除监听事件

emit(type: string, data: any, options?: BaseOptions): Client

触发事件

whenReady(callback: EventHandler): Client

当其他frame下的Client被创建时(或者已经创建)运行

whenReady(unique: string | string[], callback: EventHandler): Client

当指定的frame下的Client被创建时(或者已经创建)运行

send(message: any, targetOrigin?: string)

同postMessage

Subscriber

基于Client的订阅器,订阅器在client上接受特定的事件,可以认为ClientSubscriber的中转站,Subscriber只订阅Client转发的部分消息

subscriber(options?: SubscriberOptions): Subscriber

SubscriberOptions {
    unique?: string
    namespace?: string
    origin?: string
}

这三个参数与client作用一致,需要注意的是,如果client已经指定了某一个,限制了消息的订阅,那么订阅器就会失效

var myClient = initializeClient()

// 其他 client 发送给`subscriber-namespace`
var mySubscriber = subscriber({namespace: 'subscriber-namespace'})


// in other frame
var otherClient = initializeClient()

// mySubscriber将收到消息
otherClient.emit('test', 'data', {namespace: 'subscriber-namespace})

Method

Subscriber同样拥有 on,once,off, offAll方法,于Client不同的是, 没有options参数

remove

从client上移出这个订阅器,并移出它的所有事件监听