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

oculusx

v0.4.1

Published

Upgrade objects to observables

Downloads

19

Readme

oculusx

Easy javascript object observing for browser and node

Oculus is a latin word for eye or sight

See Demo

Watching


import { watch } from 'oculusx';

const appData = {
    // empty state at first, but it can be a fully populated object
};

watch(appData)
    ('user.name', (value) => {
        // do something when the name changes
    })
    ('user', (value) => {
        // do something when the whole user object changes
        // subscription to name remains even if the user is a whole new object and will be invoked
    });

appData.user = {
    name: 'John Doe' // both wathcers are inboked
};

appData.user.name = 'Jane Doe'; // user.name watcher is invoked

appData.user = undefined; // both watchers are invoked

appData.user = {
    name: 'Jordan Doe' // user.name is still intact and both watchers will be invoked.
};

Unwatching a specific callback

import { watch, unwatch } from 'oculusx'

const handler_1 = (value) => {
    // do something
};

const handler_2 = (value) => {
    // do something
};

watch(appData)
    ('user.name', handler_1)
    ('user.name', handler_2);

unwatch(appData)('user.name', handler_1);

appData.user = {
    name: 'Jaquelin Doe' // only handler_2 is invoked
};

Unwatching all callbacks from a specific path

import { watch, unwatch } from 'oculusx';

watch(appData)
    ('user', () => { /* do something useful */ }) // callback #1
    ('user', () => { /* do something useful */ }) // callback #2
    ('user.name', () => { /* do something useful */ }); // watch user.name

unwatch(appData)('user'); // removes all user object watchers

appData.user.name = 'James Doe'; // user.name watcher is invoked
appData.user = {
    name: 'Jimmy Doe' // Only user.name watcher is invoked
};

Immediate invocation


watch(target)(path, callback, true);

Alternative syntax

For those who dislike currying syntax:

watch(target)
    (path, callback)
    (path2, callback2);

// equals
watch(target, path, callback);
watch(target, path2, callback2);

// or
watch(target, path, callback)
    (path2, callback2);

It also works the same for unwatch.

DOM Binding - browser only feature

Demo

Interface:

type NodeBindingOptions = {
  method?: 'attribute'|'text', // defaults to 'text'
  attribute?: string, // attribute to be changed applicable only when method is 'attribute',
  compute?: Function // observed value can be computed before injected to the element
};

bindToElement (model: Object, target: Element, path: string, options?:NodeBindingOptions) => Function
// returns unsubscribe function to stop binding

Example:

import 'oculusx/bind-to-element';
const someElement = document.querySelector('#myElement');
const model = {}
const unsubscribe = oculusx.bindToElement(model, someElement, 'path.to.data');
model.path.to = {
  data: 'Hello, world'
}; // element's text changed to 'Hello, world'
unsubscribe(); // element is no longer bound to model

Using options:

const someElement = document.querySelector('#myElement');
const unsubscribe = oculusx.bindToElement(model, someElement, 'path.to.data', {
  method: 'attribute',
  attribute: 'my-attr-name',
  compute: x => x.toLowerCase()
});

Future releases

  • Unwatching all nested pathes: unwatch(target)('some.path.*');
  • Unwatching all pathes from an object: unwatch(target, '*');
  • Watching arrays. Currently partially working only when shift/unshift are invoked or the whole array is replaced
  • Documentation

Installation

npm i oculusx yarn add oculusx