diff --git a/package.json b/package.json index d07626001..c15af024f 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,7 @@ ] }, "devDependencies": { + "@edge-runtime/jest-environment": "^3.0.4", "@arethetypeswrong/cli": "^0.15.3", "@playwright/test": "^1.34.3", "@swc/core": "^1.3.62", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ca79cc636..09539aebc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@arethetypeswrong/cli': specifier: ^0.15.3 version: 0.15.3 + '@edge-runtime/jest-environment': + specifier: ^3.0.4 + version: 3.0.4 '@playwright/test': specifier: ^1.34.3 version: 1.34.3 @@ -506,6 +509,29 @@ packages: dev: true optional: true + /@edge-runtime/jest-environment@3.0.4: + resolution: {integrity: sha512-2VpMtS0mcc0qodGQ5ZJRC0OdPkbD029eYahTL5WrbItID4xzcbgF89wVJFIU2stHuFg0q/meCGiAbpgM3/57+Q==} + engines: {node: '>=16'} + dependencies: + '@edge-runtime/vm': 4.0.4 + '@jest/environment': 29.5.0 + '@jest/fake-timers': 29.5.0 + jest-mock: 29.5.0 + jest-util: 29.5.0 + dev: true + + /@edge-runtime/primitives@5.1.1: + resolution: {integrity: sha512-osrHE4ObQ3XFkvd1sGBLkheV2mcHUqJI/Bum2AWA0R3U78h9lif3xZAdl6eLD/XnW4xhsdwjPUejLusXbjvI4Q==} + engines: {node: '>=16'} + dev: true + + /@edge-runtime/vm@4.0.4: + resolution: {integrity: sha512-LqPw+yaSPpCNnVZl5XoHQAySEzlnZiC9gReUuQHMh9GI03KKqwpVqWkIK1UfK116Yww7f2WZuAgnY/nhHwTsJA==} + engines: {node: '>=16'} + dependencies: + '@edge-runtime/primitives': 5.1.1 + dev: true + /@emnapi/runtime@1.3.1: resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} requiresBuild: true @@ -845,6 +871,16 @@ packages: '@jest/types': 27.5.1 dev: true + /@jest/environment@29.5.0: + resolution: {integrity: sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.2.5 + jest-mock: 29.7.0 + dev: true + /@jest/environment@29.7.0: resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -872,6 +908,18 @@ packages: - supports-color dev: true + /@jest/fake-timers@29.5.0: + resolution: {integrity: sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.0.2 + '@types/node': 20.2.5 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + dev: true + /@jest/fake-timers@29.7.0: resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4004,6 +4052,15 @@ packages: stack-utils: 2.0.5 dev: true + /jest-mock@29.5.0: + resolution: {integrity: sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.2.5 + jest-util: 29.7.0 + dev: true + /jest-mock@29.7.0: resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4142,6 +4199,18 @@ packages: - supports-color dev: true + /jest-util@29.5.0: + resolution: {integrity: sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.2.5 + chalk: 4.1.2 + ci-info: 3.3.2 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + /jest-util@29.7.0: resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5914,7 +5983,3 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true - -settings: - autoInstallPeers: false - excludeLinksFromLockfile: false diff --git a/src/_internal/utils/hash.ts b/src/_internal/utils/hash.ts index 1edf59165..c9528a6a8 100644 --- a/src/_internal/utils/hash.ts +++ b/src/_internal/utils/hash.ts @@ -6,6 +6,9 @@ import { OBJECT, isUndefined } from './shared' // complexity is almost O(1). const table = new WeakMap() +const isObjectType = (value: any, type: string) => + OBJECT.prototype.toString.call(value) === `[object ${type}]` + // counter of the key let counter = 0 @@ -19,13 +22,13 @@ let counter = 0 // parsable. export const stableHash = (arg: any): string => { const type = typeof arg - const constructor = arg && arg.constructor - const isDate = constructor == Date - + const isDate = isObjectType(arg, 'Date') + const isRegex = isObjectType(arg, 'RegExp') + const isPlainObject = isObjectType(arg, 'Object') let result: any let index: any - if (OBJECT(arg) === arg && !isDate && constructor != RegExp) { + if (OBJECT(arg) === arg && !isDate && !isRegex) { // Object/function, not null/date/regexp. Use WeakMap to store the id first. // If it's already hashed, directly return the result. result = table.get(arg) @@ -37,7 +40,7 @@ export const stableHash = (arg: any): string => { result = ++counter + '~' table.set(arg, result) - if (constructor == Array) { + if (Array.isArray(arg)) { // Array. result = '@' for (index = 0; index < arg.length; index++) { @@ -45,7 +48,7 @@ export const stableHash = (arg: any): string => { } table.set(arg, result) } - if (constructor == OBJECT) { + if (isPlainObject) { // Object, sort keys. result = '#' const keys = OBJECT.keys(arg).sort() diff --git a/test/unit/serialize.test.ts b/test/unit/serialize.test.ts index 9cb6f3235..3fdf80156 100644 --- a/test/unit/serialize.test.ts +++ b/test/unit/serialize.test.ts @@ -1,3 +1,6 @@ +/** + * @jest-environment @edge-runtime/jest-environment + */ import { unstable_serialize } from 'swr' import { stableHash } from 'swr/_internal' diff --git a/test/unit/utils.test.tsx b/test/unit/utils.test.tsx index 689cf7889..918fb4328 100644 --- a/test/unit/utils.test.tsx +++ b/test/unit/utils.test.tsx @@ -1,3 +1,6 @@ +/** + * @jest-environment @edge-runtime/jest-environment + */ import { stableHash as hash, serialize,