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

diamondhands

v0.1.10

Published

MVC OO React

Downloads

23

Readme

Diamondhands

React JS designed around the desire to write code such as:

<span>{ user.fullName.value() }</span>

🔮 or 🪄

<span>{ user.fullName.edit() }</span>

Inspired by stimulus.

Suggested JS folder structure

// app/javascript/app/...

JS strucure is suggested to mirror what one would typically find in a Rails app as much as possible. The models, controllers, views of JS are a different beast, but the MVC style division of labor can be the same.

This convention should speed up development by abstracting such things as validations into JS model files, and API requests into controller files. In addition none of the view or model files will contain and request response logic. And the controllers and views should contain no validation logic. The hypothesis is that this will clean up development for the average person on a team by not having to deal with controller API requests or validations at the same time as interacting with the views, which is normally the case in React codebases. The views may just contain <span>{ user.fullName.value() }</span> or <span>{ user.fullName.edit() }</span> for example to render a self-saving editiable input.

Models

For handling data and business logic.

Views

For handling graphical user interface objects and presentation.

// app/javascript/app/views/...

/html This folder is intended to store bits of html & css without any interactivity or other functionality. All html & css or styled_components should be in this folder.

/atoms This folder is intended to import html & css components from the html folder and add very simple pieces of functionality. Atoms can only contain one piece of state, one value.

/molecules This folder contains traditional React components. Components here are intended to import pieces of functionality from the atoms folder and combine them into re-usable route components.

/routes This folder is intended to import from the atoms & molecules folders and contain the root javascript file for each individual url of the application.

Controllers

Handle the request response logic. Graphql queries will be defined and composed in the controllers.

Other features

store.ts contains a simplified reducer to handle all state in the application. Store keys 🗝 are generated automatically in resolver.ts or can be added manually to components that want to talk to the store. You can talk to the store manually via:

import { store } from "diamondhands";

store.set({
  someKey: {
    nested: "🧞‍♀️"
  }
});
//...
store.get("someKey.nested");

This example is automatically associated with a model:

import React from "react";
import user from "app/models/user.ts";

class Input extends Atom {
  constructor(props) {
    super({
      ...props,
      model: user
    });
  }
}

This component is using the store for whtever it wants with its file path as a key 🗝:

class Header extends Molecule {
  constructor(props) {
    super({
      ...props,
      storeKey: "views.molecules.Header"
    });
  }
}

The Store key should always be the path to the file within the javascript application ("views.atoms.Input"). TODO: Add some validation around this. Example controller:

import ApolloController from "../../lib/diamondhands/ApolloController";
import { GetJobs } from "./generated/graphql";

class JobsController extends ApolloController {
  accessor() {
    return "jobs";
  }

  index() {
    return GetJobs;
  }
}

Examle model:

import Model from "lib/diamondhands/Model"
import JobsController from "app/controllers/JobsController";

class Job extends Model {
  constructor() {
    super();

    this.controller = new JobsController();
  }

  name() {
    return "jobs";
  }

  resolvers() {
    return [{
      attr: "index"
    }];
  }
}

export default new Job;

Debugging diamondhands should be easy to do. Other existing libraries have been avoided intentionally in diamondhands to keep debugging as simple and strightforward as possible, without getting lost in other people's code. Libraries can be heavily abstracted in some cases for issues that we may not even have, or are not trying to handle.

Data flow

  • Muon handles client store <-> atom state

  • Proton handles server <-> client store state

  • Rails controllers (empty) -> erb files (empty) -> React router (see routes.ts) -> app/views/routes

  • Routes -> Molecules -> Atoms (single piece of state)

  • Atom components -> resolver.ts -> Muon#quark -> controller action

  • Model files define what attrs are available, and controller files define the graphql to access that data.

  • You can also make calls directly from methods generated on the model.

import search from "app/models/search";

class SearchAnything extends React.Component {
  ...
  private searchJobs = () => {
    search.anything.query({ search_term: this.state.searchTerm });
  }
}

Models are given lowercase filenames, as they export an instance export default new Job; Controllers are always referenced via the model, where they are instantiated.

Logging

🚏 Router props: {env: {…}} 🧬 Quark attr: fullName 🧩 Fetching... 🌀 Starting get from server... user 🎩 Server: http://localhost:3000 🍱 Store state: {serverProps: {…}} 🦭 Server sha: 7ffcba4c7df7cd6fb99d5fcf96dda146ddec3768 📜 Response: {profile: {…}} 🧩 Fetched Justin Ancherh