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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@straits/utils

v1.0.2

Published

Utility library for straits

Downloads

7

Readme

@straits/utils npm (scoped) NpmLicense David Travis (.com) Coveralls github

Utilities to declare and use traits and trait sets.

Installation

npm install --save @straits/utils

Quickstart

const {TraitSet} = require('@straits/utils');

const traits = TraitSet.fromKeys({
	a: {},
	b: {}
});

const sym = traits.a;

{
	// implementing `sym` for all objects
	use traits * from TraitSet;
	sym.*impl( Object.prototype, 42 );
}

{
	// using `sym`
	use traits * from traits;
	console.log( ({}).*a ); // 42
}

API

TraitSet.fromKeys( obj ) => TraitSet

Create and return a new TraitSet, with a new symbol for each property of obj.

TraitSet.fromStrings( names ) => TraitSet

Create and return a new TraitSet, witha symbol for each string in names.

new TraitSet( traitSet={} ) => TraitSet

Create a new TraitSet, borrowing symbols from TraitSet.

traitSet.asFreeFunctions() => { str:fn(), ... }

Return an object with a free function wrapping each symbol in traitSet.

symbol.*impl( target, value ) => symbol

Set target[symbol] to value. Such property symbol is not enumerable nor writable.

const obj = {};
Symbol.iterator.*impl( obj, ()=>{/*...*/} );

symbol.*implDefault( value ) => symbol

Set value as the default value for symbol. Free functions wrapping traits will call value(obj, ...args) if they're called on an obj that doesn't have a symbol property.

symbol.*asFreeFunction() => fn()

Return a free function wrapping symbol.

const fn = Symbol.iterator.*asFreeFunction();

const arr = [];
// the following two statements will be equivalent
fn( arr, 1, 2, 3 );
arr[ Symbol.iterator ]( 1, 2, 3 );

obj.*addSymbol( name, sym ) => sym

Add sym to this with key name: obj[name] = symbol. Throw if sym is not a symbol or if obj already has a property name.

obj.*defineTrait( name ) => symbol

Add a new symbol called name to obj: obj[name] = Symbol(). Throw it obj already has a property called name.

obj.*borrowTraits( traitSet, names=undefined ) => obj

Add to obj all the symbols from traitSet whose property is listed in names. If names is not set, all the symbols from traitSet are imported into obj.

obj.*traitsToFreeFunctions() => obj

Return an object with a free function wrapping each symbol in traitSet.

obj.*implTraits( target, implementationObj ) => obj

implementationObj should be an object whose keys are names of symbols in obj. For each key, value entry of implementationObj, set target[ this[key] ] to value.

obj.*defineAndImplTraits( target, implementationObj ) => obj

Like obj.*implTraits( target, implementationObj ), but it defines the symbols (obj.*defineTrait) before using them.

obj.*defineAndImplMethodsAsTraits( target, source, methodList ) => obj

methodList should be a list of properties in source whose value is a method. Create a new symbol sym in obj for each key m of methodList, and set target[sym] to a function wrapping source.m().

obj.*defineAndImplMemberFreeFunctionsAsTraits( target, functionObj ) => obj

functionObj should be an object whose values are free functions. For each key, fn entry in methodList, create a new symbol sym in obj, and set target[sym] to a function wrapping fn().