https://github.com/tomokimiyauci/memo
Memoization tools, TC39 proposal-function-memo implementation
https://github.com/tomokimiyauci/memo
cache cache-map memo memoization memoize proposal-function-memo tc39
Last synced: 4 months ago
JSON representation
Memoization tools, TC39 proposal-function-memo implementation
- Host: GitHub
- URL: https://github.com/tomokimiyauci/memo
- Owner: TomokiMiyauci
- License: mit
- Created: 2023-06-07T08:41:08.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-07-08T04:21:10.000Z (11 months ago)
- Last Synced: 2025-02-19T22:19:55.454Z (4 months ago)
- Topics: cache, cache-map, memo, memoization, memoize, proposal-function-memo, tc39
- Language: TypeScript
- Homepage: https://deno.land/x/memoization
- Size: 61.5 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
- Security: .github/SECURITY.md
Awesome Lists containing this project
README
# memo
[](https://deno.land/x/memoization)
[](https://deno.land/x/memoization?doc)
[](https://github.com/TomokiMiyauci/memo/releases)
[](https://codecov.io/gh/TomokiMiyauci/memo)
[](LICENSE)[](https://github.com/TomokiMiyauci/memo/actions/workflows/test.yaml)
[](https://nodei.co/npm/@miyauci/memo/)
[](https://github.com/RichardLitt/standard-readme)
[](https://github.com/semantic-release/semantic-release)Memoization tools, TC39
[proposal-function-memo](https://github.com/tc39/proposal-function-memo)
implementation.## Table of Contents
- [Install](#install)
- [Usage](#usage)
- [Custom cache](#custom-cache)
- [Keying](#keying)
- [Instantiation caching](#instantiation-caching)
- [Polyfill](#polyfill)
- [API](#api)
- [Contributing](#contributing)
- [License](#license)## Install
deno.land:
```ts
import * as mod from "https://deno.land/x/memoization/mod.ts";
```npm:
```bash
npm i @miyauci/memo
```## Usage
Returns the proxy function whose call is monitored. It calls at most once for
each given arguments.```ts
import { memo } from "https://deno.land/x/memoization/mod.ts";function f(x: number): number {
console.log(x);
return x * 2;
}const fMemo = memo(f);
fMemo(3); // Prints 3 and returns 6.
fMemo(3); // Does not print anything. Returns 6.
fMemo(2); // Prints 2 and returns 4.
fMemo(2); // Does not print anything. Returns 4.
fMemo(3); // Does not print anything. Returns 6.
```Either version would work with recursive functions:
```ts
import { memo } from "https://deno.land/x/memoization/mod.ts";const fib = memo((num: number): number => {
if (num < 2) return num;return fib(num - 1) + fib(num - 2);
});fib(1000);
```### Custom cache
To control the cache, specify `cache`.
The cache must implement the following interfaces:
```ts
interface MapLike {
get(key: K): V | undefined;
has(key: K): boolean;
set(key: K, value: V): void;
}
```By default, an unlimited cache is used by `WeakMap`.
```ts
import { type MapLike, memo } from "https://deno.land/x/memoization/mod.ts";declare const lruCache: MapLike;
declare const fn: () => unknown;const $fn = memo(fn, lruCache);
```See TC39
[proposal-policy-map-set](https://github.com/tc39/proposal-policy-map-set) and
its [implementation](https://github.com/TomokiMiyauci/cache-mapset).### Keying
Cache keys are represented by
[composite keys](https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey).The composite keys are passed several elements for the key, called components.
The components are as follows:
- target function
- this arg(`this`)
- new target(`new.target`)
- argsOf these, target function is used to identify a unique function. The target
function is not used to identify a unique function, since the composite key is a
global registry. For more information, see
[FAQ: What scope is the idempotentcy?](https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey#what-scope-is-the-idempotentcy)Also, composite key employs the
[same-value-zero](https://tc39.es/ecma262/#sec-samevaluezero) algorithm to
verify the equivalence of each component.You can modify the args component through the `keying` callback.
```ts
import { type MapLike, memo } from "https://deno.land/x/memoization/mod.ts";declare const respond: (request: Request) => Response;
const $respond = memo(
respond,
undefined,
([request]) => [request.method, request.url],
);
```Currently, only the args component can be modified. This is being discussed in
[#4 (comment)](https://github.com/tc39/proposal-function-memo/issues/4#issuecomment-1083552333)
and it is not clear how this arg and new target should be handled.### Instantiation caching
Caching of instantiation is also supported. Calls to constructor functions with
the `new` operator are cacheable based on their arguments.```ts
import { memo } from "https://deno.land/x/memoization/mod.ts";
import { assert } from "https://deno.land/std/testing/asserts.ts";assert(new Error() !== new Error());
const $Error = memo(Error);
assert(new $Error() === new $Error());
assert($Error("test") === $Error("test"));assert(new $Error() !== $Error());
assert(new $Error() !== new $Error("test"));
```### Polyfill
Polyfill affects the global object. You must be very careful when using it.
```ts
import "https://deno.land/x/memoization/polyfill.ts";const fib = ((num: number): number => {
if (num < 2) return num;return fib(num - 1) + fib(num - 2);
}).memo();fib(1000);
```## API
See [deno doc](https://deno.land/x/memoization?doc) for all APIs.
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md)
## License
[MIT](LICENSE) © 2023 Tomoki Miyauchi