Initial commit: New MoreminiMore website with fresh design

This commit is contained in:
MoreminiMore
2026-04-22 01:59:05 +07:00
commit 76409638cc
14010 changed files with 2052041 additions and 0 deletions

9
node_modules/promise-limit/.eslintrc generated vendored Normal file
View File

@@ -0,0 +1,9 @@
{
"extends": [
"standard",
"plugin:es5/no-es2015"
],
"rules": {
"no-console": "error"
}
}

3
node_modules/promise-limit/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,3 @@
language: node_js
node_js:
- stable

97
node_modules/promise-limit/README.md generated vendored Normal file
View File

@@ -0,0 +1,97 @@
promise-limit [![npm version](https://img.shields.io/npm/v/promise-limit.svg)](https://www.npmjs.com/package/promise-limit) [![npm](https://img.shields.io/npm/dm/promise-limit.svg)](https://www.npmjs.com/package/promise-limit) [![Build Status](https://travis-ci.org/featurist/promise-limit.svg?branch=master)](https://travis-ci.org/featurist/promise-limit)
===
Limit outstanding calls to promise returning functions, or a semaphore for promises. You might want to do this to reduce load on external services, or reduce memory usage when processing large batches of jobs.
```sh
npm install promise-limit
```
```js
var promiseLimit = require('promise-limit')
var limit = promiseLimit(2)
var jobs = ['a', 'b', 'c', 'd', 'e']
Promise.all(jobs.map((name) => {
return limit(() => job(name))
})).then(results => {
console.log()
console.log('results:', results)
})
function job (name) {
var text = `job ${name}`
console.log('started', text)
return new Promise(function (resolve) {
setTimeout(() => {
console.log(' ', text, 'finished')
resolve(text)
}, 100)
})
}
```
will output:
```
started job a
started job b
job a finished
job b finished
started job c
started job d
job c finished
job d finished
started job e
job e finished
results: [ 'job a', 'job b', 'job c', 'job d', 'job e' ]
```
API
---
```js
var promiseLimit = require('promise-limit')
promiseLimit(concurrency?: Number) -> limit
```
Returns a function that can be used to wrap promise returning functions, limiting them to `concurrency` outstanding calls.
- `concurrency` the concurrency, i.e. 1 will limit calls to one at a time, effectively in sequence or serial. 2 will allow two at a time, etc. 0 or `undefined` specify no limit, and all calls will be run in parallel.
limit
=====
```js
limit(fn: () -> Promise<T>) -> Promise<T>
```
A function that limits calls to `fn`, based on `concurrency` above. Returns a promise that resolves or rejects the same value or error as `fn`. All functions are executed in the same order in which they were passed to `limit`. `fn` must return a promise.
* `fn` a function that is called with no arguments and returns a promise. You can pass arguments to your function by putting it inside another function, i.e. `() -> myfunc(a, b, c)`.
limit.map
=========
```js
limit.map(items: [T], mapper: (T) -> Promise<R>) -> Promise<[R]>
```
Maps an array of items using `mapper`, but limiting the number of concurrent calls to `mapper` with the `concurrency` of `limit`. If at least one call to `mapper` returns a rejected promise, the result of `map` is a the same rejected promise, and no further calls to `mapper` are made.
limit.queue
===========
```js
limit.queue: Number
```
Returns the queue length, the number of jobs that are waiting to be started. You could use this to throttle incoming jobs, so the queue doesn't overwhealm the available memory - for e.g. `pause()` a stream.
## We're Hiring!
Featurist provides full stack, feature driven development teams. Want to join us? Check out [our career opportunities](https://www.featurist.co.uk/careers/).

22
node_modules/promise-limit/example/example.ts generated vendored Normal file
View File

@@ -0,0 +1,22 @@
import * as promiseLimit from '../'
const limit = promiseLimit<string>(2)
var jobs = ['a', 'b', 'c', 'd', 'e']
Promise.all(jobs.map((name) => {
return limit(() => job(name))
})).then(results => {
console.log('\nresults:', results)
})
function job (name): Promise<string> {
var text = `job ${name}`
console.log('started', text)
return new Promise(function (resolve) {
setTimeout(() => {
console.log(' ', text, 'finished')
resolve(text)
}, 100)
})
}

45
node_modules/promise-limit/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,45 @@
export = limitFactory
declare namespace limitFactory {}
/**
* Returns a function that can be used to wrap promise returning functions,
* limiting them to concurrency outstanding calls.
* @param concurrency the concurrency, i.e. 1 will limit calls to one at a
* time, effectively in sequence or serial. 2 will allow two at a time, etc.
* 0 or undefined specify no limit, and all calls will be run in parallel.
*/
declare function limitFactory<T>(concurrency?: number): limit<T>
declare type limit<T> = limitFunc<T> & limitInterface<T>
declare interface limitInterface<T> {
/**
* Maps an array of items using mapper, but limiting the number of concurrent
* calls to mapper with the concurrency of limit. If at least one call to
* mapper returns a rejected promise, the result of map is a the same rejected
* promise, and no further calls to mapper are made.
* @param items any items
* @param mapper iterator
*/
map<U>(items: ReadonlyArray<T>, mapper: (value: T) => Promise<U>): Promise<U[]>
/**
* Returns the queue length, the number of jobs that are waiting to be started.
* You could use this to throttle incoming jobs, so the queue doesn't
* overwhealm the available memory - for e.g. pause() a stream.
*/
queue: number
}
/**
* A function that limits calls to fn, based on concurrency above. Returns a
* promise that resolves or rejects the same value or error as fn. All functions
* are executed in the same order in which they were passed to limit. fn must
* return a promise.
* @param fn a function that is called with no arguments and returns a promise.
* You can pass arguments to your function by putting it inside another function,
* i.e. `() -> myfunc(a, b, c)`.
*/
declare type limitFunc<T> = (fn: () => Promise<T>) => Promise<T>

88
node_modules/promise-limit/index.js generated vendored Normal file
View File

@@ -0,0 +1,88 @@
function limiter (count) {
var outstanding = 0
var jobs = []
function remove () {
outstanding--
if (outstanding < count) {
dequeue()
}
}
function dequeue () {
var job = jobs.shift()
semaphore.queue = jobs.length
if (job) {
run(job.fn).then(job.resolve).catch(job.reject)
}
}
function queue (fn) {
return new Promise(function (resolve, reject) {
jobs.push({fn: fn, resolve: resolve, reject: reject})
semaphore.queue = jobs.length
})
}
function run (fn) {
outstanding++
try {
return Promise.resolve(fn()).then(function (result) {
remove()
return result
}, function (error) {
remove()
throw error
})
} catch (err) {
remove()
return Promise.reject(err)
}
}
var semaphore = function (fn) {
if (outstanding >= count) {
return queue(fn)
} else {
return run(fn)
}
}
return semaphore
}
function map (items, mapper) {
var failed = false
var limit = this
return Promise.all(items.map(function () {
var args = arguments
return limit(function () {
if (!failed) {
return mapper.apply(undefined, args).catch(function (e) {
failed = true
throw e
})
}
})
}))
}
function addExtras (fn) {
fn.queue = 0
fn.map = map
return fn
}
module.exports = function (count) {
if (count) {
return addExtras(limiter(count))
} else {
return addExtras(function (fn) {
return fn()
})
}
}

39
node_modules/promise-limit/package.json generated vendored Normal file
View File

@@ -0,0 +1,39 @@
{
"name": "promise-limit",
"version": "2.7.0",
"description": "limits calls to functions that return promises",
"main": "index.js",
"dependencies": {},
"devDependencies": {
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"eslint": "*",
"eslint-config-standard": "11.0.0",
"eslint-plugin-es5": "1.3.1",
"eslint-plugin-import": "*",
"eslint-plugin-node": "7.0.1",
"eslint-plugin-promise": "3.8.0",
"eslint-plugin-standard": "3.1.0",
"fs-promise": "2.0.3",
"lowscore": "1.17.0",
"mocha": "*"
},
"scripts": {
"test": "mocha && eslint ."
},
"repository": {
"type": "git",
"url": "git+https://github.com/featurist/promise-limit.git"
},
"keywords": [
"limit",
"promise",
"semaphore"
],
"author": "Tim Macfarlane <timmacfarlane@gmail.com>",
"license": "ISC",
"bugs": {
"url": "https://github.com/featurist/promise-limit/issues"
},
"homepage": "https://github.com/featurist/promise-limit#readme"
}

3
node_modules/promise-limit/test/max.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
module.exports = function (numbers) {
return Math.max.apply(null, numbers)
}

48
node_modules/promise-limit/test/memoryUsageSpec.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
/* eslint-env mocha */
var times = require('lowscore/times')
var limiter = require('..')
var expect = require('chai').expect
var max = require('./max')
describe('promise-limit memory usage', function () {
var memoryProfile
beforeEach(function () {
memoryProfile = []
})
function checkMemory () {
var memory = process.memoryUsage().heapUsed
memoryProfile.push(memory)
}
function load (i) {
checkMemory()
return new Promise(function (resolve, reject) {
setTimeout(resolve, 10)
}).then(function () {
checkMemory()
var array = new Array(1024 * 1024)
return {
i: i,
array: array
}
})
}
it("doesn't use too much memory", function () {
this.timeout(20000)
var limit = limiter(5)
return Promise.all(times(1000, function (i) {
return limit(function () {
return load(i).then(function () {})
})
})).then(function () {
var maxMemoryUsage = max(memoryProfile)
expect(maxMemoryUsage).to.be.lessThan(2000 * 1024 * 1024)
})
})
})

270
node_modules/promise-limit/test/spec.js generated vendored Normal file
View File

@@ -0,0 +1,270 @@
/* eslint-env mocha */
var times = require('lowscore/times')
var range = require('lowscore/range')
var limiter = require('..')
var chai = require('chai')
var expect = chai.expect
chai.use(require('chai-as-promised'))
var max = require('./max')
describe('promise-limit', function () {
var output
beforeEach(function () {
output = []
})
function wait (text, n) {
output.push('starting', text)
return new Promise(function (resolve) {
setTimeout(resolve, n)
}).then(function () {
output.push('finished', text)
return text
})
}
function expectMaxOutstanding (n) {
var outstanding = 0
var outstandingOverTime = output.map(function (line) {
if (line.match(/starting/)) {
outstanding++
} else if (line.match(/finished/)) {
outstanding--
}
return outstanding
})
var maxOutstanding = max(outstandingOverTime)
expect(maxOutstanding).to.equal(n)
}
it('limits the number of outstanding calls to a function', function () {
var limit = limiter(5)
return Promise.all(times(9, function (i) {
return limit(function () {
return wait('job ' + (i + 1), 100)
})
})).then(function () {
expectMaxOutstanding(5)
})
})
it("doesn't limit if the number outstanding is the limit", function () {
var limit = limiter(5)
return Promise.all(times(5, function (i) {
return limit(function () {
return wait('job ' + (i + 1), 100)
})
})).then(function () {
expectMaxOutstanding(5)
})
})
it("doesn't limit if the number outstanding less than the limit", function () {
var limit = limiter(5)
return Promise.all(times(4, function (i) {
return limit(function () {
return wait('job ' + (i + 1), 100)
})
})).then(function () {
expectMaxOutstanding(4)
})
})
it('returns the results from each job', function () {
var limit = limiter(5)
return Promise.all(times(9, function (i) {
return limit(function () {
return wait('job ' + (i + 1), 100)
})
})).then(function (results) {
expect(results).to.eql(times(9, function (i) {
return 'job ' + (i + 1)
}))
})
})
it('returns a rejected promise if the function throws an error', function () {
var limit = limiter(5)
var promise = limit(function () {
throw new Error('uh oh')
})
expect(promise).to.be.a('promise')
return promise.then(function () {
throw new Error('the promise resolved, instead of rejecting')
}).catch(function (err) {
expect(String(err)).to.equal('Error: uh oh')
})
})
it('should fulfil or reject when the function fulfils or rejects', function () {
var limit = limiter(2)
var numbers = [1, 2, 3, 4, 5, 6]
function rejectOdd (n) {
return new Promise(function (resolve, reject) {
if (n % 2 === 0) {
resolve(n + ' is even')
} else {
reject(new Error(n + ' is odd'))
}
})
}
return Promise.all(numbers.map(function (i) {
return limit(function () {
return rejectOdd(i)
}).then(function (r) {
return 'pass: ' + r
}, function (e) {
return 'fail: ' + e.message
})
})).then(function (results) {
expect(results).to.eql([
'fail: 1 is odd',
'pass: 2 is even',
'fail: 3 is odd',
'pass: 4 is even',
'fail: 5 is odd',
'pass: 6 is even'
])
})
})
describe('no limit', function () {
function expectNoLimit (limit) {
return Promise.all(times(9, function (i) {
return limit(function () { return wait('job ' + (i + 1), 100) })
})).then(function () {
expectMaxOutstanding(9)
}).then(function () {
return expectNoMapLimit(limit)
})
}
function expectNoMapLimit (limit) {
return limit.map(range(0, 9), function (i) {
return wait('job ' + (i + 1), 100)
}).then(function () {
expectMaxOutstanding(9)
})
}
it("doesn't limit if the limit is 0", function () {
var limit = limiter(0)
return expectNoLimit(limit)
})
it("doesn't limit if the limit is undefined", function () {
var limit = limiter()
return expectNoLimit(limit)
})
})
describe('map', function () {
function failsAt1 (num) {
if (num === 1) return Promise.reject(new Error('rejecting number ' + num))
else return Promise.resolve('accepting number ' + num)
}
function resolvesAll (num) {
return Promise.resolve('accepting number ' + num)
}
it('returns all results when all are resolved', function () {
var limit = limiter(2)
return limit.map([0, 1, 2, 3], resolvesAll).then(function (results) {
expect(results).to.eql([
'accepting number 0',
'accepting number 1',
'accepting number 2',
'accepting number 3'
])
})
})
it('returns first failure when one fails', function () {
var limit = limiter(2)
return expect(limit.map([0, 1, 2, 3], failsAt1)).to.be.rejectedWith('rejecting number 1')
})
it('limiter can still be used after map with failure', function () {
var limit = limiter(2)
return expect(limit.map([0, 1, 2, 3], failsAt1)).to.be.rejectedWith('rejecting number 1').then(function () {
return limit.map([0, 1, 2, 3], resolvesAll).then(function (results) {
expect(results).to.eql([
'accepting number 0',
'accepting number 1',
'accepting number 2',
'accepting number 3'
])
})
})
})
})
describe('large numbers of tasks failing', function () {
context('when error thrown', function () {
function alwaysFails (n) {
throw new Error('argh: ' + n)
}
it("doesn't exceed stack size", function () {
var limit = limiter(2)
return expect(limit.map(range(0, 1000), alwaysFails)).to.be.rejectedWith('argh: 0')
})
})
context('when error rejected', function () {
function alwaysFails (n) {
return Promise.reject(new Error('argh: ' + n))
}
it("doesn't exceed stack size", function () {
var limit = limiter(2)
return expect(limit.map(range(0, 1000), alwaysFails)).to.be.rejectedWith('argh: 0')
})
})
})
describe('queue length', function () {
it('updates the queue length when there are more jobs than there is concurrency', function () {
var limit = limiter(2)
var one = limit(function () { return wait('one', 10) })
expect(limit.queue).to.equal(0)
var two = limit(function () { return wait('two', 20) })
expect(limit.queue).to.equal(0)
limit(function () { return wait('three', 100) })
expect(limit.queue).to.equal(1)
limit(function () { return wait('four', 100) })
expect(limit.queue).to.equal(2)
return one.then(function () {
expect(limit.queue).to.equal(1)
return two.then(function () {
expect(limit.queue).to.equal(0)
})
})
})
})
})