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

@sullux/fp-light-type

v0.0.4

Published

A lightweight functional library for functional composition and object composition.

Downloads

11

Readme

home

fp-light-type

npm i @sullux/fp-light-type source test

The type function supplements the scattered and inconsistent type-related functionality in Javascript. This includes supplying proper factory functions for undefined and null, the only values in Javascript that are missing a native factory. This also includes a utility to define new types in a consistent way.

allProperties

allProperties(object: any): { [name: string | Symbol]: Descriptor }

Enumerates the properties of the given object and every prototype in the prototype chain of the given object, returning a map of property names/symbols to descriptors. See the Node.js reference for Object.defineProperty for details about the descriptors.

Note that the result includes non-enumerable properties. The following example shows the REPL output of the function.

allProperties(Error('reasons'))
/*
{ stack:
   { value: 'Error: reasons\n    at repl:1:15\n    at ContextifyScript.Script.runInThisContext (vm.js:50:33)\n    at REPLServer.defaultEval (repl.js:240:29)\n    at bound (domain.js:301:14)\n    at REPLServer.runBound [as eval] (domain.js:314:12)\n    at REPLServer.onLine (repl.js:468:10)\n    at emitOne (events.js:121:20)\n    at REPLServer.emit (events.js:211:7)\n    at REPLServer.Interface._onLine (readline.js:280:10)\n    at REPLServer.Interface._line (readline.js:629:8)',
     writable: true,
     enumerable: false,
     configurable: true },
  message:
   { value: '',
     writable: true,
     enumerable: false,
     configurable: true },
  constructor:
   { value: [Function: Object],
     writable: true,
     enumerable: false,
     configurable: true },
  name:
   { value: 'Error',
     writable: true,
     enumerable: false,
     configurable: true },
  toString:
   { value: [Function: toString],
     writable: true,
     enumerable: false,
     configurable: true },
  __defineGetter__:
   { value: [Function: __defineGetter__],
     writable: true,
     enumerable: false,
     configurable: true },
  __defineSetter__:
   { value: [Function: __defineSetter__],
     writable: true,
     enumerable: false,
     configurable: true },
  hasOwnProperty:
   { value: [Function: hasOwnProperty],
     writable: true,
     enumerable: false,
     configurable: true },
  __lookupGetter__:
   { value: [Function: __lookupGetter__],
     writable: true,
     enumerable: false,
     configurable: true },
  __lookupSetter__:
   { value: [Function: __lookupSetter__],
     writable: true,
     enumerable: false,
     configurable: true },
  isPrototypeOf:
   { value: [Function: isPrototypeOf],
     writable: true,
     enumerable: false,
     configurable: true },
  propertyIsEnumerable:
   { value: [Function: propertyIsEnumerable],
     writable: true,
     enumerable: false,
     configurable: true },
  valueOf:
   { value: [Function: valueOf],
     writable: true,
     enumerable: false,
     configurable: true },
  __proto__:
   { get: [Function: get __proto__],
     set: [Function: set __proto__],
     enumerable: false,
     configurable: true },
  toLocaleString:
   { value: [Function: toLocaleString],
     writable: true,
     enumerable: false,
     configurable: true } }
*/

bindAll

bindAll<T>(object: T): T

Iterates all properties on the given object and the object's prototype chain and binds all functions to the given object. This solves a wide range of bugs that occur when an instance function is called out of context. The following test demonstrates the solution.

const { strictEqual, throws } = require('assert')

const { bindAll } = require('@sullux/fp-light-type')

class Foo {
  constructor() {
    this.x = 42
  }
  xString() {
    return this.x.toString()
  }
}

describe('bindAll', () => {
  it('should throw without binding', () => {
    const unbound = new Foo()
    throws(unbound.xString)
  })
  it('should work properly with binding', () => {
    const bound = bindAll(new Foo())
    strictEqual(bound.xString(), '42')
  })
})

define

define(name: string, options: ?{ extend: ?Function, construct: ?(...args: mixed[]) => Object, enumerable: ?{ [name: String | Symbol]: mixed }, hidden: ?{ [name: String | Symbol]: mixed }, properties: ?{ [name: String | Symbol]: Descriptor }, describe, }): Function

At the most basic level, the define utiliy defines a function that will behave the same whether called as a factory or as a constructor.

const Foo = define('Foo')
const foo1 = Foo()
const foo2 = new Foo()

