Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependencies #91

Merged
merged 8 commits into from
May 6, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 8 additions & 8 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ type AnyFunction = (...arguments_: any) => any;

const cacheStore = new WeakMap<AnyFunction, CacheStorage<any, any>>();

interface CacheStorageContent<ValueType> {
type CacheStorageContent<ValueType> = {
fregante marked this conversation as resolved.
Show resolved Hide resolved
data: ValueType;
maxAge: number;
}
};

interface CacheStorage<KeyType, ValueType> {
type CacheStorage<KeyType, ValueType> = {
has: (key: KeyType) => boolean;
get: (key: KeyType) => CacheStorageContent<ValueType> | undefined;
set: (key: KeyType, value: CacheStorageContent<ValueType>) => void;
delete: (key: KeyType) => void;
clear?: () => void;
}
};

export interface Options<
export type Options<
FunctionToMemoize extends AnyFunction,
CacheKeyType,
> {
> = {
/**
Milliseconds until the cache expires.

Expand Down Expand Up @@ -63,7 +63,7 @@ export interface Options<
@example new WeakMap()
*/
readonly cache?: CacheStorage<CacheKeyType, ReturnType<FunctionToMemoize>>;
}
};

/**
[Memoize](https://en.wikipedia.org/wiki/Memoization) functions - An optimization used to speed up consecutive function calls by caching the result of calls with identical input.
Expand Down Expand Up @@ -174,7 +174,7 @@ export function memDecorator<
propertyKey: string,
descriptor: PropertyDescriptor,
): void => {
const input = target[propertyKey]; // eslint-disable-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
const input = target[propertyKey]; // eslint-disable-line @typescript-eslint/no-unsafe-assignment

if (typeof input !== 'function') {
throw new TypeError('The decorated value must be a function');
Expand Down
27 changes: 11 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,25 @@
"promise"
],
"dependencies": {
"map-age-cleaner": "^0.1.3",
"map-age-cleaner": "^0.2.0",
"mimic-fn": "^4.0.0"
},
"devDependencies": {
"@ava/typescript": "^1.1.1",
"@sindresorhus/tsconfig": "^1.0.2",
"@types/serialize-javascript": "^4.0.0",
"ava": "^3.15.0",
"del-cli": "^3.0.1",
"delay": "^4.4.0",
"serialize-javascript": "^5.0.1",
"ts-node": "^10.1.0",
"tsd": "^0.13.1",
"typescript": "^4.3.5",
"xo": "^0.41.0"
"@sindresorhus/tsconfig": "^3.0.1",
fregante marked this conversation as resolved.
Show resolved Hide resolved
"@types/serialize-javascript": "^5.0.2",
"ava": "^5.2.0",
"del-cli": "^5.0.0",
"delay": "^5.0.0",
"serialize-javascript": "^6.0.1",
"ts-node": "^10.9.1",
"tsd": "^0.28.1",
"typescript": "^5.0.4",
"xo": "^0.54.2"
},
"ava": {
"timeout": "1m",
"extensions": {
"ts": "module"
},
"nonSemVerExperiments": {
"configurableModuleFormat": true
},
fregante marked this conversation as resolved.
Show resolved Hide resolved
"nodeArguments": [
"--loader=ts-node/esm"
]
Expand Down
18 changes: 10 additions & 8 deletions test-d/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {expectType} from 'tsd';
import mem, {memClear} from '..';
import mem, {memClear} from '../index.js';

// eslint-disable-next-line unicorn/prefer-native-coercion-functions -- Required `string` type
const fn = (text: string) => Boolean(text);

expectType<typeof fn>(mem(fn));
Expand Down Expand Up @@ -33,42 +34,43 @@ memClear(fn);

// `cacheKey` tests.
// The argument should match the memoized function’s parameters
// eslint-disable-next-line unicorn/prefer-native-coercion-functions -- Required `string` type
mem((text: string) => Boolean(text), {
cacheKey: arguments_ => {
cacheKey(arguments_) {
expectType<[string]>(arguments_);
},
});

mem(() => 1, {
cacheKey: arguments_ => {
cacheKey(arguments_) {
expectType<[]>(arguments_); // eslint-disable-line @typescript-eslint/ban-types
},
});

// Ensures that the various cache functions infer their arguments type from the return type of `cacheKey`
mem((_arguments: {key: string}) => 1, {
cacheKey: (arguments_: [{key: string}]) => {
cacheKey(arguments_: [{key: string}]) {
expectType<[{key: string}]>(arguments_);
return new Date();
},
cache: {
get: key => {
get(key) {
expectType<Date>(key);

return {
data: 5,
maxAge: 2,
};
},
set: (key, data) => {
set(key, data) {
expectType<Date>(key);
expectType<{data: number; maxAge: number}>(data);
},
has: key => {
has(key) {
expectType<Date>(key);
return true;
},
delete: key => {
delete(key) {
expectType<Date>(key);
},
clear: () => undefined,
Expand Down
88 changes: 44 additions & 44 deletions test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,43 +10,43 @@ test('memoize', t => {
t.is(memoized(), 0);
t.is(memoized(), 0);
t.is(memoized(), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(undefined), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(undefined), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized('foo'), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized('foo'), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized('foo'), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized('foo', 'bar'), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized('foo', 'bar'), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized('foo', 'bar'), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 2);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 2);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(null), 3);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(null), 3);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(fixture), 4);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(fixture), 4);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(true), 5);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(true), 5);

// Ensure that functions are stored by reference and not by "value" (e.g. their `.toString()` representation)
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(() => i++), 6);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(() => i++), 7);
});

Expand All @@ -66,13 +66,13 @@ test('memoize with multiple non-primitive arguments', t => {
const memoized = mem(() => i++, {cacheKey: JSON.stringify});
t.is(memoized(), 0);
t.is(memoized(), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized({foo: true}, {bar: false}), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized({foo: true}, {bar: false}), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized({foo: true}, {bar: false}, {baz: true}), 2);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized({foo: true}, {bar: false}, {baz: true}), 2);
});

Expand All @@ -81,13 +81,13 @@ test('memoize with regexp arguments', t => {
const memoized = mem(() => i++, {cacheKey: serializeJavascript});
t.is(memoized(), 0);
t.is(memoized(), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(/Sindre Sorhus/), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(/Sindre Sorhus/), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(/Elvin Peng/), 2);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(/Elvin Peng/), 2);
});

Expand All @@ -98,29 +98,29 @@ test('memoize with Symbol arguments', t => {
const memoized = mem(() => i++);
t.is(memoized(), 0);
t.is(memoized(), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(argument1), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(argument1), 1);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(argument2), 2);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(argument2), 2);
});

test('maxAge option', async t => {
let i = 0;
const fixture = () => i++;
const memoized = mem(fixture, {maxAge: 100});
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
await delay(50);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
await delay(200);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 1);
});

Expand All @@ -135,19 +135,19 @@ test('maxAge option deletes old items', async t => {
return _delete(item);
};

// @ts-expect-error
// @ts-expect-error Testing "never"
const memoized = mem(fixture, {maxAge: 100, cache});
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
t.is(cache.has(1), true);
await delay(50);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
t.is(deleted.length, 0);
await delay(200);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 1);
t.is(deleted.length, 1);
t.is(deleted[0], 1);
Expand All @@ -165,17 +165,17 @@ test('maxAge items are deleted even if function throws', async t => {

const cache = new Map();
const memoized = mem(fixture, {maxAge: 100, cache});
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
t.is(cache.size, 1);
await delay(50);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(memoized(1), 0);
await delay(200);
t.throws(() => {
// @ts-expect-error
// @ts-expect-error Testing "never"
memoized(1);
}, {message: 'failure'});
t.is(cache.size, 0);
Expand All @@ -201,7 +201,7 @@ test('promise support', async t => {
const memoized = mem(async () => i++);
t.is(await memoized(), 0);
t.is(await memoized(), 0);
// @ts-expect-error
// @ts-expect-error Testing "never"
t.is(await memoized(10), 1);
});

Expand Down