1/** A hash value as computed by {@link phash}.
2 *
3 * @remarks
4 * Typically `HashValue`s are used as hashes and keys of GraphQL documents,
5 * variables, and combined, for GraphQL requests.
6 */
7export type HashValue = number & {
8 /** Marker to indicate that a `HashValue` may not be created by a user.
9 *
10 * @remarks
11 * `HashValue`s are created by {@link phash} and are marked as such to not mix them
12 * up with other numbers and prevent them from being created or used outside of this
13 * hashing function.
14 *
15 * @internal
16 */
17 readonly _opaque: unique symbol;
18};
19
20/** Computes a djb2 hash of the given string.
21 *
22 * @param x - the string to be hashed
23 * @param seed - optionally a prior hash for progressive hashing
24 * @returns a hash value, i.e. a number
25 *
26 * @remark
27 * This is the hashing function used throughout `urql`, primarily to compute
28 * {@link Operation.key}.
29 *
30 * @see {@link http://www.cse.yorku.ca/~oz/hash.html#djb2} for a further description of djb2.
31 */
32export const phash = (x: string, seed?: HashValue): HashValue => {
33 let h = (seed || 5381) | 0;
34 for (let i = 0, l = x.length | 0; i < l; i++)
35 h = (h << 5) + h + x.charCodeAt(i);
36 return h as HashValue;
37};