is equivalent to

function Foo () {
  return new.target
    ? this
    : Object.setPrototypeOf({}, Foo.prototype)
const foo1 = bindAll(Foo())
const foo2 = bindAll(new Foo())
}

While this removes much of the underlying complexity of constructors and factories, defining a type would not be useful without the various options.

extend

Sets the parent constructor of the given type. The following example demonstrates defining a custom error.

const FooError = define('FooError', { extend: Error })
const error = FooError()
error instanceof FooError // true
error instanceof Error // true

construct

Allows a custom-constructed base object for a new instance of the type. The construct function's this is the new instance and the return value of the construct function will be also be composed onto the new instance.

const FooError = define('FooError', {
  extend: Error,
  construct(message) {
    this.id = 'Foo123'
    return Error(message)
  },
})
const error = new FooError('reasons')
error.id // Foo123
error.message // reasons
error.stack
/*
Error: reasons
    at FooError.construct (repl:1:76)
    ...etc.
*/

enumerable

Defines enumerable properties to be added to the defined prototype. Defining a property as enumerable is similar to making it public in the sense that it is discoverable by looping structures and functions that iterate enumerable properties such as Object.keys.

Note that the following is the same example as for construct except that instead of modifying each instance during construction, the id property is now an enumerable property of the prototype.

const FooError = define('FooError', {
  extend: Error,
  construct: Error,
  enumerable: { id: 'Foo123' },
})
const error = new FooError('reasons')
error.id // Foo123
error.message // reasons
error.stack
/*
Error: reasons
    at FooError.construct (repl:1:76)
    ...etc.
*/

hidden

Defines hidden (non-enumerable) properties on the defined prototype. Note that a hidden property is not private in the traditional sense because it can still be accessed externally. It is only hidden from discovery by looping structures and functions that iterate enumerable properties.

const Foo = define('Foo', { hidden: { secret: 42 } })
const foo = new Foo()
Object.keys(foo).includes('secret') // false
foo.secret // 42

properties

Defines property descriptors for the defined prototype. This allows the definition of properties with getters and setters, non-configurable properties, etc.

const Foo = define('Foo', {
  properties: {
    answer: { get() { return 42 } },
  },
})
const foo = new Foo()
Object.keys(foo).includes('answer') // false
foo.answer = 1
foo.answer // 42

describe

The describe function is a special helper that is called by the Node.js utility function util.inspect() to generate a string representation of an object. This is called by the REPL to provide console output.

const Foo = define('Foo', { describe: () => 'instance of Foo' })
const Bar = define('Bar')
console.log(new Foo())
// instance of Foo
console.log(new Bar())
// [Object Bar]

factoryOf

factoryOf(value: any): Function

Given a value, returns the factory of the value.

Example:

const { strictEqual } = require('assert')
const { factoryOf } = require('@sullux/fp-light-type')

strictEqual(factoryOf(true), Boolean)

Null

Null(): null

Provided as the missing factory/constructor for null.

Example:

const { strictEqual } = require('assert')
const { Null, factoryOf } = require('@sullux/fp-light-type')

strictEqual(Null(), null)
strictEqual(factoryOf(null), Null)

type

type(value: any): { jstype: string, name: string, factory: Function, inheritance: Array<string> }

Returns a map of information about the type of the given value.

  • jstype: the native type as reported by typeof value.
  • name: the name of the factory function for this type.
  • factory: the factory function for this type.
  • inheritance: an array of all factory functions within the prototype chain from the factory of the given value through the final factory Object.

Example:

const { type } = require('@sullux/fp-light-type')

console.log(type(true))
/*
{ jstype: 'boolean',
  name: 'Boolean',
  factory: [Function: Boolean],
  inheritance: [ [Function: Boolean], [Function: Object] ] }
*/

typeEquals

typeEquals(first: any, second: any): boolean

Given two values, returns true if the values share the same factory function.

Example:

const { ok } = require('assert')
const { typeEquals } = require('@sullux/fp-light-type')

ok(typeEquals(false, true))
ok(typeEquals(null, null))
ok(!typeEquals(null, undefined))

Undefined

Undefined(): undefined

Provided as the missing factory/constructor for undefined.

Example:

const { strictEqual } = require('assert')
const { Undefined, factoryOf } = require('@sullux/fp-light-type')

strictEqual(Undefined(), undefined)
strictEqual(factoryOf(undefined), Undefined)