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

deekay

v1.0.7

Published

A simple vanilla JS front-end framework with no dependencies.

Downloads

6

Readme

Deekay

A simple vanilla JS front-end framework with no dependencies.

Why create 'Yet Another JS Framework'?

I've been using Backbone and JQuery forever. I really only use a small bit of the functionality they offer. So I decided to create a simple framework that only does that small bit.

Getting started

  npm install deekay

The easiest way to get started is to jump into the Example App.

To run it, you'll need a webserver. I recommend https://www.npmjs.com/package/http-server. After installing it run http-server and open a browser to http://localhost:8080/example/.

Usage

View

View is a class that provides a small subset of the functionality provided by Backbone.

View Documentation

  // create our variables up top
  const {View} = require('deekay');
  const template = require('./templates/search.hbs');
  const selector = '#content';
  const events = [
    {'type': 'submit', 'selector': '#search-form', 'listener': 'onSubmit'},
    {'type': 'search:refresh', 'listener': 'onRefresh'}
  ];
  const uri = '/api/search';
  const route = {'pathname': '/search/:query', 'name': 'Search', 'listener': 'show'};
  const binded = ['refresh'];
  
  // extend the View class
  class SearchView extends View {
    
    // pass in all our variables to the parent View
    constructor() {
      super({selector, template, events, route, uri, binded});
    }
    
    // callback when our route is triggered. Grab the 'query' property from params and render 
    // it in our template. The template will be inserted into #content. Notice that 'this' 
    // is already set to the SearchView instance. 
    show(params){
      this.query = params.query;
      this.render({
        'data': {
          'query': this.query 
        }
      });
    }
    
    // callback when our form is submitted. Call our API with the query using this.fetch.
    // The uri for fetch has already been set up top. If there is an error, the returned object
    // from this.fetch will have the 'error' property set to true. 
    async onSubmit(e, target) {
      e.preventDefault();
      const response = await this.fetch({
        'body': JSON.stringify({
          'query': this.query
        });
      });
      if (response.error === false) {
        alert('Good response'); 
      } else {
        alert('There was an error'); 
      }
      return false; 
    }
    
    // callback when a custom 'search:refresh' event is fired from another view because we 
    // included it in our events array up top.
    onRefresh(e, target) {
      setTimeout(this.binded.refresh, 500);
    }
    
    // refresh called from our setTimeout above. Notice that 'this' is already set to the SearchView 
    // instance because we set it in the binded array up top and used 'this.binded.refresh'.
    refresh() {
      this.render({
        'data': {
          'query': this.query 
        }
      }); 
    }
    
  }
  
  export {SearchView}

Query

Query is a class that provides a small subset of the functionality provided by jQuery. View the docs to see what it includes.

View Documentation

  const {Query} = require('deekay');
  
  const el = new Query('#some-id');
  el.addClass('myclass');
  el.text = 'Some new text';

Router

Router listens to browser location changes and fires when a known route is matched. If there is no match, a 'router:nomatch' event will be fired.

Router will listen for all clicks on anchor elements. When anchors are clicked the browser will not navigate to the new url, but will instead change the History state. If the anchor has target=_self the browser will perform a full navigation. If the anchor has target=_blank' it will open a new tab/window.

View Documentation

  const {Router} = require('deekay');
  
  // create a new router. It is a singleton and only one router can be created in an application.
  const router = new Router();
  
  // call this after all views are created to trigger the initial route. 
  router.execute();

All View instances automatically have the router set as a member, and will usually be accessed that way.

  const {View} = require('deekay');
  const template = require('./templates/not-found.hbs');
  const events = [
    {'type': 'router:nomatch', 'listener': 'show'},
    {'type': 'click', 'selector': '#home', 'listener': 'onClick'}
  ];
  
  class NotFoundView extends View {
    
    constructor() {
      super({events});
    }
    
    show(params) {
      this.render();
    }
    
    // #home was clicked. Navigate our router to '/'.
    onClick(e, target) {
      this.router.navigate({'href': '/'});
    }  
     
  }

DocumentListener

DocumentListener is rarely used directly, but rather through a View. Each view instance will get a member documentListener. Each application will only have one DocumentListener created (singleton).

View Documentation

  const {View} = require('deekay');
  
  // events added here with a selector property will be passed to the documentListener.on method
  const events = [
    {'type': 'click', 'selector': '#home', 'listener': 'onClick'}
  ];
  
  class NotFoundView extends View {
    
    constructor() {
      super({events});
    }
    
    // #home was clicked. We can add a class to it.
    onClick(e, target) {
      target.addClass('active');
    } 
    
    // We can add listeners this way as well
    addListener() {
      this.documentListener.on('click', '#some-id', (e, target) => {
        target.addClass('active');
      }, this);
    } 
     
  }

If you do want to use DocumentListener outside of a View.

  const {DocumentListener} = require('deekay');
  
  let documentListener = new DocumentListener();
  documentListener.on('click', '#some-id', (e, target) => {
    target.addClass('active');
  }, this);

EventBus

EventBus is used as a global event bus for custom events.

EventBus is rarely used directly, but rather through a View. Each view instance will get a member EventBus. Each application will only have one EventBus created (singleton).

View Documentation

  const {View} = require('deekay');
  
  // events added here without a selector property are considered custom events and will be passed 
  // to the eventBus.on method
  const events = [
    {'type': 'search:refresh', 'listener': 'onRefresh'}
  ];
  
  class SearchView extends View {
    
    constructor() {
      super({events});
    }
    
    // search:refresh was triggered 
    onRefresh(e, data) {
      console.log(data);
    } 
    
    // We can add listeners for custom events this way too
    addListener() {
      this.on('search:refresh', this.onRefresh);
    } 
     
  }

Stop listening for a custom event.

  const {View} = require('deekay');
  
  class SearchView extends View { 
    
    removeListener() {
      this.off('search:refresh', this.onRefresh);
    } 
     
  }

Trigger a custom event.

  const {View} = require('deekay');
  
  class SearchView extends View { 
    
    triggerEvent() {
      this.trigger('search:refresh', data);
    } 
     
  }

If you do want to use EventBus outside of a View.

  const {EventBus} = require('deekay');
  
  let eventBus = new EventBus();
  eventBus.on('search:refresh', (e, data) => {
    console.log(data);
  });

Build from source

Deekay is written in ES6. To compile it for use in browsers, use Rollup. The command to compile is - npm run build

To create the latest docs, you can do npm run jsdoc

Babel / CoreJS

Deekay targets modern browsers but can work all the way back to IE11 with a few polyfills. If using CoreJs you'll need to include these features to work properly. Learn more here - https://github.com/zloirock/core-js

import 'core-js/features/array/for-each';
import 'core-js/features/array/find';
import 'core-js/features/promise';
import 'core-js/web/dom-collections';
import 'core-js/features/object/assign';