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

gorgona

v0.0.2

Published

Minimal reactive toolset. With a React hook

Downloads

3

Readme

GORGONA

Minimal reactive toolset. With a React hook

Installation

npm i gorgona

Roster

  • Subject. An object that holds an observable value.
    Observers can subscribe to changes of the value.

  • Observable. A Subject to be exposed to the outside world.
    Encapsulates everything

  • Observer. Just a type of the function which can be subscribed to a Subject

  • useObservable. A React hook to easily use Observables within React components.

Usage

Vanilla

Let's say we're making an app for our favorite band. The app is meant to notify us fans about a new release.

import { Subject, Observable } from 'gorgona';

class Artist {
	public discography$: Observable<string[]>;

	private _discography$: Subject<string[]>;

	public constructor(previousReleases: string[]) {
		this._discography$ = new Subject(previousReleases);
		this.discography$ = this._discography.asObservable();
	}

	public releaseNewAlbum(title: string): void {
		this._discography$.setValue([...this._discography$.getValue(), title]);
	}
}

class Fan {
	public rejoiceBlissfully = (): void => {
		console.log('YOSH!');
	}
}

const artist = new Artist(['The Goliath', 'The Joyless Parson']);
const fan = new Fan();

artist.discography$.subscribe(fan.rejoiceBlissfully);

artist.releaseNewAlbum('Another cool album title');

// Console output
// > YOSH!

React

This time we are developing a mecha part selling marketplace. We decided to decouple business logic from the UI and started with a view model

// part.ts
export const enum PartType {
	Weapon = 'weapon',
	BodyPart = 'body part',
}

export interface Part {
	manufacturer: string;
	type: PartType;
	name: string;
	price: number;
}
// parts-rack-view-model.ts
import { Observable, Subject } from 'gorgona';

import { Part, PartType } from './part.ts';

export interface IPartsRackViewModel {
	parts$: Observable<Part[]>;
	getParts(): Part[];
	fetchParts(): Promise<void>;
}

export class PartsRackViewModel implements IPartsRackViewModel {
	public parts$: Observable<Part[]>;

	private _parts$: Subject<Part[]>;

	public constructor() {
		this._parts$ = new Subject<Part[]>([]);
		this.parts$ = this._parts$.asObservable();
	}

	public getParts(): Part[] {
		return this._parts$.getValue();
	}

	public async fetchParts(): Promise<void> {
		// Imagine we got this from the server
		this._parts$.setValue([{
			manufacturer: 'Kisaragi',
			type: PartType.BodyPart,
			name: 'KAW-SAMURAI2',
			price: 128_000,
		}]);
	}
}
// parts-rack.tsx
import React from 'react';
import { useObservable } from 'gorgona';

import { IPartsRackViewModel } from './parts-rack-view-model';

interface PartsRackProps {
	model: IPartsRackViewModel;
}

export function PartsRack(props: PartsRackProps): JSX.Element {
	const { model } = props;

	// Now the component will be rerendered
	// every time anyone calls `PartsRackViewModel.fetchParts`
	const parts = useObservable(model.parts$, model.getParts());

	return (
		<div>
			{ parts.map((part) => (
				<div>
					<p>{ part.name }</p>
					<p>{ part.type }</p>
					<p>{ part.price }</p>
					<p>{ part.manufacturer }</p>
				</div>
			))}
		</div>
	);
}
// app.tsx
import React from 'react';

import { PartsRack } from './parts-rack';
import { PartsRackViewModel } from './parts-rack-view-model';

export function App(): JSX.Element {
	const partsRackViewModel = new PartsRackViewModel();

	return (
		<PartsRack model={ partsRackViewModel } />
	);
}

The code above needs to be put in a React project