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

create-factory-function

v2.0.0

Published

Syntactically concise, curry-friendly convenience method for factory function creation. Given a properties array and a prototype object, returns a factory function that returns objects with the specified prototype and properties.

Downloads

12

Readme

🏭 create-factory-function

Syntactically concise, curry-friendly convenience method for factory function creation.

Usage

Install locally with npm:

npm i create-factory-function

Import:

const factory = require('create-factory-function');

or

import factory from 'create-factory-function';

API

factory.create

Syntax

factory.create([proto[, keys[, props]]]);

Parameters

proto

Optional. Object specifying the prototype of objects created by the returned factory.

Defaults to Object.prototype if no argument is provided.

keys

Optional. Array of zero or more strings or symbols specifying the keys of properties to be assigned to objects created by the returned factory (e.g., 'key'). Used for keys without predefined values.

props

Optional. Object, the enumerable properties of which specify properties to be assigned to objects returned by the returned factory. Used for methods and keys with predefined values.

Examples

Passing a proto:

const factory = require('create-factory-function');

const proto = {
  greetWorld() {
    return 'hello, world!';
  },
};

const factoryFunction = factory.create(proto);

const obj = factoryFunction(); // {}

Object.getPrototypeOf(obj); // { greetWorld: [Function: greetWorld] }

obj.greetWorld(); // hello, world!

Passing keys with no predefined value:

const factoryFunction = factory.create(proto, ['key1', 'key2']);

const obj = factoryFunction('val1', 'val2'); // { key1: 'val1', key2: 'val2' }

Passing properties:

const factoryFunction = factory.create(proto, ['key1'], {
  key2: 'val2',
  method: () => "I'm a method!",
}
);

const obj = factoryFunction('val1'); // { key1: 'val1', key2: 'val2', method: [Function: method] }

obj.method(); // I'm a method!

Passing no arguments:

const factoryFunction = factory.create();

const obj = factoryFunction(); // {}

Object.getPrototypeOf(obj); // [Object: null prototype] {}

Purpose

ES6 introduced concise object literal syntax and implicit function returns, which combine to permit highly concise factory function creation:

const factoryFunction = (key1, key2) => ({ key1, key2 });

This style of object creation's reliance on object literals means that prototype assignment is not possible during object creation. Since prototype assigment post-creation is a performance sink, this makes prototype assignment difficult.

One option is to use Object.create, but to assign properties to the returned object either one must use verbose property descriptors:

const factoryFunction = (key1, key2) => Object.create(someProto, {
  key1: {
    value: 'val1',
    enumerable: true,
    writable: true,
  },
  key2: {
    value: 'val2',
    enumerable: true,
    writable: true,
  },
});

Or explicitly assign parameter values to argument values:

const factoryFunction = (key1, key2) => {
  const obj = Object.create(someProto);
  obj.key1 = key1;
  obj.key2 = key2;
  return obj;
};

Both options remove the concision ES6 permits.

This package provides a syntactically concise method for creating factories that assign prototypes and properties during object creation.

Currying

To keep the package minimal and comply with the single-use principle, currying is not implemented in factory.create. But the create method is structured so as to be friendly to currying. Currying factory.create allows for partial application of the prototype parameter:

const curry = require('curry-function');
const factory = require('create-factory-function');

const animalProto = {
  makeNoise() {
    return this.noise;
  },
};

const animal = curry(factory.create)(animalProto);

const lion = animal(['name', { noise: 'Roar!' }]);
const eagle = animal(['name', { noise: 'Caw!' }]);

const leanne = lion('leanne'); // { name: 'leanne', noise: 'Roar!' }
const ernie = eagle('ernie'); // { name: 'ernie', noise: 'Caw!' }

leanne.makeNoise(); // Roar!
ernie.makeNoise(); // Caw!

Flipping the parameter order is possible, allowing for partial application of the keys/props parameter:

const curry = require('curry-function');
const factory = require('create-factory-function');

const lionProto = {
  type: 'lion',
  makeNoise() {
    return 'Roar!';
  },
};

const eagleProto = {
  type: 'eagle',
  makeNoise() {
    return 'Caw!';
  },
};

const flip = (f) => (a, b, c) => f(b, c, a);

const getType = function getType() {
    return this.type;
}

const animal = curry(flip(factory.create))(['name'], { getType });

const lion = animal(lionProto);
const eagle = animal(eagleProto);

const leanne = lion('leanne'); // { name: 'leanne'}
const ernie = eagle('ernie'); // { name: 'ernie'}

leanne.makeNoise(); // Roar!
leanne.getType(); // lion

ernie.makeNoise(); // Caw!
ernie.getType(); // eagle

Test

Tested with AVA.

npm test

or

npx ava