@strictly/base 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +26 -0
- package/.out/errors/not_implemented.d.ts +3 -0
- package/.out/errors/not_implemented.js +5 -0
- package/.out/errors/unexpected_implementation.d.ts +3 -0
- package/.out/errors/unexpected_implementation.js +5 -0
- package/.out/errors/unreachable.d.ts +3 -0
- package/.out/errors/unreachable.js +6 -0
- package/.out/index.d.ts +20 -0
- package/.out/index.js +20 -0
- package/.out/test/index.d.ts +1 -0
- package/.out/test/index.js +1 -0
- package/.out/test/vitest/expect.d.ts +4 -0
- package/.out/test/vitest/expect.js +13 -0
- package/.out/tsconfig.json +16 -0
- package/.out/tsconfig.tsbuildinfo +1 -0
- package/.out/tsup.config.d.ts +3 -0
- package/.out/tsup.config.js +12 -0
- package/.out/types/element_of_array.d.ts +1 -0
- package/.out/types/element_of_array.js +1 -0
- package/.out/types/extract_generics.d.ts +2 -0
- package/.out/types/extract_generics.js +1 -0
- package/.out/types/is_field_optional.d.ts +1 -0
- package/.out/types/is_field_optional.js +1 -0
- package/.out/types/is_field_readonly.d.ts +8 -0
- package/.out/types/is_field_readonly.js +2 -0
- package/.out/types/maybe.d.ts +3 -0
- package/.out/types/maybe.js +1 -0
- package/.out/types/printable_of.d.ts +1 -0
- package/.out/types/printable_of.js +1 -0
- package/.out/types/required_of_record.d.ts +3 -0
- package/.out/types/required_of_record.js +1 -0
- package/.out/types/specs/element_of_array.tests.d.ts +1 -0
- package/.out/types/specs/element_of_array.tests.js +6 -0
- package/.out/types/specs/is_field_readonly.tests.d.ts +1 -0
- package/.out/types/specs/is_field_readonly.tests.js +9 -0
- package/.out/types/specs/printable_of.tests.d.ts +1 -0
- package/.out/types/specs/printable_of.tests.js +6 -0
- package/.out/types/specs/required_of_record.tests.d.ts +1 -0
- package/.out/types/specs/required_of_record.tests.js +12 -0
- package/.out/types/specs/string_key_of.tests.d.ts +1 -0
- package/.out/types/specs/string_key_of.tests.js +10 -0
- package/.out/types/string_key_of.d.ts +1 -0
- package/.out/types/string_key_of.js +1 -0
- package/.out/util/array.d.ts +1 -0
- package/.out/util/array.js +8 -0
- package/.out/util/cache.d.ts +13 -0
- package/.out/util/cache.js +42 -0
- package/.out/util/delay.d.ts +12 -0
- package/.out/util/delay.js +32 -0
- package/.out/util/format.d.ts +2 -0
- package/.out/util/format.js +11 -0
- package/.out/util/json.d.ts +1 -0
- package/.out/util/json.js +11 -0
- package/.out/util/poll.d.ts +8 -0
- package/.out/util/poll.js +23 -0
- package/.out/util/preconditions.d.ts +11 -0
- package/.out/util/preconditions.js +43 -0
- package/.out/util/promises.d.ts +1 -0
- package/.out/util/promises.js +11 -0
- package/.out/util/record.d.ts +10 -0
- package/.out/util/record.js +64 -0
- package/.out/util/specs/cache.tests.d.ts +1 -0
- package/.out/util/specs/cache.tests.js +49 -0
- package/.out/util/specs/format.tests.d.ts +1 -0
- package/.out/util/specs/format.tests.js +67 -0
- package/.out/util/specs/poll.tests.d.ts +1 -0
- package/.out/util/specs/poll.tests.js +47 -0
- package/.out/vitest.workspace.d.ts +2 -0
- package/.out/vitest.workspace.js +7 -0
- package/.turbo/turbo-build.log +18 -0
- package/.turbo/turbo-check-types.log +3 -0
- package/.turbo/turbo-release$colon$exports.log +3 -0
- package/README.md +3 -0
- package/dist/index.cjs +387 -0
- package/dist/index.d.cts +109 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.js +328 -0
- package/errors/not_implemented.ts +5 -0
- package/errors/unexpected_implementation.ts +5 -0
- package/errors/unreachable.ts +6 -0
- package/index.ts +20 -0
- package/package.exports.json +18 -0
- package/package.json +50 -0
- package/test/index.ts +1 -0
- package/test/vitest/expect.ts +16 -0
- package/tsconfig.build.json +11 -0
- package/tsconfig.json +16 -0
- package/tsup.config.ts +16 -0
- package/types/element_of_array.ts +1 -0
- package/types/extract_generics.ts +2 -0
- package/types/is_field_optional.ts +5 -0
- package/types/is_field_readonly.ts +8 -0
- package/types/maybe.ts +5 -0
- package/types/printable_of.ts +1 -0
- package/types/required_of_record.ts +4 -0
- package/types/specs/element_of_array.tests.ts +9 -0
- package/types/specs/is_field_readonly.tests.ts +15 -0
- package/types/specs/printable_of.tests.ts +8 -0
- package/types/specs/required_of_record.tests.ts +16 -0
- package/types/specs/string_key_of.tests.ts +16 -0
- package/types/string_key_of.ts +1 -0
- package/util/array.ts +12 -0
- package/util/cache.ts +52 -0
- package/util/delay.ts +36 -0
- package/util/format.ts +23 -0
- package/util/json.ts +10 -0
- package/util/poll.ts +40 -0
- package/util/preconditions.ts +83 -0
- package/util/promises.ts +11 -0
- package/util/record.ts +133 -0
- package/util/specs/cache.tests.ts +68 -0
- package/util/specs/format.tests.ts +70 -0
- package/util/specs/poll.tests.ts +75 -0
- package/vitest.workspace.ts +11 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type Delay = () => Promise<void>;
|
|
2
|
+
export declare function createDelay(millis: number): Delay;
|
|
3
|
+
/**
|
|
4
|
+
* creates a delay that blocks everything for the specified number of cold milliseconds initially, then
|
|
5
|
+
* the warm millis thereafter
|
|
6
|
+
* @param coldMillis the number of milliseconds to block initial delays for
|
|
7
|
+
* @param warmMillis the number of milliseconds to block subsequent delays for
|
|
8
|
+
* @returns a Promise that awaits for the specified time
|
|
9
|
+
*/
|
|
10
|
+
export declare function createWarmupDelay(coldMillis: number, warmMillis: number): () => Promise<void>;
|
|
11
|
+
export declare function delay(millis: number): Promise<void>;
|
|
12
|
+
export declare const secondDelay: Delay;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function createDelay(millis) {
|
|
2
|
+
return function () {
|
|
3
|
+
return delay(millis);
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* creates a delay that blocks everything for the specified number of cold milliseconds initially, then
|
|
8
|
+
* the warm millis thereafter
|
|
9
|
+
* @param coldMillis the number of milliseconds to block initial delays for
|
|
10
|
+
* @param warmMillis the number of milliseconds to block subsequent delays for
|
|
11
|
+
* @returns a Promise that awaits for the specified time
|
|
12
|
+
*/
|
|
13
|
+
export function createWarmupDelay(coldMillis, warmMillis) {
|
|
14
|
+
let warmup;
|
|
15
|
+
return function () {
|
|
16
|
+
if (warmup != null) {
|
|
17
|
+
return warmup.then(function () {
|
|
18
|
+
return delay(warmMillis);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
warmup = delay(coldMillis);
|
|
23
|
+
return warmup;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function delay(millis) {
|
|
28
|
+
return new Promise(function (resolve) {
|
|
29
|
+
setTimeout(resolve, millis);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export const secondDelay = createDelay(1000);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function format(message, ...args) {
|
|
2
|
+
let index = 0;
|
|
3
|
+
return message.replaceAll(/{(\d*)}/g, function (_substring, indexString) {
|
|
4
|
+
let argIndex = parseInt(indexString);
|
|
5
|
+
if (Number.isNaN(argIndex)) {
|
|
6
|
+
argIndex = index;
|
|
7
|
+
index++;
|
|
8
|
+
}
|
|
9
|
+
return JSON.stringify(args[argIndex]);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function errorHandlingJsonParse<T = any>(json: string, errorHandler?: (e: unknown) => void): T | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
|
+
export function errorHandlingJsonParse(json, errorHandler) {
|
|
3
|
+
try {
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
5
|
+
return JSON.parse(json);
|
|
6
|
+
}
|
|
7
|
+
catch (e) {
|
|
8
|
+
errorHandler?.(e);
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Maybe } from 'types/maybe';
|
|
2
|
+
export declare function constantPollInterval(delay: number): () => number;
|
|
3
|
+
type PollOptions = {
|
|
4
|
+
pollInterval?: (retries: number) => number;
|
|
5
|
+
retries?: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function poll<T>(f: () => Promise<Maybe<T>>, { pollInterval, retries, }?: PollOptions): Promise<Maybe<T>>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { delay } from './delay';
|
|
2
|
+
export function constantPollInterval(delay) {
|
|
3
|
+
return function () {
|
|
4
|
+
return delay;
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export async function poll(f, { pollInterval = constantPollInterval(200), retries = 3, } = {}) {
|
|
8
|
+
let retriesRemaining = retries;
|
|
9
|
+
while (retriesRemaining > 0) {
|
|
10
|
+
await delay(pollInterval(retriesRemaining));
|
|
11
|
+
retriesRemaining--;
|
|
12
|
+
const v = await f();
|
|
13
|
+
if (v != null) {
|
|
14
|
+
return v;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
// TODO
|
|
20
|
+
// function createPoll<P, T>(
|
|
21
|
+
// p: (params: P) => Promise<Maybe<T>>,
|
|
22
|
+
// options: PollOptions,
|
|
23
|
+
// ): (params: P) => Promise<Maybe<T>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FormatArg } from './format';
|
|
2
|
+
export declare class PreconditionFailedError extends Error {
|
|
3
|
+
constructor(message: string, ...args: readonly FormatArg[]);
|
|
4
|
+
}
|
|
5
|
+
export declare function assertExistsAndReturn<T>(t: T, message: string, ...args: readonly FormatArg[]): NonNullable<T>;
|
|
6
|
+
export declare function assertExists<V>(v: V, message: string, ...args: readonly FormatArg[]): asserts v is NonNullable<V>;
|
|
7
|
+
export declare function assertEqual<T extends FormatArg>(a: T, b: T, message?: string, arg1?: FormatArg, arg2?: FormatArg, ...args: readonly FormatArg[]): void;
|
|
8
|
+
export declare function assertState(condition: boolean, message: string, ...args: readonly FormatArg[]): asserts condition is true;
|
|
9
|
+
export declare function assertIs<V, T extends V>(v: V, condition: (v: V) => v is T, message: string, ...args: readonly FormatArg[]): asserts v is T;
|
|
10
|
+
export declare function checkUnary<T>(t: readonly T[], message: string, ...args: readonly FormatArg[]): T;
|
|
11
|
+
export declare function checkValidNumber(n: number, message: string, ...args: readonly FormatArg[]): number;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { format, } from './format';
|
|
2
|
+
export class PreconditionFailedError extends Error {
|
|
3
|
+
constructor(message, ...args) {
|
|
4
|
+
super(format(message, ...args));
|
|
5
|
+
this.name = 'PreconditionFailedError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export function assertExistsAndReturn(t, message, ...args) {
|
|
9
|
+
assertExists(t, message, ...args);
|
|
10
|
+
return t;
|
|
11
|
+
}
|
|
12
|
+
export function assertExists(v, message, ...args) {
|
|
13
|
+
if (v == null) {
|
|
14
|
+
throw new PreconditionFailedError(message, ...args);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function assertEqual(a, b, message = '{} != {}', arg1 = a, arg2 = b, ...args) {
|
|
18
|
+
if (a !== b) {
|
|
19
|
+
throw new PreconditionFailedError(message, arg1, arg2, ...args);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function assertState(condition, message, ...args) {
|
|
23
|
+
if (!condition) {
|
|
24
|
+
throw new PreconditionFailedError(message, ...args);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function assertIs(v, condition, message, ...args) {
|
|
28
|
+
if (!condition(v)) {
|
|
29
|
+
throw new PreconditionFailedError(message, ...args);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function checkUnary(t, message, ...args) {
|
|
33
|
+
if (t.length !== 1) {
|
|
34
|
+
throw new PreconditionFailedError(message, ...args);
|
|
35
|
+
}
|
|
36
|
+
return t[0];
|
|
37
|
+
}
|
|
38
|
+
export function checkValidNumber(n, message, ...args) {
|
|
39
|
+
if (isNaN(n) || !isFinite(n)) {
|
|
40
|
+
throw new PreconditionFailedError(message, ...args);
|
|
41
|
+
}
|
|
42
|
+
return n;
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function callAsPromise(f: (cb: (e?: unknown) => void) => void): Promise<void>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function reverse<Key extends string | number | symbol, Value extends string | number | symbol>(obj: Record<Key, Value>): Record<Value, Key>;
|
|
2
|
+
export declare function rollup<R extends Record<K, V>, K extends string | number | symbol = keyof R, V = R[K]>(...records: Partial<R>[]): R;
|
|
3
|
+
export declare function union<R1 extends Readonly<Record<K1, V1>>, K1 extends string | number | symbol, V1 extends R1[K1], R2 extends Readonly<Record<K2, V2>>, K2 extends string | number | symbol, V2 extends R2[K2]>(r1: R1, r2: R2): R1 & R2;
|
|
4
|
+
export declare function map<K extends string | number | symbol, V, R = V>(r: Readonly<Record<K, V>>, f: (k: K, v: V) => R): Record<K, R>;
|
|
5
|
+
export declare function reduce<K extends string | number | symbol, V, A>(r: Readonly<Record<K, V>>, f: (acc: A, k: K, v: V) => A, a: A): A;
|
|
6
|
+
export declare function forEach<R extends Readonly<Record<K, V>>, K extends string | number | symbol = R extends Readonly<Record<infer Kk, infer _Vv>> ? Kk : never, V = R extends Readonly<Record<infer _Kk, infer Vv>> ? Vv : never>(r: R, f: (k: K, v: R[K]) => void): void;
|
|
7
|
+
export declare function toArray<K extends string | number | symbol, V>(r: Readonly<Record<K, V>>): readonly (readonly [K, V])[];
|
|
8
|
+
export type Mutable<T> = {
|
|
9
|
+
-readonly [K in keyof T]: T[K];
|
|
10
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function reverse(obj) {
|
|
2
|
+
return Object.keys(obj).reduce((acc, stringKey) => {
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
4
|
+
const key = stringKey;
|
|
5
|
+
const value = obj[key];
|
|
6
|
+
acc[value] = key;
|
|
7
|
+
return acc;
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
9
|
+
}, {});
|
|
10
|
+
}
|
|
11
|
+
// TODO simplify the generics
|
|
12
|
+
export function rollup(...records) {
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
14
|
+
return records.slice(1).reduce((acc, record) => {
|
|
15
|
+
Object.keys(record).forEach((key) => {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
17
|
+
const k = key;
|
|
18
|
+
acc[k] = acc[k] ?? record[k];
|
|
19
|
+
});
|
|
20
|
+
return acc;
|
|
21
|
+
}, records[0]);
|
|
22
|
+
}
|
|
23
|
+
// TODO simplify the generics
|
|
24
|
+
export function union(r1, r2) {
|
|
25
|
+
return {
|
|
26
|
+
...r1,
|
|
27
|
+
...r2,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// TODO simplify the generics
|
|
31
|
+
export function map(r, f) {
|
|
32
|
+
// TODO can use reduce to implement map
|
|
33
|
+
return Object.entries(r).reduce(function (acc, [k, v,]) {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
35
|
+
const typedKey = k;
|
|
36
|
+
acc[typedKey] = f(typedKey, v);
|
|
37
|
+
return acc;
|
|
38
|
+
},
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
40
|
+
{});
|
|
41
|
+
}
|
|
42
|
+
// TODO simplify the generics
|
|
43
|
+
export function reduce(r, f, a) {
|
|
44
|
+
return Object.entries(r).reduce(function (acc, [k, v,]) {
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
46
|
+
const typedKey = k;
|
|
47
|
+
return f(acc, typedKey, v);
|
|
48
|
+
}, a);
|
|
49
|
+
}
|
|
50
|
+
export function forEach(r, f) {
|
|
51
|
+
return Object.entries(r).forEach(function ([k, v,]) {
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
53
|
+
return f(k, v);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
export function toArray(r) {
|
|
57
|
+
return reduce(r, function (acc, k, v) {
|
|
58
|
+
acc.push([
|
|
59
|
+
k,
|
|
60
|
+
v,
|
|
61
|
+
]);
|
|
62
|
+
return acc;
|
|
63
|
+
}, []);
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Cache, } from 'util/cache';
|
|
2
|
+
import { vi, } from 'vitest';
|
|
3
|
+
describe('cache', function () {
|
|
4
|
+
let cache;
|
|
5
|
+
let valueFactory;
|
|
6
|
+
beforeEach(function () {
|
|
7
|
+
valueFactory = vi.fn();
|
|
8
|
+
valueFactory.mockReturnValue(true);
|
|
9
|
+
cache = new Cache(valueFactory);
|
|
10
|
+
});
|
|
11
|
+
describe('creates value that does not exist', function () {
|
|
12
|
+
let value;
|
|
13
|
+
const params = [
|
|
14
|
+
'a',
|
|
15
|
+
1,
|
|
16
|
+
false,
|
|
17
|
+
];
|
|
18
|
+
beforeEach(function () {
|
|
19
|
+
value = cache.retrieveOrCreate(...params);
|
|
20
|
+
});
|
|
21
|
+
it('calls the value factory with the transformed key', function () {
|
|
22
|
+
expect(valueFactory).toHaveBeenCalledOnce();
|
|
23
|
+
expect(valueFactory).toHaveBeenCalledWith(...params);
|
|
24
|
+
});
|
|
25
|
+
it('returns the expected value', function () {
|
|
26
|
+
expect(value).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
describe('retrieveByKey', function () {
|
|
29
|
+
it('retrieves value by key', function () {
|
|
30
|
+
expect(cache.retrieve(...params)).toEqual([true]);
|
|
31
|
+
});
|
|
32
|
+
it('returns nothing when a non-existent key is supplied', function () {
|
|
33
|
+
expect(cache.retrieve('a', 1, true)).toBeNull();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe('looking up previously created value', function () {
|
|
37
|
+
let cachedValue;
|
|
38
|
+
beforeEach(function () {
|
|
39
|
+
cachedValue = cache.retrieveOrCreate(...params);
|
|
40
|
+
});
|
|
41
|
+
it('does not create the value again', function () {
|
|
42
|
+
expect(valueFactory).toHaveBeenCalledOnce();
|
|
43
|
+
});
|
|
44
|
+
it('returns the expected value', function () {
|
|
45
|
+
expect(cachedValue).toBeTruthy();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { format } from 'util/format';
|
|
2
|
+
describe('format', function () {
|
|
3
|
+
it.each([
|
|
4
|
+
[
|
|
5
|
+
'no args',
|
|
6
|
+
'message',
|
|
7
|
+
'message',
|
|
8
|
+
],
|
|
9
|
+
[
|
|
10
|
+
'one anonymous arg',
|
|
11
|
+
'arg {}',
|
|
12
|
+
'arg 1',
|
|
13
|
+
1,
|
|
14
|
+
],
|
|
15
|
+
[
|
|
16
|
+
'one indexed arg',
|
|
17
|
+
'arg {0}',
|
|
18
|
+
'arg "0"',
|
|
19
|
+
'0',
|
|
20
|
+
],
|
|
21
|
+
[
|
|
22
|
+
'two args',
|
|
23
|
+
'args {}, {}',
|
|
24
|
+
'args 1, 2',
|
|
25
|
+
1,
|
|
26
|
+
2,
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
'two indexed args',
|
|
30
|
+
'args {0}, {1}',
|
|
31
|
+
'args 1, 2',
|
|
32
|
+
1,
|
|
33
|
+
2,
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
'two indexed args, reversed',
|
|
37
|
+
'args {1}, {0}',
|
|
38
|
+
'args 2, 1',
|
|
39
|
+
1,
|
|
40
|
+
2,
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
'null',
|
|
44
|
+
'null? {}',
|
|
45
|
+
'null? null',
|
|
46
|
+
null,
|
|
47
|
+
],
|
|
48
|
+
[
|
|
49
|
+
'mixed argument types',
|
|
50
|
+
'{} {} {} {}',
|
|
51
|
+
'1 "2" true -5',
|
|
52
|
+
1,
|
|
53
|
+
'2',
|
|
54
|
+
true,
|
|
55
|
+
-5,
|
|
56
|
+
],
|
|
57
|
+
[
|
|
58
|
+
'object',
|
|
59
|
+
'{}',
|
|
60
|
+
'{"b":true}',
|
|
61
|
+
{ b: true },
|
|
62
|
+
],
|
|
63
|
+
])('formats %s', function (_name, message, expectedResult, ...args) {
|
|
64
|
+
const result = format(message, ...args);
|
|
65
|
+
expect(result).toEqual(expectedResult);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { constantPollInterval, poll, } from 'util/poll';
|
|
2
|
+
import { vi, } from 'vitest';
|
|
3
|
+
describe('poll', function () {
|
|
4
|
+
const pollInterval = constantPollInterval(1);
|
|
5
|
+
let callee;
|
|
6
|
+
beforeEach(function () {
|
|
7
|
+
callee = vi.fn();
|
|
8
|
+
});
|
|
9
|
+
it('returns the success value', async function () {
|
|
10
|
+
const value = 1;
|
|
11
|
+
callee.mockResolvedValueOnce([value]);
|
|
12
|
+
const result = await poll(callee, {
|
|
13
|
+
pollInterval,
|
|
14
|
+
});
|
|
15
|
+
expect(result).toEqual([value]);
|
|
16
|
+
expect(callee).toHaveBeenCalledTimes(1);
|
|
17
|
+
});
|
|
18
|
+
it('returns the success value after a retry', async function () {
|
|
19
|
+
const value = 1;
|
|
20
|
+
callee.mockResolvedValueOnce(null);
|
|
21
|
+
callee.mockResolvedValueOnce([value]);
|
|
22
|
+
const result = await poll(callee, {
|
|
23
|
+
pollInterval,
|
|
24
|
+
retries: 2,
|
|
25
|
+
});
|
|
26
|
+
expect(result).toEqual([value]);
|
|
27
|
+
expect(callee).toHaveBeenCalledTimes(2);
|
|
28
|
+
});
|
|
29
|
+
it('returns null when polling result not available after retries', async function () {
|
|
30
|
+
callee.mockResolvedValue(null);
|
|
31
|
+
const retries = 4;
|
|
32
|
+
const result = await poll(callee, {
|
|
33
|
+
pollInterval,
|
|
34
|
+
retries,
|
|
35
|
+
});
|
|
36
|
+
expect(result).toBe(null);
|
|
37
|
+
expect(callee).toHaveBeenCalledTimes(retries);
|
|
38
|
+
});
|
|
39
|
+
it('reports errors immediately', async function () {
|
|
40
|
+
const error = new Error();
|
|
41
|
+
callee.mockRejectedValue(error);
|
|
42
|
+
await expect(poll(callee, {
|
|
43
|
+
pollInterval,
|
|
44
|
+
})).rejects.toBe(error);
|
|
45
|
+
expect(callee).toHaveBeenCalledTimes(1);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
yarn run v1.22.22
|
|
2
|
+
$ tsup
|
|
3
|
+
[34mCLI[39m Building entry: index.ts
|
|
4
|
+
[34mCLI[39m Using tsconfig: tsconfig.build.json
|
|
5
|
+
[34mCLI[39m tsup v8.3.5
|
|
6
|
+
[34mCLI[39m Using tsup config: /home/runner/work/de/de/packages/base/tsup.config.ts
|
|
7
|
+
[34mCLI[39m Target: esnext
|
|
8
|
+
[34mCJS[39m Build start
|
|
9
|
+
[34mESM[39m Build start
|
|
10
|
+
[32mESM[39m [1mdist/index.js [22m[32m6.64 KB[39m
|
|
11
|
+
[32mESM[39m ⚡️ Build success in 47ms
|
|
12
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m8.78 KB[39m
|
|
13
|
+
[32mCJS[39m ⚡️ Build success in 50ms
|
|
14
|
+
[34mDTS[39m Build start
|
|
15
|
+
[32mDTS[39m ⚡️ Build success in 2940ms
|
|
16
|
+
[32mDTS[39m [1mdist/index.d.cts [22m[32m5.90 KB[39m
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m5.90 KB[39m
|
|
18
|
+
Done in 4.05s.
|
package/README.md
ADDED