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 🙏

© 2026 – Pkg Stats / Ryan Hefner

turboprop

v0.0.3

Published

Metho-like library to allow use of arrays as property accessors

Downloads

13

Readme

Turboprop

Turboprop provides functionality to modify JavaScript arrays so that they can be used as property accessors (both for getting, and setting values). It also lets you define the methods by which the target object's properties are get and set using the accessor array.

That probably seems a lot like gibberish, so the best way to explain is with some sample code:

// Retrieve multiple values from an array
const arr = ['a', 'b', 'c', 'd', 'e']
console.log(arr[[0, 2, 4]])   // ["a", "c", "e"]

// Nested retrieval
console.log(arr[[0, 2, [3,4]]])   // ["a", "c", ["d", "e"]]

// Setting multiple values in an array
arr[[1, 3, 5]] = ['r', 'h', 's']
console.log(arr)   // ["a", "r", "c", "h", "e", "s"]

// combine getting and setting array values
arr[[0,1]] = arr[[2,0]]
console.log(arr)   // ["c", "a", "c", "h", "e", "s"]


// Retrieve multiple object properties
const obj = {a: 5, b: 6, c: 7, d: 8, e: 9}
console.log(obj[['b', 'c', 'e']])   // [6, 7, 9]

// Set multiple object properties
obj[['a', 'e']] = [33, 66]
console.log(obj)   // { a: 33, b: 6, c: 7, d: 8, e: 66 }


// Retrieve multiple characters from a string
const str = "Hello world!"
console.log(str[[0, 4, 7, 10, 11]])   // 'Hood!'
console.log(str[0[to(3)], 6[to(10)]])   // 'Hell world' (using 'to' from metho-number)

// Strings are immutable - hence no setting

// More useful(?) examples
const addr = "123 High Street, My Town, My State"
const address = {}
address[['line1', 'line2', 'line3']] = addr.split(',').map(s=>s.trim())
console.log(address)   // { line1: "123 High Street", line2: "My Town", line3: "My State" }

const obj1 = {type: 'box', col1: 'red', col2: 'blue', col3: 'green'}
const obj2 = {}
obj2[['item', 'colours']] = obj1[['type', ['col1', 'col2', 'col3']]
console.log(obj2)   // {item: 'box', colours:['red', 'blue', 'green']}

If you would like the above standard behaviours to be added to Array.prototype - giving ANY array gaining the ability to behave like this with other arrays, objects, and strings - simply call initialiseGlobally().

Why was this built?

Basically I just wanted to see if it was possible to do it. Ever since I wrote Metho, I've been churning ideas in my head about what other possibilities would be opened up with similar JS syntax hacking. Turboprop is the first useful(?) thing to come out of the ensuing experiments.

How it Works

Turboprop works by modifying the type coercion behaviour of an array so that when JS attempts to convert it to a string for the purpose of using it as a property accessor, the following things happen:

  • Temporary properties (named with a Symbol to avoid name clashes) are set up on predefined 'target' objects - from which the properties of the target will be accessed
  • 'Getter' and 'Setter' methods are defined for these temporary properties. These methods are responsible for retrieving and setting values on the target objects, using the original accessor array in whatever way they choose. After their job is done, they delete the temporary property to avoid clutter
  • Instead of returning a string from the coercion, the Symbol that names the temporary property is returned - which causes the relevant 'getter' or 'setter' method to be triggered on the target, carrying out the property retrieval or assignment as appropriate

Usage

Turboprop defines a few basic functions for its operation:

initialiseGlobally([state], [targetOrTargets])

This is just a convenience function to quickly modify Array.prototype so that all arrays can be used as property accessors for the default targets (see below for an explanation of 'targets'). It takes 2 optional parameters:

  • state - Defaults to true - specifies whether you want to switch functionality on or off
  • targetOrTargets - Specifies a target, or array of targets that may have their properties accessed by arrays. If not specified, this will default to the default Turboprop targets

Important note - because initialiseGlobally modifies the prototype of all arrays, it is possible (although unlikely) that conflicts with other libraries that do similar can occur. Despite this modification, the standard behaviour or arrays has been preserved as far as possible.

initialise([array], [targetOrTargets])

Turns the passed array into a 'Turboprop' array that can be used as a property accessor for the targets provided (see below for an explanation of 'targets'). It takes 2 optional parameters:

  • array - The array to convert. Will default to creating an empty array
  • targetOrTargets - Specifies a target, or array of targets that may have their properties accessed by the array. If not specified, this will default to the default Turboprop targets

The function modifies the passed array, and returns that same array.

isInitialisedArray(array)

Checks if the passed array is already initialised as a 'Turboprop' array. Returns a boolean.console.log(object[property])

Targets and Default Targets

A 'target' in Turboprop is an object that defines the object to be targeted, and the functions that define how 'getting' and 'setting' of properties using an accessor array will work:

const target = {
  object: objectToTarget,
  methods: {
    // logic to 'get' and return properties from targetObject
    getter: (propNamesAr, targetObject) => returnVal,
    // logic to 'set' properties on targetObject (any return value is discarded)
    setter: (propNamesArr, valuesToSet, targetObject) => {}
  }
}

The default targets are [ TARGET_STRING, TARGET_ARRAY, TARGET_OBJECT ] - designed to provide common, hopefully useful functionality. The constants defining each of the defaults are also exported by the library should you wish to use them yourself:

// String target
// Will 'get' a concatenation of chars specified by the indexes defined in the accessor array
const TARGET_STRING = {
  object: String.prototype,
  methods: {
    getter: (indexes, str) => indexes.reduce((newStr, index) => newStr + str[index], ''),
    setter: false
  }
}

// Array target
// Will 'get' an array of values specified by the indexes defined in the accessor array
// Will 'set' the values into the array slots specified by the indexes defined in the accessor array
const TARGET_ARRAY = {
  object: Array.prototype,
  methods: {
    getter: (indexes, arr) => indexes.reduce((newArr, index) => [...newArr, arr[index]], []),
    setter: (indexes, values, arr) => indexes.forEach((index, i) => arr[index] = values[i])
  }
}

// Object target
// Will 'get' an array of values specified by the property names defined in the accessor array
// Will 'set' the object properties specified by the property names defined in the accessor array
const TARGET_OBJECT = {
  object: Object.prototype,
  methods: {
    getter: (keys, obj) => keys.reduce((newArr, key) => [...newArr, obj[key]], []),
    setter: (keys, values, obj) => keys.forEach((key, i) => obj[key] = values[i])
  }
}