-
-
Notifications
You must be signed in to change notification settings - Fork 934
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
Deprecate helpers.unique for removal #1785
Comments
Is there any rationale underneath this decision, except not having enough bandwidth to cope with everything? |
I started to look around for some npm packages and did not found directly something that suites our need as So I did something what everyone is doing right now 👀 TLDR: interface Store {
[key: string]: any;
}
function memoizeUnique<T>(callback: (...args: any[]) => T): (...args: any[]) => T {
let store: Store = {};
return function(...args: any[]): T {
let result: T;
do {
result = callback(...args);
const key = JSON.stringify(args) + JSON.stringify(result);
if (!store.hasOwnProperty(key)) {
store[key] = result;
break;
}
} while(true)
return result;
};
} With a really simple this could work-review, it can be extended to take the store as an additional argument + some addition "stop conditions" and we have something similar to what we have in faker right now. ChatGPT helped also finding a name for this: Somehow I'm really shocked that something like this doesn't already exists on npm as far as my researches are going 🤷 |
This is not required for |
My actual try of an re-implementation looks like this: export interface Store<T> {
[key: string]: T;
}
export interface MemoizeUniqueOptions<T> {
/**
* The time in milliseconds this method may take before throwing an error.
*
* @default 50
*/
maxTime?: number;
/**
* The total number of attempts to try before throwing an error.
*
* @default 50
*/
maxRetries?: number;
/**
* The value or values that should be excluded.
*
* If the callback returns one of these values, it will be called again and the internal retries counter will be incremented.
*
* @default []
*/
exclude?: T | T[];
/**
* The store of already fetched results.
*
* @default {}
*/
readonly store?: Store<T>;
}
export type MemoizeUniqueReturn<
T,
U extends readonly any[] = readonly any[]
> = (...args: [...U]) => T;
export function memoizeUnique<T, U extends readonly any[] = readonly any[]>(
callback: MemoizeUniqueReturn<T, U>,
options: MemoizeUniqueOptions<T> = {}
): MemoizeUniqueReturn<T, U> {
const { maxTime = 50, maxRetries = 50, store = {} } = options;
let { exclude = [] } = options;
if (!Array.isArray(exclude)) {
exclude = [exclude];
}
return (...args) => {
let startTime = Date.now();
let retries = 0;
let result: T;
do {
if (Date.now() - startTime > maxTime) {
throw new Error(
`memoizeUnique: maxTime of ${maxTime}ms exceeded after ${retries} retries`
);
}
if (retries > maxRetries) {
throw new Error(`memoizeUnique: maxRetries of ${maxRetries} exceeded`);
}
retries++;
result = callback(...args);
if ((exclude as T[]).includes(result)) {
continue;
}
const key = JSON.stringify(args) + JSON.stringify(result);
if (!store.hasOwnProperty(key)) {
store[key] = result;
break;
}
} while (true);
return result;
};
} I asked on Mastodon if someone wants to take this over: https://main.elk.zone/mas.to/@Shini92/109774289116607547 Until I have not written anything differently here, this is freely up for grab and whoever want to can publish this as an npm package. |
We started to merge the deprecation As already described above, this decision was made out of several arguments:
By the decision and trying to encourage the community to provide a package that serves the purpose of the function, we can move it out without the need on our side to make further breaking changes and also relieve our codebase by A comment above (#1785 (comment)) I already provided an implementation that is already improved over what our faker-unique currently provides. The best I currently can imaging is if someone out of the community is willing to grab the code, create a repo, invite me + come in contact with me on Discord and then I'm happy to help as a co-contributor, but the release management and such is outsourced from my side (because I personally feel, I have already to many packages on my own that I do not use personally). |
@Shinigami92 if someone has not claimed this yet I would like to publish that package, I think it is a very useful function to use in conjunction with faker but also use-cases not tied to it. |
Go for it 😻 |
@alexguillamon I invited you to my prototype private repo |
@Shinigami92 had quite a couple of weeks on my ends, layoffs, new job, etc if you can send the invite again I will have it up this week! |
I created an npm package to be used as a replacement to unique. |
Awesome. I will have a look at it soon. IMO it doesnt matter if there is more than one package for a feature. This ensures the feature wont vanish anytime soon. |
I'm closing this as the change described in the issue has been done. Additionally, it seems that a new home for the Special thanks to @MansurAliKoroglu for providing their solution to the problem as well as @Shinigami92 and @alexguillamon who seem to work on an additional package. |
What a shame ! ='( !!! |
You can still easily generate unique data with Faker - see https://next.fakerjs.dev/guide/unique for some pointers |
Yeah, but we are forced to generate all at once, which is not easily usable in most of our cases... :/ |
FYI: I plan to PR a new implementation for unique (that matches the requirements for inclusion) after #2763 is done (for v9.0). |
Not sure if you overlooked step 4 -> you can use the outsourced unique function from https://github.com/MansurAliKoroglu/enforce-unique |
I created an issue to simplify keeping track of re-adding the feature. |
I've seen this new dependency. But it is really terrible to add a new dependency just for this standard feature. :/ |
Done ! :) |
Please see it from another point of view: That was literally the reason why we could extract it out of the faker code base without making any dependencies. Now there is a separate package, that is explicitly maintained, got new improved features and works dedicated from faker. So I absolutely do not understand at all what the downsides are except of crying 🤷 |
My definition of "standard" is "natural", "normal". For an API generating random values, it is totally "normal" to provide the ability of generating unique values. |
If you want to discuss this out further, please ping me on our discord server or create a GitHub discussion thread. |
Hi everyone, I know it’s a bit late and there’s already a great library, enforce-unique, but I’d like to promote my solution to the problem @dpaskhin/unique. Here are a few key points:
I’d appreciate it if anyone could take a look at my library. Thanks! |
we could add this to https://fakerjs.dev/guide/unique as an alternative library |
@dPaskhin Would you like to create a PR to add it to that page? |
@matthewmayer, @ST-DDT Thank you guys, I'll open a PR today |
In team meeting 2023-01-26, we decided that we do not want to maintain methods anymore that are not directly or indirectly based on mersenne, or at least used inside one of other exposed faker methods (e.g. slugify is used in domainWord).
This affects
helpers.unique
and we will mark it as deprecated for removal.There will no alternative given from inside faker, but maybe we can link to another npm package that can be used instead.
The text was updated successfully, but these errors were encountered: