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

repeat-args

v0.1.3

Published

Yet another take at repeating sequences (string, array, array-like, buffer), also in browsers (UMD).

Downloads

9

Readme

repeat-args

Yet another take at repeating sequences (string, array, array-like, buffer), also in browsers (UMD).

API

It's all about repeaters.

  • They're functions that can remember and take parameters.
  • The essential parameters are a source sequence and a target quantity length.
  • Repeaters can't learn, they can only evolve: When you give a parameter to a repeater, it will always produce something new, based on the new parameter and the ones it remembers.
    • When you provide the last missing essential parameter, by default you get a sequence with length items from source, repeated in original order if necessary. You can modify this default behavior by configuring the addFunc parameter – see below.
    • When an essential parameter remains unknown, you get a new repeater that remembers your new parameter and all the ones that its producer knew.

This module exports a repeater that knows none of the essential parameters, so you have something to start with:

var r = require('repeat-args'), x = '.o°';

All repeaters have this interface:

r(…stuff)

With less than one argument, use an empty string as the source parameter. (Chosen because it is a sequence of length 0, and also a false-y value.)

equal(r().times(2),     '');
equal(r().times(0),     '');
equal(r().len(2),       '');
equal(r().len(0),       '');

With at least one argument, of which the first one is recognized as a sequece: Merge all arguments into a sequence of the same type as the first argument, and use that combined sequence as the source parameter.

equal(r.times(3)(x),           '.o°.o°.o°');
equal(r.times(3)([x]),        ['.o°', '.o°', '.o°']);
equal(r.times(3)([ [x] ]),  [ ['.o°'], ['.o°'], ['.o°'] ]);
equal(r('h', 'i', 5, 7).times(0),   '');
equal(r('h', 'i', 5, 7).times(2),   'hi57hi57');
equal(r(['h', 'i', 5, 7]).times(2),
        ['h', 'i', 5, 7, 'h', 'i', 5, 7]);
equal(r([ ['h', 'i', 5, 7] ]).times(2),
        [ ['h', 'i', 5, 7], ['h', 'i', 5, 7] ]);

If none of the above was applicable, behave as r.arar(…stuff) would.

equal(r(6, 9, 'a', 'b').times(2),
      [ 6, 9, 'a', 'b', 6, 9, 'a', 'b' ]);
// same as:
equal(r([], 6, 9, 'a', 'b').times(2),
          [ 6, 9, 'a', 'b', 6, 9, 'a', 'b' ]);
// to force a string instead:
equal(r('', 6, 9, 'a', 'b').times(2),   '69ab69ab');

r.len(q)

Use q as the length parameter.

r.times(n), r.n(n)

Use "n times the length of source" as the length parameter. The formula will be calculated as soon as the source parameter is known, which might be immediately.

r.arar(…stuff)

Put all (0 or more) arguments into an array (arar = "ARguments ARray") and use that as the source parameter.

equal(r.times(2).arar(),          []);
equal(r.times(2).arar(42),        [42, 42]);
equal(r.times(2).arar(3.14, 15),  [3.14, 15, 3.14, 15]);

r.seq(string | buffer | array | list)

Use the first argument as the source parameter. The list means anything that Array.prototype.slice can make an array from.

x = ifSupported(function () { return Buffer.from('.o°'); });
if (x) {
  equal(x.length, 4);     // in UTF-8, '°' costs 2 bytes.
  equal(r.times(3)(x),    Buffer.from('.o°.o°.o°'));
  equal(12,               Buffer.from('.o°.o°.o°').length);
  equal(r.len(9)(x),      Buffer.from('.o°.o°.'));  // 7 chars in 9 bytes
}

r.str(x)

Shorthand for r.seq(String(x)).

equal(r.times(3).str(),           'undefinedundefinedundefined');
equal(r.times(3).str(42),         '424242');
equal(r.times(3).str(3.14, 15),   '3.143.143.14');

r.func(add)

Use add as the addFunc parameter. The addFunc should be a function. It will be invoked with two arguments accum and maxN. The accum (accumulator) is a sequence in which elements are collected. When it is long enough, that will be the repeater's result.

The maxN argument is a number that tells addFunc up to how many new elements it shall produce in this invocation. The addFunc may safely ignore maxN in cases where it produces at most one element. (It's the repeater's job to make sure to either not request less than one element, or to discard the excess ones.)

If addFunc has produced exaclty one element and it is of another type than the accumulator, that element may be returned as-is. In all other cases (same type, multiple elements, no elements), the addFunc should return a sequence of the same type as the accumulator.

Returning an empty sequence indicates that no more values can be produced, even in future attempts. The repeater then enters futile mode. The addFunc must not make any assumptions about how often the repeater in futile mode will invoke it to request more elements. (At time of writing, it stops immediately.) A repeater may optionally leave futile mode if any new elements are produced. (Not really relevant since the addFunc won't know about that.)

function fiboArg(accum) {
  var n = accum.length;
  return (accum[n - 1] + accum[n - 2]);
}
equal(r.func(fiboArg).times(4)(1, 1),     [ 1, 1, 2, 3, 5, 8, 13, 21 ]);
equal(r.func(fiboArg).len(8)(1, 1),       [ 1, 1, 2, 3, 5, 8, 13, 21 ]);
equal(r.func(fiboArg).len(8)('AB', 'rs'), 'ABrssrrs');
equal(r.func(fiboArg).len(6)(['AB', 'rs']),
  [ 'AB', 'rs', 'rsAB', 'rsABrs', 'rsABrsrsAB', 'rsABrsrsABrsABrs' ]);

r.mthd(add)

Like r.func but the addFunc is invoked with just the maxN argument, and its invocation context (this) will be set to the accumulator.

function fiboMtd() {  // no named arguments since we ignore maxN
  var accum = this, n = accum.length;
  return (accum[n - 1] + accum[n - 2]);
}
equal(r.mthd(fiboMtd).times(4)(1, 1),     [ 1, 1, 2, 3, 5, 8, 13, 21 ]);
equal(r.mthd(fiboMtd).len(8)(1, 1),       [ 1, 1, 2, 3, 5, 8, 13, 21 ]);
equal(r.mthd(fiboMtd).len(8)('AB', 'rs'), 'ABrssrrs');
equal(r.mthd(fiboMtd).len(6)(['AB', 'rs']),
  [ 'AB', 'rs', 'rsAB', 'rsABrs', 'rsABrsrsAB', 'rsABrsrsABrsABrs' ]);

Known issues

  • It can't work async. Try the times function from the async module. or promises.
  • Needs more/better tests and docs.

License

ISC