@wixc3/common
Advanced tools
Comparing version 3.0.4 to 3.0.5
@@ -14,2 +14,30 @@ /** | ||
export declare function once<T extends (...args: any[]) => any>(fn: T): T; | ||
/** | ||
* Ensures `func` will be called with at least `wait` ms between runs. | ||
* For @example, if `func` is called 3 times in a row: | ||
* `func(1); func(2); func(3);` | ||
* it will wait `wait` ms between each run: | ||
* `func(1); await sleep(wait); func(2); await sleep(wait); func(3);` | ||
* | ||
* This is not throttling (!) since eventually all calls will be ran, | ||
* while in throttling the calls in the "wait" period are skipped. | ||
*/ | ||
export declare function delayed<T extends (...args: any[]) => any>(fn: T, wait: number): (...args: Parameters<T>) => Promise<ReturnType<T>>; | ||
/** | ||
* Ensures that when the async function `fn` is called twice in a row, the | ||
* second call only begins after the first one has finished (successfully or not). | ||
* | ||
* @example | ||
* ``` | ||
* const doWork = enforceSequentialExecution(() => { | ||
* console.log('start'); | ||
* await sleep(1000); | ||
* console.log('end'); | ||
* }); | ||
* void doWork(); | ||
* void doWork(); | ||
* // Result: start, end, start, end | ||
* ``` | ||
*/ | ||
export declare function enforceSequentialExecution<P, T extends (...args: any[]) => Promise<Awaited<P>>>(fn: T): T; | ||
//# sourceMappingURL=functions.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.once = exports.asyncNoop = exports.noop = void 0; | ||
exports.enforceSequentialExecution = exports.delayed = exports.once = exports.asyncNoop = exports.noop = void 0; | ||
const promise_assist_1 = require("promise-assist"); | ||
/** | ||
@@ -31,2 +32,53 @@ * @returns a no operation function | ||
exports.once = once; | ||
/** | ||
* Ensures `func` will be called with at least `wait` ms between runs. | ||
* For @example, if `func` is called 3 times in a row: | ||
* `func(1); func(2); func(3);` | ||
* it will wait `wait` ms between each run: | ||
* `func(1); await sleep(wait); func(2); await sleep(wait); func(3);` | ||
* | ||
* This is not throttling (!) since eventually all calls will be ran, | ||
* while in throttling the calls in the "wait" period are skipped. | ||
*/ | ||
function delayed(fn, wait) { | ||
let queue = null; | ||
return ((...args) => { | ||
if (!queue) { | ||
queue = Promise.resolve(fn(...args)); | ||
} | ||
else { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call | ||
queue = queue.then(() => fn(...args), () => fn(...args)); | ||
} | ||
const tmp = queue; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
queue = tmp.then(() => (0, promise_assist_1.sleep)(wait)); | ||
return tmp; | ||
}); | ||
} | ||
exports.delayed = delayed; | ||
/** | ||
* Ensures that when the async function `fn` is called twice in a row, the | ||
* second call only begins after the first one has finished (successfully or not). | ||
* | ||
* @example | ||
* ``` | ||
* const doWork = enforceSequentialExecution(() => { | ||
* console.log('start'); | ||
* await sleep(1000); | ||
* console.log('end'); | ||
* }); | ||
* void doWork(); | ||
* void doWork(); | ||
* // Result: start, end, start, end | ||
* ``` | ||
*/ | ||
function enforceSequentialExecution(fn) { | ||
let queue = Promise.resolve(null); | ||
return ((...args) => { | ||
queue = queue.then(() => fn(...args), () => fn(...args)); | ||
return queue; | ||
}); | ||
} | ||
exports.enforceSequentialExecution = enforceSequentialExecution; | ||
//# sourceMappingURL=functions.js.map |
@@ -146,6 +146,2 @@ /** | ||
/** | ||
* Generates a string repeating [str] [count] times | ||
*/ | ||
export declare function repeat(str: string, count: number): string; | ||
/** | ||
* Returns a string safe to be used in RegExp | ||
@@ -152,0 +148,0 @@ * @see https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.naiveStripComments = exports.escapeRegExp = exports.repeat = exports.templateCompilerProvider = exports.isString = exports.noWhiteSpace = exports.minimalIndent = exports.noIdents = exports.equalIdents = exports.includesCaseInsensitive = exports.indexToLineAndColumn = exports.toCSSCamelCase = exports.toCSSKebabCase = exports.toNamingConvention = exports.toCamelCase = exports.toPascalCaseJsIdentifier = exports.toPascalCase = exports.toKebabCase = exports.splitIntoWords = exports.capitalizeFirstLetter = exports.isValidNamingConvention = exports.NamingConvention = exports.escapeCSS = exports.assertIsString = void 0; | ||
exports.naiveStripComments = exports.escapeRegExp = exports.templateCompilerProvider = exports.isString = exports.noWhiteSpace = exports.minimalIndent = exports.noIdents = exports.equalIdents = exports.includesCaseInsensitive = exports.indexToLineAndColumn = exports.toCSSCamelCase = exports.toCSSKebabCase = exports.toNamingConvention = exports.toCamelCase = exports.toPascalCaseJsIdentifier = exports.toPascalCase = exports.toKebabCase = exports.splitIntoWords = exports.capitalizeFirstLetter = exports.isValidNamingConvention = exports.NamingConvention = exports.escapeCSS = exports.assertIsString = void 0; | ||
const objects_1 = require("./objects"); | ||
@@ -282,9 +282,2 @@ /** | ||
/** | ||
* Generates a string repeating [str] [count] times | ||
*/ | ||
function repeat(str, count) { | ||
return [...new Array(count)].map(() => str).join(''); | ||
} | ||
exports.repeat = repeat; | ||
/** | ||
* Returns a string safe to be used in RegExp | ||
@@ -291,0 +284,0 @@ * @see https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex |
@@ -14,2 +14,30 @@ /** | ||
export declare function once<T extends (...args: any[]) => any>(fn: T): T; | ||
/** | ||
* Ensures `func` will be called with at least `wait` ms between runs. | ||
* For @example, if `func` is called 3 times in a row: | ||
* `func(1); func(2); func(3);` | ||
* it will wait `wait` ms between each run: | ||
* `func(1); await sleep(wait); func(2); await sleep(wait); func(3);` | ||
* | ||
* This is not throttling (!) since eventually all calls will be ran, | ||
* while in throttling the calls in the "wait" period are skipped. | ||
*/ | ||
export declare function delayed<T extends (...args: any[]) => any>(fn: T, wait: number): (...args: Parameters<T>) => Promise<ReturnType<T>>; | ||
/** | ||
* Ensures that when the async function `fn` is called twice in a row, the | ||
* second call only begins after the first one has finished (successfully or not). | ||
* | ||
* @example | ||
* ``` | ||
* const doWork = enforceSequentialExecution(() => { | ||
* console.log('start'); | ||
* await sleep(1000); | ||
* console.log('end'); | ||
* }); | ||
* void doWork(); | ||
* void doWork(); | ||
* // Result: start, end, start, end | ||
* ``` | ||
*/ | ||
export declare function enforceSequentialExecution<P, T extends (...args: any[]) => Promise<Awaited<P>>>(fn: T): T; | ||
//# sourceMappingURL=functions.d.ts.map |
@@ -0,1 +1,2 @@ | ||
import { sleep } from "promise-assist"; | ||
/** | ||
@@ -25,2 +26,51 @@ * @returns a no operation function | ||
} | ||
/** | ||
* Ensures `func` will be called with at least `wait` ms between runs. | ||
* For @example, if `func` is called 3 times in a row: | ||
* `func(1); func(2); func(3);` | ||
* it will wait `wait` ms between each run: | ||
* `func(1); await sleep(wait); func(2); await sleep(wait); func(3);` | ||
* | ||
* This is not throttling (!) since eventually all calls will be ran, | ||
* while in throttling the calls in the "wait" period are skipped. | ||
*/ | ||
export function delayed(fn, wait) { | ||
let queue = null; | ||
return ((...args) => { | ||
if (!queue) { | ||
queue = Promise.resolve(fn(...args)); | ||
} | ||
else { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call | ||
queue = queue.then(() => fn(...args), () => fn(...args)); | ||
} | ||
const tmp = queue; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
queue = tmp.then(() => sleep(wait)); | ||
return tmp; | ||
}); | ||
} | ||
/** | ||
* Ensures that when the async function `fn` is called twice in a row, the | ||
* second call only begins after the first one has finished (successfully or not). | ||
* | ||
* @example | ||
* ``` | ||
* const doWork = enforceSequentialExecution(() => { | ||
* console.log('start'); | ||
* await sleep(1000); | ||
* console.log('end'); | ||
* }); | ||
* void doWork(); | ||
* void doWork(); | ||
* // Result: start, end, start, end | ||
* ``` | ||
*/ | ||
export function enforceSequentialExecution(fn) { | ||
let queue = Promise.resolve(null); | ||
return ((...args) => { | ||
queue = queue.then(() => fn(...args), () => fn(...args)); | ||
return queue; | ||
}); | ||
} | ||
//# sourceMappingURL=functions.js.map |
@@ -146,6 +146,2 @@ /** | ||
/** | ||
* Generates a string repeating [str] [count] times | ||
*/ | ||
export declare function repeat(str: string, count: number): string; | ||
/** | ||
* Returns a string safe to be used in RegExp | ||
@@ -152,0 +148,0 @@ * @see https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex |
@@ -259,8 +259,2 @@ import { getIn } from './objects'; | ||
/** | ||
* Generates a string repeating [str] [count] times | ||
*/ | ||
export function repeat(str, count) { | ||
return [...new Array(count)].map(() => str).join(''); | ||
} | ||
/** | ||
* Returns a string safe to be used in RegExp | ||
@@ -267,0 +261,0 @@ * @see https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex |
{ | ||
"name": "@wixc3/common", | ||
"version": "3.0.4", | ||
"version": "3.0.5", | ||
"description": "Common utils, usable in all environments", | ||
@@ -22,4 +22,5 @@ "main": "dist/cjs/index.js", | ||
"@file-services/path": "^7.0.1", | ||
"@file-services/types": "^7.0.1" | ||
"@file-services/types": "^7.0.1", | ||
"promise-assist": "^1.3.0" | ||
} | ||
} |
@@ -0,1 +1,3 @@ | ||
import { sleep } from "promise-assist"; | ||
/** | ||
@@ -26,1 +28,57 @@ * @returns a no operation function | ||
} | ||
/** | ||
* Ensures `func` will be called with at least `wait` ms between runs. | ||
* For @example, if `func` is called 3 times in a row: | ||
* `func(1); func(2); func(3);` | ||
* it will wait `wait` ms between each run: | ||
* `func(1); await sleep(wait); func(2); await sleep(wait); func(3);` | ||
* | ||
* This is not throttling (!) since eventually all calls will be ran, | ||
* while in throttling the calls in the "wait" period are skipped. | ||
*/ | ||
export function delayed<T extends (...args: any[]) => any>(fn: T, wait: number): (...args: Parameters<T>) => Promise<ReturnType<T>> { | ||
let queue:Promise<ReturnType<T>|void>|null = null; | ||
return ((...args: Parameters<T>) => { | ||
if (!queue) { | ||
queue = Promise.resolve(fn(...args)) | ||
} else { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call | ||
queue = queue.then( | ||
() => fn(...args) as ReturnType<T>, | ||
() => fn(...args) as ReturnType<T> | ||
); | ||
} | ||
const tmp = queue; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
queue = tmp.then(()=>sleep(wait)) | ||
return tmp as Promise<ReturnType<T>>; | ||
}) as T; | ||
} | ||
/** | ||
* Ensures that when the async function `fn` is called twice in a row, the | ||
* second call only begins after the first one has finished (successfully or not). | ||
* | ||
* @example | ||
* ``` | ||
* const doWork = enforceSequentialExecution(() => { | ||
* console.log('start'); | ||
* await sleep(1000); | ||
* console.log('end'); | ||
* }); | ||
* void doWork(); | ||
* void doWork(); | ||
* // Result: start, end, start, end | ||
* ``` | ||
*/ | ||
export function enforceSequentialExecution<P, T extends (...args: any[]) => Promise<Awaited<P>>>(fn: T): T { | ||
let queue = Promise.resolve(null as P); | ||
return ((...args: Parameters<T>) => { | ||
queue = queue.then( | ||
() => fn(...args), | ||
() => fn(...args) | ||
); | ||
return queue; | ||
}) as T; | ||
} |
@@ -290,9 +290,2 @@ import { getIn } from './objects'; | ||
/** | ||
* Generates a string repeating [str] [count] times | ||
*/ | ||
export function repeat(str: string, count: number) { | ||
return [...new Array<void>(count)].map(() => str).join(''); | ||
} | ||
/** | ||
* Returns a string safe to be used in RegExp | ||
@@ -299,0 +292,0 @@ * @see https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex |
import chai, { expect } from 'chai'; | ||
import { once } from '..'; | ||
import { stub } from 'sinon'; | ||
import { delayed, enforceSequentialExecution, once } from '..'; | ||
import Sinon, { stub } from 'sinon'; | ||
import sinonChai from 'sinon-chai'; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument | ||
import { sleep } from 'promise-assist'; | ||
chai.use(sinonChai); | ||
@@ -20,1 +19,69 @@ | ||
}); | ||
describe('enforceSequentialExecution', () => { | ||
let clock: Sinon.SinonFakeTimers; | ||
beforeEach(() => { | ||
clock = Sinon.useFakeTimers(); | ||
}); | ||
afterEach(() => clock.restore()); | ||
it('executes calls AFTER the previous call was fulfilled', async () => { | ||
const results: number[] = []; | ||
const fn = enforceSequentialExecution(async (delay: number) => { | ||
results.push(delay); | ||
await sleep(delay); | ||
results.push(delay); | ||
return delay; | ||
}); | ||
void fn(101); | ||
void fn(102); | ||
await clock.tickAsync(1); | ||
expect(results).to.eql([101]); | ||
await clock.tickAsync(101); | ||
expect(results).to.eql([101, 101, 102]); | ||
await clock.tickAsync(102); | ||
expect(results).to.eql([101, 101, 102, 102]); | ||
}); | ||
it('resolves the returned promise with the returned value', async () => { | ||
const fn = enforceSequentialExecution(async (delay: number) => { | ||
await sleep(delay); | ||
return delay; | ||
}); | ||
const r1 = fn(1); | ||
const r2 = fn(2); | ||
await clock.tickAsync(10); | ||
expect(await r1).to.equal(1); | ||
expect(await r2).to.equal(2); | ||
}); | ||
}); | ||
describe('delayed', () => { | ||
let clock: Sinon.SinonFakeTimers; | ||
beforeEach(() => { | ||
clock = Sinon.useFakeTimers(); | ||
}); | ||
afterEach(() => clock.restore()); | ||
it('waits before executing subsequent calls', async () => { | ||
const results: number[] = []; | ||
const fn = delayed((id: number) => { | ||
results.push(id); | ||
}, 100); | ||
void fn(0); | ||
void fn(1); | ||
void fn(2); | ||
expect(results).to.eql([0]); | ||
await clock.tickAsync(10); | ||
expect(results).to.eql([0]); | ||
await clock.tickAsync(100); | ||
expect(results).to.eql([0, 1]); | ||
await clock.tickAsync(100); | ||
expect(results).to.eql([0, 1, 2]); | ||
}); | ||
it('resolves the returned promise with the returned value', async () => { | ||
const fn = delayed((id: number) => id, 100) | ||
const r1 = fn(1) | ||
const r2 = fn(2) | ||
await clock.tickAsync(100) | ||
expect(await r1).to.equal(1) | ||
expect(await r2).to.equal(2) | ||
}); | ||
}); |
@@ -65,3 +65,3 @@ import { expect } from 'chai'; | ||
describe('unique', () => { | ||
it('creates an array with no repeats', () => { | ||
it('creates an iterable with no repeats', () => { | ||
expect([...unique(['1', 1, 1, true])]).to.eql(['1', 1, true]); | ||
@@ -68,0 +68,0 @@ expect([...unique([0, 1, 2, 3], (i) => i % 2)]).to.eql([0, 1]); |
@@ -1,2 +0,2 @@ | ||
import { noWhiteSpace, repeat, splitIntoWords, naiveStripComments, toCamelCase, toKebabCase, toPascalCase } from '..'; | ||
import { noWhiteSpace, splitIntoWords, naiveStripComments, toCamelCase, toKebabCase, toPascalCase } from '..'; | ||
import { expect } from 'chai'; | ||
@@ -38,6 +38,2 @@ | ||
it('repeat', () => { | ||
expect(repeat('[]', 3)).to.eql('[][][]'); | ||
}); | ||
it('noWhiteSpace', () => { | ||
@@ -44,0 +40,0 @@ expect(noWhiteSpace('no whitespace')).to.equal('no whitespace'); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
325444
5853
3
+ Addedpromise-assist@^1.3.0
+ Addedpromise-assist@1.3.0(transitive)