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

@joedski/vue-flyd

v0.4.1

Published

Use Flyd in Vue! If some reaction is good, more is better, right?

Downloads

9

Readme

vue-flyd

Use flyd in Vue! Make a delicious Vuebeer Float!

NOTE: While in v0.x, API may not be stable!

This is kind of silly, but could offer you an easy way to try out streams if you're coming from a vue background. Or, possibly, you have a few components with very hairy interactions and you want to leverage the power of streams to manage that complexity. Or you just like bolting things together without regard for others' sanity! :D

I made this in a fit of pique when trying to embed some other webapp in a webapp that already embeds too many other webapps, where all those webapps could cause events the others had to respond to. I already had to resort to notating things in streams just to make sense of all the moving parts, so I figured, why should I have to translate all that back into imperative-procedural malarkey?

Usage

npm install --save vue-flyd

Then you can do this in your component

<template lang="html">
  <div class="counter">
    <div class="counter-value">{{ currentCount }}</div>
    <div class="counter-controls">
      <button @click="$streams.incrementClicks">Increment</button>
    </div>
  </div>
</template>

<script>
import flyd from 'flyd'
import { StreamsMixin } from 'vue-flyd'

export default {
  name: 'Counter',
  
  mixins: [StreamsMixin],
  
  streams() {
    const incrementClicks = flyd.stream()
    const currentCount = incrementClicks.pipe(flyd.scan(
      acc => acc + 1,
      0
    ))
    return {
      sources: { incrementClicks },
      sinks: { currentCount },
    }
  },
}
</script>

You can also use it as a plugin:

import Vue from 'vue'
import VueFlyd from 'vue-flyd'

Vue.use(VueFlyd)

Now every component can have streams()!

API

Use as a Plugin

As noted above, you can install vue-flyd as a plugin:

import Vue from 'vue'
import VueFlyd from 'vue-flyd'

Vue.use(VueFlyd)

Use as a Mixin: StreamsMixin

The plugin applies the StreamsMixin at the top level. You can also import it directly and apply it only to components you want to have streams, as shown below.

import { StreamsMixin } from 'vue-flyd'

export default {
  mixins: [StreamsMixin],

  // Now you can setup streams in this component option:
  streams({ fromWatch }) {
    // First, define your sources...
    // Then, define processing and sinks...
    return {
      sources: { /* ... sources exposed here */ },
      sinks: { /* ... sinks exposed here */ },
    }
  },
}

Component Option streams

The StreamsMixin adds support for a Component Option named streams, which is a function. You use this function to define the per-instance streams of your component.

  • Type: (utilities: Utilities) => { sources: { [name: string]: Stream<any> }, sinks: { name: string]: Stream<any> } }

Parameters of Component Option streams

The Component Option streams has one parameter:

  • utilities: { [utilityName: string]: any }
    • An object holding a collection of utility functions. Currently there is only one utility function.
    • utilities.fromWatch: (binding, options = { immediate: true }) => Stream
      • Creates a new Stream which is updated by the watched property or value. This utility function can be used to watch other Data Values in a Vue Component, or stream changes of the Vue Component's Props. Anything you can pass to vm.$watch(), basically.
      • Parameters:
        • binding: string | () => TWatchValue A watch binding passed to vm.$watch(). The value that results from that watch binding will be pushed into the resultant Stream.
        • options: Partial<{ immediate: boolean, deep: boolean }> | void Optional Options passed to vm.$watch().
          • By default, options.immediate is true unless you explicitly pass false for that option.
      • Returns:
        • Stream<TWatchValue> A stream that will have values from the Watch Binding.

Return Value of Component Option streams

  • Type: { sources: { [name: string]: Stream<any> }, sinks: { [name: string]: Stream<any> } }
  • An object with two keys: sources and sinks, each an object one mapping names to Streams.
    • Sources returned will be accessible at this.$streams.$sources[sourceName] and are aliased at this.$streams[sourceName] for convenience.
      • These Source Streams are the inputs into your stream processing stuff, and they're where you'll push inputs into, for instance, DOM events or component events of various sorts.
    • The Sink Streams will be accessible at this.$streams.$sinks[sinkName].
      • Each Sink Stream returned will result in a Data prop of the same name which will hold the current value of that Sink Stream.

Example: fromWatch()

export default {
  mixins: [StreamsMixin],

  streams({ fromWatch }) {
    // For things like event streams, we just create a plain stream.
    const mouseEvents = flyd.stream()

    // For creating a stream from a prop, we can just watch the prop.
    const labelProp = fromWatch('prop')

    // For some cases, you can watch a derivation instead of just a prop.
    const combinedProp = fromWatch(() => this.a + this.b)

    // You can also pass options to fromWatch().
    const deepProp = fromWatch('someObjectProp', { deep: true })

    // Do something with the sources from above.
    const bigFatArrayOfEverything = flyd.combine(
      (...deps, self, changed) => {
        return deps.map(dep => dep())
      },
      [sources.mouseEvents, sources.labelProp, sources.combinedProp, sources.deepProp]
    )

    return {
      sources: { mouseEvents, labelProp, combinedProp, deepProp },
      sinks: { bigFatArrayOfEverything },
    }
  },
}

Example: Counter with Reset

<template lang="html">
  <div class="counter">
    <!-- Here we have a Data value that's automatically updated by a Sink Stream of the same name -->
    <div class="counter-value">{{ currentCount }}</div>
    <div class="counter-controls">
      <!--
        Here, we use some Source Streams as the event handlers.
        This results in those events being pushed straight into the streams.
      -->
      <button @click="$streams.incrementClicks">Increment</button>
      <button @click="$streams.resetClicks">Reset</button>
    </div>
  </div>
</template>

<script>
import flyd from 'flyd'

import { StreamsMixin } from 'vue-flyd'

export default {
  name: 'CounterWithReset',

  mixins: [StreamsMixin],

  streams() {
    // For clicks and other DOM events, we just create plain streams,
    // Then as noted above, we shove events straight into them.
    const incrementClicks = flyd.stream()
    const resetClicks = flyd.stream()

    // Just to make things short, I made the actions plain functions...
    const actionTypes = {
      increment: acc => acc + 1,
      reset: () => 0,
    }

    // Replace each event with a function to call instead,
    // and merge those function streams together...
    const clickActions = flyd.merge(
      incrementClicks.map(() => actionTypes.increment),
      resetClicks.map(() => actionTypes.reset)
    )

    // Then just scan over the stream of functions that come through.
    const currentCount = clickActions.pipe(flyd.scan((acc, fn) => fn(acc), 0))

    // Finally, return any Sinks we want to expose to Vue.
    // A new Data value will be created with the same name for each Sink Stream.
    return {
      sources: { incrementClicks, resetClicks },
      sinks: { currentCount },
    }
  },
}
</script>