chore: add extentsion in imports (#1678)

* chore: add extentsion in imports

* fix github workflow

* revert for zustand/context

* do not patch :)

* fix workflow file

* update ts 5

* patch tsconfig

* use old typescript for react 16

* downlevel-dts to 3.8

* Revert "downlevel-dts to 3.8"

This reverts commit d03e5266e14146ed4a7c92e8a5cd2cb295727f69.

* patch workflow file

* patch for react 16

* remove ts3.4 in workflow

* skipLibChecks

* revert changes in test-multiple-versions.yml

* fix sed

* wip: add allowJs

* Revert "wip: add allowJs"

This reverts commit fca34d7d2decc1e469a733224f7680ab37792dc8.

* use ts 495

* useESM false

* Revert "useESM false"

This reverts commit 07a91d8acb14bc5839013aad47d0606dec312d62.

* no coverage

* no coverage 2

* no coverage 3

* wip

* disable transform

* revert a change

* revert changes

* test: try ignoring tests with dynamic imports

* test: skip tests that require/tests modules in isolation

* test: remove dynamic import

* run skipped tests on CI

* test: add new devtools imports to ci-only tests

* revert CI-ONLY-* hack

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* wip: workaround for react 16

* CI-MATRIX- for devtools CI hacks

* test: add env variable to test multiple builds workflow

* hack await import

* hack await import for another one

* wip: experimenting workflow file

* wip: experimenting workflow file

* wip: experimenting workflow file

* use different env name

* wip: experimenting workflow file

* do not use two envs

* revert to NODE_ENV

---------

Co-authored-by: Arjun <14841132+arjunvegda@users.noreply.github.com>
This commit is contained in:
Daishi Kato 2023-05-02 06:28:46 +09:00 committed by GitHub
parent 22db0014bb
commit f37530fc3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 152 additions and 136 deletions

View File

@ -36,6 +36,7 @@
"prefer-const": "error",
"curly": ["warn", "multi-line", "consistent"],
"no-console": "off",
"import/extensions": ["error", "always"],
"import/no-unresolved": ["error", { "commonjs": true, "amd": true }],
"import/export": "error",
"@typescript-eslint/no-duplicate-imports": ["error"],
@ -93,12 +94,8 @@
"@typescript-eslint/parser": [".js", ".jsx", ".ts", ".tsx"]
},
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx", ".json"],
"paths": ["src"]
},
"alias": {
"extensions": [".js", ".jsx", ".ts", ".tsx", ".json"],
"extensions": [".js", ".jsx", ".ts", ".tsx"],
"map": [
["^zustand$", "./src/index.ts"],
["zustand", "./src"]
@ -108,9 +105,9 @@
},
"overrides": [
{
"files": ["src"],
"parserOptions": {
"project": "./tsconfig.json"
"files": ["tests/**/*.ts", "tests/**/*.tsx"],
"rules": {
"import/extensions": ["error", "never"]
}
},
{

View File

@ -14,6 +14,22 @@ jobs:
matrix:
build: [cjs, umd] # [cjs, esm, umd, system]
env: [development, production]
devtools-skip:
- CI-MATRIX-NOSKIP
include:
- devtools-skip: CI-MATRIX-[2345]
build: umd
- devtools-skip: CI-MATRIX-[1345]
build: umd
- devtools-skip: CI-MATRIX-[1245]
build: umd
- devtools-skip: CI-MATRIX-[1235]
build: umd
- devtools-skip: CI-MATRIX-[1234]
build: umd
exclude:
- devtools-skip: CI-MATRIX-NOSKIP
build: umd
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
@ -48,13 +64,23 @@ jobs:
sed -i~ "1s/^/import.meta.env=import.meta.env||{};import.meta.env.MODE='${NODE_ENV}';/" tests/*.tsx
env:
NODE_ENV: ${{ matrix.env }}
- name: Patch for UMD/SystemJS
if: ${{ matrix.build == 'umd' || matrix.build == 'system' }}
- name: Patch for UMD
if: ${{ matrix.build == 'umd' }}
run: |
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\/${BUILD}\1.${NODE_ENV}.js/" package.json
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\/umd\1.${NODE_ENV}.js/" package.json
sed -i~ 's/"test:ci":.*,$/"test:ci": "jest",/' package.json
sed -i~ 's/= await import(/= require(/' tests/devtools.test.tsx
env:
NODE_ENV: ${{ matrix.env }}
run: |
sed -i~ "s/it('\[${DEVTOOLS_SKIP}\]/it.skip('/" tests/devtools.test.tsx
env:
DEVTOOLS_SKIP: ${{ matrix.devtools-skip }}
- name: Patch for SystemJS
if: ${{ matrix.build == 'system' }}
run: |
sed -i~ "s/<rootDir>\/src\(.*\)\.ts/<rootDir>\/dist\/system\1.${NODE_ENV}.js/" package.json
env:
BUILD: ${{ matrix.build }}
NODE_ENV: ${{ matrix.env }}
- name: Test ${{ matrix.build }} ${{ matrix.env }}
run: |

View File

@ -35,6 +35,22 @@ jobs:
- 18.2.0
- 18.3.0-next-1308e49a6-20230330
- 0.0.0-experimental-1308e49a6-20230330
devtools-skip:
- CI-MATRIX-NOSKIP
include:
- devtools-skip: CI-MATRIX-[2345]
react: 16.8.0
- devtools-skip: CI-MATRIX-[1345]
react: 16.8.0
- devtools-skip: CI-MATRIX-[1245]
react: 16.8.0
- devtools-skip: CI-MATRIX-[1235]
react: 16.8.0
- devtools-skip: CI-MATRIX-[1234]
react: 16.8.0
exclude:
- devtools-skip: CI-MATRIX-NOSKIP
react: 16.8.0
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
@ -53,7 +69,11 @@ jobs:
sed -i~ 's/"jsx": "react-jsx"/"jsx": "react"/' tsconfig.json
sed -i~ 's/import\.meta\.env[?]\.MODE/"DEVELOPMENT".toLowerCase()/' src/*.ts src/*/*.ts
sed -i~ 's/"test:ci":.*,$/"test:ci": "jest",/' package.json
- name: Test ${{ matrix.react }}
sed -i~ 's/= await import(/= require(/' tests/devtools.test.tsx
sed -i~ "s/it('\[${DEVTOOLS_SKIP}\]/it.skip('/" tests/devtools.test.tsx
env:
DEVTOOLS_SKIP: ${{ matrix.devtools-skip }}
- name: Test ${{ matrix.react }} ${{ matrix.devtools-skip }}
run: |
yarn add -D react@${{ matrix.react }} react-dom@${{ matrix.react }}
yarn test:ci

View File

@ -13,6 +13,7 @@ jobs:
fail-fast: false
matrix:
typescript:
- 4.9.5
- 4.8.4
- 4.7.4
- 4.6.4
@ -35,6 +36,8 @@ jobs:
sed -i~ 's/\/\/ @ts-expect-error.*\[LATEST-TS-ONLY\]//' tests/*.tsx
sed -i~ 's/"target":/"skipLibCheck":true,"target":/' tsconfig.json
sed -i~ 's/"exactOptionalPropertyTypes": true,//' tsconfig.json
sed -i~ 's/"moduleResolution": "nodenext",/"moduleResolution": "node",/' tsconfig.json
sed -i~ 's/"allowImportingTsExtensions": true,//' tsconfig.json
sed -i~ 's/"zustand": \["\.\/src\/index\.ts"\],/"zustand": [".\/dist\/index.d.ts"],/' tsconfig.json
sed -i~ 's/"zustand\/\*": \["\.\/src\/\*\.ts"\]/"zustand\/*": [".\/dist\/*.d.ts"]/' tsconfig.json
sed -i~ 's/"include": .*/"include": ["src\/types.d.ts", "dist\/**\/*", "tests\/**\/*"],/' tsconfig.json

View File

@ -85,7 +85,7 @@
"build:middleware:immer": "rollup -c --config-middleware_immer",
"build:shallow": "rollup -c --config-shallow",
"build:context": "rollup -c --config-context",
"postbuild": "yarn copy && yarn patch-esm-ts",
"postbuild": "yarn patch-d-ts && yarn copy && yarn patch-esm-ts",
"prettier": "prettier \"*.{js,json,md}\" \"{examples,src,tests,docs}/**/*.{js,jsx,ts,tsx,md,mdx}\" --write",
"prettier:ci": "prettier '*.{js,json,md}' '{examples,src,tests,docs}/**/*.{js,jsx,ts,tsx,md,mdx}' --list-different",
"eslint": "eslint --no-eslintrc --c .eslintrc.json --fix '*.{js,json}' '{src,tests}/**/*.{ts,tsx}'",
@ -95,6 +95,7 @@
"test:ci": "yarn node --experimental-vm-modules $(yarn bin jest)",
"test:dev": "yarn node --experimental-vm-modules $(yarn bin jest) --watch --no-coverage",
"test:coverage:watch": "yarn node --experimental-vm-modules $(yarn bin jest) --watch",
"patch-d-ts": "node -e \"var {entries}=require('./rollup.config.js');require('shelljs').find('dist/**/*.d.ts').forEach(f=>{entries.forEach(({find,replacement})=>require('shelljs').sed('-i',new RegExp(' from \\''+find.source.slice(0,-1)+'\\';$'),' from \\''+replacement+'\\';',f));require('shelljs').sed('-i',/ from '(\\.[^']+)\\.ts';$/,' from \\'\\$1\\';',f)})\"",
"copy": "shx cp -r dist/src/* dist/esm && shx cp -r dist/src/* dist && shx rm -rf dist/src && shx rm -rf dist/{src,tests} && downlevel-dts dist dist/ts3.4 && shx cp package.json readme.md LICENSE dist && json -I -f dist/package.json -e \"this.private=false; this.devDependencies=undefined; this.optionalDependencies=undefined; this.scripts=undefined; this.prettier=undefined; this.jest=undefined;\"",
"patch-esm-ts": "node -e \"require('shelljs').find('dist/esm/**/*.d.ts').forEach(f=>{var f2=f.replace(/\\.ts$/,'.mts');require('fs').copyFileSync(f,f2);require('shelljs').sed('-i',/ from '(\\.[^']+)';$/,' from \\'\\$1.mjs\\';',f2);require('shelljs').sed('-i',/^declare module '(\\.[^']+)'/,'declare module \\'\\$1.mjs\\'',f2)})\""
},

View File

@ -6,10 +6,11 @@ const replace = require('@rollup/plugin-replace')
const terser = require('@rollup/plugin-terser')
const typescript = require('@rollup/plugin-typescript')
const { default: esbuild } = require('rollup-plugin-esbuild')
const createBabelConfig = require('./babel.config')
const createBabelConfig = require('./babel.config.js')
const extensions = ['.js', '.ts', '.tsx']
const { root } = path.parse(process.cwd())
const entries = [{ find: /.*\/vanilla\.ts$/, replacement: 'zustand/vanilla' }]
function external(id) {
return !id.startsWith('.') && !id.startsWith(root)
@ -55,11 +56,7 @@ function createESMConfig(input, output) {
output: { file: output, format: 'esm' },
external,
plugins: [
alias({
entries: {
'./vanilla': 'zustand/vanilla',
},
}),
alias({ entries }),
resolve({ extensions }),
replace({
...(output.endsWith('.js')
@ -100,11 +97,7 @@ function createCommonJSConfig(input, output, options) {
},
external,
plugins: [
alias({
entries: {
'./vanilla': 'zustand/vanilla',
},
}),
alias({ entries }),
resolve({ extensions }),
replace({
'import.meta.env?.MODE': 'process.env.NODE_ENV',
@ -140,11 +133,7 @@ function createUMDConfig(input, output, env) {
},
external,
plugins: [
alias({
entries: {
'./vanilla': 'zustand/vanilla',
},
}),
alias({ entries }),
resolve({ extensions }),
replace({
'import.meta.env?.MODE': JSON.stringify(env),
@ -166,11 +155,7 @@ function createSystemConfig(input, output, env) {
},
external,
plugins: [
alias({
entries: {
'./vanilla': 'zustand/vanilla',
},
}),
alias({ entries }),
resolve({ extensions }),
replace({
'import.meta.env?.MODE': JSON.stringify(env),
@ -211,3 +196,5 @@ module.exports = function (args) {
createSystemConfig(`src/${c}.ts`, `dist/system/${c}`, 'production'),
]
}
module.exports.entries = []

View File

@ -1,3 +1,3 @@
export * from './vanilla'
export * from './react'
export { default } from './react'
export * from './vanilla.ts'
export * from './react.ts'
export { default } from './react.ts'

View File

@ -1,5 +1,5 @@
export * from './middleware/redux'
export * from './middleware/devtools'
export * from './middleware/subscribeWithSelector'
export * from './middleware/combine'
export * from './middleware/persist'
export * from './middleware/redux.ts'
export * from './middleware/devtools.ts'
export * from './middleware/subscribeWithSelector.ts'
export * from './middleware/combine.ts'
export * from './middleware/persist.ts'

View File

@ -1,4 +1,4 @@
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla'
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.ts'
type Write<T, U> = Omit<T, keyof U> & U

View File

@ -1,5 +1,9 @@
import type {} from '@redux-devtools/extension'
import type { StateCreator, StoreApi, StoreMutatorIdentifier } from '../vanilla'
import type {
StateCreator,
StoreApi,
StoreMutatorIdentifier,
} from '../vanilla.ts'
// Copy types to avoid import type { Config } from '@redux-devtools/extension'
// https://github.com/pmndrs/zustand/issues/1205

View File

@ -1,6 +1,6 @@
import { produce } from 'immer'
import type { Draft } from 'immer'
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla'
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.ts'
type Immer = <
T,

View File

@ -1,4 +1,8 @@
import type { StateCreator, StoreApi, StoreMutatorIdentifier } from '../vanilla'
import type {
StateCreator,
StoreApi,
StoreMutatorIdentifier,
} from '../vanilla.ts'
export interface StateStorage {
getItem: (name: string) => string | null | Promise<string | null>

View File

@ -1,5 +1,5 @@
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla'
import type { NamedSet } from './devtools'
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.ts'
import type { NamedSet } from './devtools.ts'
type Write<T, U> = Omit<T, keyof U> & U

View File

@ -1,4 +1,4 @@
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla'
import type { StateCreator, StoreMutatorIdentifier } from '../vanilla.ts'
type SubscribeWithSelector = <
T,

View File

@ -3,14 +3,15 @@ import { useDebugValue } from 'react'
// This doesn't work in ESM, because use-sync-external-store only exposes CJS.
// See: https://github.com/pmndrs/valtio/issues/452
// The following is a workaround until ESM is supported.
// eslint-disable-next-line import/extensions
import useSyncExternalStoreExports from 'use-sync-external-store/shim/with-selector'
import { createStore } from './vanilla'
import { createStore } from './vanilla.ts'
import type {
Mutate,
StateCreator,
StoreApi,
StoreMutatorIdentifier,
} from './vanilla'
} from './vanilla.ts'
const { useSyncExternalStoreWithSelector } = useSyncExternalStoreExports

View File

@ -6,13 +6,8 @@ import {
it,
jest,
} from '@jest/globals'
import { StoreApi } from 'zustand/vanilla'
const getImports = async () => {
const { devtools } = await import('zustand/middleware')
const { createStore } = await import('zustand/vanilla')
return { createStore, devtools }
}
import { devtools, redux } from 'zustand/middleware'
import { StoreApi, createStore } from 'zustand/vanilla'
type TupleOfEqualLengthH<
Arr extends unknown[],
@ -133,7 +128,6 @@ beforeEach(() => {
})
it('connects to the extension by passing the options and initializes', async () => {
const { devtools, createStore } = await getImports()
const options = { name: 'test', foo: 'bar' }
const initialState = { count: 0 }
createStore(devtools(() => initialState, { enabled: true, ...options }))
@ -157,32 +151,27 @@ describe('If there is no extension installed...', () => {
})
it('does not throw', async () => {
const { devtools, createStore } = await getImports()
expect(() => {
createStore(devtools(() => ({ count: 0 })))
}).not.toThrow()
})
it('does not warn if not enabled', async () => {
const { devtools, createStore } = await getImports()
createStore(devtools(() => ({ count: 0 })))
expect(console.warn).not.toBeCalled()
})
it('[DEV-ONLY] warns if enabled in dev mode', async () => {
const { devtools, createStore } = await getImports()
createStore(devtools(() => ({ count: 0 }), { enabled: true }))
expect(console.warn).toBeCalled()
})
it.skip('[PRD-ONLY] does not warn if not in dev env', async () => {
const { devtools, createStore } = await getImports()
createStore(devtools(() => ({ count: 0 })))
expect(console.warn).not.toBeCalled()
})
it.skip('[PRD-ONLY] does not warn if not in dev env even if enabled', async () => {
const { devtools, createStore } = await getImports()
createStore(devtools(() => ({ count: 0 }), { enabled: true }))
expect(console.warn).not.toBeCalled()
})
@ -190,7 +179,6 @@ describe('If there is no extension installed...', () => {
describe('When state changes...', () => {
it("sends { type: setStateName || 'anonymous`, ...rest } as the action with current state", async () => {
const { devtools, createStore } = await getImports()
const options = {
name: 'testOptionsName',
enabled: true,
@ -224,7 +212,6 @@ describe('When state changes...', () => {
describe('when it receives a message of type...', () => {
describe('ACTION...', () => {
it('does nothing', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0 }
const api = createStore(devtools(() => initialState, { enabled: true }))
const setState = jest.spyOn(api, 'setState')
@ -240,7 +227,6 @@ describe('when it receives a message of type...', () => {
})
it('unless action type is __setState', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0 }
const api = createStore(devtools(() => initialState, { enabled: true }))
@ -254,7 +240,6 @@ describe('when it receives a message of type...', () => {
})
it('does nothing even if there is `api.dispatch`', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0 }
const api = createStore(devtools(() => initialState, { enabled: true }))
;(api as any).dispatch = jest.fn()
@ -272,7 +257,6 @@ describe('when it receives a message of type...', () => {
})
it('dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0 }
const api = createStore(devtools(() => initialState, { enabled: true }))
;(api as any).dispatch = jest.fn()
@ -293,7 +277,6 @@ describe('when it receives a message of type...', () => {
})
it('does not throw for unsupported payload', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0 }
const api = createStore(devtools(() => initialState, { enabled: true }))
;(api as any).dispatch = jest.fn()
@ -342,7 +325,6 @@ describe('when it receives a message of type...', () => {
describe('DISPATCH and payload of type...', () => {
it('RESET, it inits with initial state', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0 }
const api = createStore(devtools(() => initialState, { enabled: true }))
api.setState({ count: 1 })
@ -361,7 +343,6 @@ describe('when it receives a message of type...', () => {
})
it('COMMIT, it inits with current state', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0 }
const api = createStore(devtools(() => initialState, { enabled: true }))
api.setState({ count: 2 })
@ -381,7 +362,6 @@ describe('when it receives a message of type...', () => {
describe('ROLLBACK...', () => {
it('it updates state without recording and inits with `message.state`', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0, increment: () => {} }
const api = createStore(devtools(() => initialState, { enabled: true }))
const newState = { foo: 'bar' }
@ -404,7 +384,6 @@ describe('when it receives a message of type...', () => {
})
it('does not throw for unparsable `message.state`', async () => {
const { devtools, createStore } = await getImports()
const increment = () => {}
const initialState = { count: 0, increment }
const api = createStore(devtools(() => initialState, { enabled: true }))
@ -442,7 +421,6 @@ describe('when it receives a message of type...', () => {
describe('JUMP_TO_STATE...', () => {
const increment = () => {}
it('it updates state without recording with `message.state`', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0, increment }
const api = createStore(devtools(() => initialState, { enabled: true }))
const newState = { foo: 'bar' }
@ -460,7 +438,6 @@ describe('when it receives a message of type...', () => {
})
it('does not throw for unparsable `message.state`', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0, increment: () => {} }
const api = createStore(devtools(() => initialState, { enabled: true }))
const originalConsoleError = console.error
@ -494,7 +471,6 @@ describe('when it receives a message of type...', () => {
describe('JUMP_TO_ACTION...', () => {
it('it updates state without recording with `message.state`', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0, increment: () => {} }
const api = createStore(devtools(() => initialState, { enabled: true }))
const newState = { foo: 'bar' }
@ -512,7 +488,6 @@ describe('when it receives a message of type...', () => {
})
it('does not throw for unparsable `message.state`', async () => {
const { devtools, createStore } = await getImports()
const increment = () => {}
const initialState = { count: 0, increment }
const api = createStore(devtools(() => initialState, { enabled: true }))
@ -546,7 +521,6 @@ describe('when it receives a message of type...', () => {
})
it('IMPORT_STATE, it updates state without recording and inits the last computedState', async () => {
const { devtools, createStore } = await getImports()
const initialState = { count: 0, increment: () => {} }
const api = createStore(devtools(() => initialState, { enabled: true }))
const nextLiftedState = {
@ -571,7 +545,6 @@ describe('when it receives a message of type...', () => {
})
it('PAUSE_RECORDING, it toggles the sending of actions', async () => {
const { devtools, createStore } = await getImports()
const api = createStore(devtools(() => ({ count: 0 }), { enabled: true }))
api.setState({ count: 1 }, false, 'increment')
@ -614,8 +587,6 @@ describe('with redux middleware', () => {
}>
it('works as expected', async () => {
const { devtools, redux } = await import('zustand/middleware')
const { createStore } = await import('zustand/vanilla')
api = createStore(
devtools(
redux(
@ -673,7 +644,6 @@ describe('with redux middleware', () => {
})
it('works in non-browser env', async () => {
const { devtools, createStore } = await getImports()
const originalWindow = global.window
global.window = undefined as any
@ -685,7 +655,6 @@ it('works in non-browser env', async () => {
})
it('works in react native env', async () => {
const { devtools, createStore } = await getImports()
const originalWindow = global.window
global.window = {} as any
@ -697,7 +666,6 @@ it('works in react native env', async () => {
})
it('preserves isRecording after setting from devtools', async () => {
const { devtools, createStore } = await getImports()
const api = createStore(devtools(() => ({ count: 0 }), { enabled: true }))
const [connection] = getNamedConnectionApis(undefined)
const [connectionSubscriber] = getNamedConnectionSubscribers(undefined)
@ -729,7 +697,6 @@ it('preserves isRecording after setting from devtools', async () => {
describe('when redux connection was called on multiple stores with `name` undefined in `devtools` options', () => {
it('should create separate connection for each devtools store with .connect call', async () => {
const { devtools, createStore } = await getImports()
const options1 = { foo: 'bar', testConnectionId: 'asdf' }
const options2 = { foo: 'barr', testConnectionId: '123asd' }
const initialState1 = { count: 0 }
@ -743,7 +710,6 @@ describe('when redux connection was called on multiple stores with `name` undefi
})
it('should call .init on each different connection object', async () => {
const { devtools, createStore } = await getImports()
const options1 = { foo: 'bar', testConnectionId: 'asdf' }
const options2 = { foo: 'barr', testConnectionId: '123asd' }
const initialState1 = { count: 0 }
@ -761,15 +727,22 @@ describe('when redux connection was called on multiple stores with `name` undefi
})
describe('when `store` property was provided in `devtools` call in options', () => {
it('should create single connection for all indernal calls of .connect and `store` is not passed to .connect', async () => {
const { devtools, createStore } = await getImports()
// FIXME: Run this test separately in CI, until we're able to test modules in isolation i.e. use jest.resetModule and re-import modules in each test
// Relevant issues https://github.com/nodejs/node/issues/35889
it('[CI-MATRIX-1] should create single connection for all indernal calls of .connect and `store` is not passed to .connect', async () => {
const { devtools: newDevtools } = await import('zustand/middleware')
const options1 = { store: 'store1123', foo: 'bar1' }
const options2 = { store: 'store2313132', foo: 'bar2' }
const initialState1 = { count: 0 }
const initialState2 = { count1: 1 }
createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
createStore(
newDevtools(() => initialState1, { enabled: true, ...options1 })
)
createStore(
newDevtools(() => initialState2, { enabled: true, ...options2 })
)
expect(extensionConnector.connect).toHaveBeenCalledTimes(1)
expect(extensionConnector.connect).toHaveBeenCalledWith({
@ -777,15 +750,22 @@ describe('when redux connection was called on multiple stores with `name` undefi
})
})
it('should call `.init` on single connection with combined states after each `create(devtools` call', async () => {
const { devtools, createStore } = await getImports()
// FIXME: Run this test separately in CI, until we're able to test modules in isolation i.e. use jest.resetModule and re-import modules in each test
// Relevant issues https://github.com/nodejs/node/issues/35889
it('[CI-MATRIX-2] should call `.init` on single connection with combined states after each `create(devtools` call', async () => {
const { devtools: newDevtools } = await import('zustand/middleware')
const options1 = { store: 'store12' }
const options2 = { store: 'store21' }
const initialState1 = { count1: 0 }
const initialState2 = { count2: 1 }
createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
createStore(
newDevtools(() => initialState1, { enabled: true, ...options1 })
)
createStore(
newDevtools(() => initialState2, { enabled: true, ...options2 })
)
expect(extensionConnector.connect).toHaveBeenCalledTimes(1)
const [connection] = getNamedConnectionApis(undefined)
@ -804,7 +784,6 @@ describe('when redux connection was called on multiple stores with `name` undefi
describe('when redux connection was called on multiple stores with `name` provided in `devtools` options', () => {
describe('when same `name` is provided to all stores in devtools options', () => {
it('should call .connect of redux extension with `name` that was passed from `devtools` options', async () => {
const { devtools, createStore } = await getImports()
const connectionName = 'test'
const options1 = { name: connectionName, store: 'store1123', foo: 'bar1' }
const options2 = { name: connectionName, store: 'store1414', foo: 'bar1' }
@ -824,7 +803,6 @@ describe('when redux connection was called on multiple stores with `name` provid
describe('when different `name` props were provided for different group of stores in devtools options', () => {
it('should call .connect of redux extension with `name` that was passed from `devtools` options', async () => {
const { devtools, createStore } = await getImports()
const connectionNameGroup1 = 'test1'
const connectionNameGroup2 = 'test2'
const options1 = {
@ -868,8 +846,10 @@ describe('when redux connection was called on multiple stores with `name` provid
})
})
it('should call `.init` on single connection with combined states after each `create(devtools` call', async () => {
const { devtools, createStore } = await getImports()
// FIXME: Run this test separately in CI, until we're able to test modules in isolation i.e. use jest.resetModule and re-import modules in each test
// Relevant issues https://github.com/nodejs/node/issues/35889
it('[CI-MATRIX-3] should call `.init` on single connection with combined states after each `create(devtools` call', async () => {
const { devtools: newDevtools } = await import('zustand/middleware')
const connectionNameGroup1 = 'test1'
const connectionNameGroup2 = 'test2'
const options1 = {
@ -897,10 +877,18 @@ describe('when redux connection was called on multiple stores with `name` provid
const initialState3 = { count: 5 }
const initialState4 = { count: 7 }
createStore(devtools(() => initialState1, { enabled: true, ...options1 }))
createStore(devtools(() => initialState2, { enabled: true, ...options2 }))
createStore(devtools(() => initialState3, { enabled: true, ...options3 }))
createStore(devtools(() => initialState4, { enabled: true, ...options4 }))
createStore(
newDevtools(() => initialState1, { enabled: true, ...options1 })
)
createStore(
newDevtools(() => initialState2, { enabled: true, ...options2 })
)
createStore(
newDevtools(() => initialState3, { enabled: true, ...options3 })
)
createStore(
newDevtools(() => initialState4, { enabled: true, ...options4 })
)
expect(extensionConnector.connect).toHaveBeenCalledTimes(2)
const [connection1, connection2] = getNamedConnectionApis(
@ -926,7 +914,6 @@ describe('when redux connection was called on multiple stores with `name` provid
})
it('preserves isRecording after setting from devtools on proper connection subscriber', async () => {
const { devtools, createStore } = await getImports()
const options1 = { name: 'asdf1' }
const options2 = { name: 'asdf2' }
const api1 = createStore(
@ -967,8 +954,6 @@ describe('when redux connection was called on multiple stores with `name` provid
}>
it('works as expected', async () => {
const { devtools, redux } = await import('zustand/middleware')
const { createStore } = await import('zustand/vanilla')
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
api1 = createStore(
@ -1065,7 +1050,6 @@ describe('when redux connection was called on multiple stores with `name` provid
describe('when create devtools was called multiple times with `name` option undefined', () => {
describe('When state changes...', () => {
it("sends { type: setStateName || 'anonymous`, ...rest } as the action with current state, isolated from other connections", async () => {
const { devtools, createStore } = await getImports()
const options1 = {
enabled: true,
testConnectionId: '123',
@ -1121,7 +1105,6 @@ describe('when create devtools was called multiple times with `name` option unde
describe('when it receives a message of type...', () => {
describe('ACTION...', () => {
it('does nothing, connections isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: '123' }
const options2 = { testConnectionId: '231' }
const options3 = { testConnectionId: '4342' }
@ -1167,7 +1150,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('unless action type is __setState, connections isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1198,7 +1180,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('does nothing even if there is `api.dispatch`, connections isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1244,7 +1225,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1299,7 +1279,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('does not throw for unsupported payload, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1437,7 +1416,6 @@ describe('when create devtools was called multiple times with `name` option unde
describe('DISPATCH and payload of type...', () => {
it('RESET, it inits with initial state, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1485,7 +1463,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('COMMIT, it inits with current state, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1535,7 +1512,6 @@ describe('when create devtools was called multiple times with `name` option unde
describe('ROLLBACK...', () => {
it('it updates state without recording and inits with `message.state, connections are isolated from each other`', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1615,7 +1591,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('does not throw for unparsable `message.state`, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const increment1 = () => {}
const increment2 = () => {}
const increment3 = () => {}
@ -1717,7 +1692,6 @@ describe('when create devtools was called multiple times with `name` option unde
const increment3 = () => {}
it('it updates state without recording with `message.state`, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1784,7 +1758,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('does not throw for unparsable `message.state`, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1880,7 +1853,6 @@ describe('when create devtools was called multiple times with `name` option unde
const increment3 = () => {}
it('it updates state without recording with `message.state`, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -1948,7 +1920,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('does not throw for unparsable `message.state`, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -2037,7 +2008,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('IMPORT_STATE, it updates state without recording and inits the last computedState, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -2129,7 +2099,6 @@ describe('when create devtools was called multiple times with `name` option unde
})
it('PAUSE_RECORDING, it toggles the sending of actions, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: 'asdf' }
const options2 = { testConnectionId: '2f' }
const options3 = { testConnectionId: 'd2e' }
@ -2243,7 +2212,6 @@ describe('when create devtools was called multiple times with `name` and `store`
describe('when `type` was provided in store state methods as option', () => {
describe('When state changes...', () => {
it("sends { type: setStateName || 'anonymous`, ...rest } as the action with current state", async () => {
const { devtools, createStore } = await getImports()
const options = {
name: 'testOptionsName',
store: 'someStore',
@ -2282,7 +2250,6 @@ describe('when create devtools was called multiple times with `name` and `store`
describe('when it receives a message of type...', () => {
describe('ACTION...', () => {
it('does nothing, connections isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const options1 = { testConnectionId: '123', store: 'store1' }
const options2 = { testConnectionId: '231', store: 'store2' }
const initialState1 = { count: 0 }
@ -2337,7 +2304,6 @@ describe('when create devtools was called multiple times with `name` and `store`
})
it('unless action type is __setState, connections isolated from each other', async () => {
const { devtools, createStore } = await getImports()
const name1 = 'name1'
const name2 = 'name2'
const store1 = 'someStore1'
@ -2393,8 +2359,11 @@ describe('when create devtools was called multiple times with `name` and `store`
console.error = originalConsoleError
})
it('does nothing even if there is `api.dispatch`, connections isolated from each other', async () => {
const { devtools, createStore } = await getImports()
// FIXME: Run this test separately in CI, until we're able to test modules in isolation i.e. use jest.resetModule and re-import modules in each test
// Relevant issues https://github.com/nodejs/node/issues/35889
it('[CI-MATRIX-4] does nothing even if there is `api.dispatch`, connections isolated from each other', async () => {
const { devtools: newDevtools } = await import('zustand/middleware')
const name1 = 'name1'
const name2 = 'name2'
const store1 = 'someStore1'
@ -2412,10 +2381,10 @@ describe('when create devtools was called multiple times with `name` and `store`
const initialState1 = { count: 0 }
const initialState2 = { count: 2 }
const api1 = createStore(
devtools(() => initialState1, { enabled: true, ...options1 })
newDevtools(() => initialState1, { enabled: true, ...options1 })
)
const api2 = createStore(
devtools(() => initialState2, { enabled: true, ...options2 })
newDevtools(() => initialState2, { enabled: true, ...options2 })
)
;(api1 as any).dispatch = jest.fn()
;(api2 as any).dispatch = jest.fn()
@ -2440,8 +2409,10 @@ describe('when create devtools was called multiple times with `name` and `store`
expect((api2 as any).dispatch).not.toBeCalled()
})
it('dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true, connections are isolated from each other', async () => {
const { devtools, createStore } = await getImports()
// FIXME: Run this test separately in CI, until we're able to test modules in isolation i.e. use jest.resetModule and re-import modules in each test
// Relevant issues https://github.com/nodejs/node/issues/35889
it('[CI-MATRIX-5] dispatches with `api.dispatch` when `api.dispatchFromDevtools` is set to true, connections are isolated from each other', async () => {
const { devtools: newDevtools } = await import('zustand/middleware')
const name1 = 'name1'
const name2 = 'name2'
const store1 = 'someStore1'
@ -2459,10 +2430,10 @@ describe('when create devtools was called multiple times with `name` and `store`
const initialState1 = { count: 0 }
const initialState2 = { count: 2 }
const api1 = createStore(
devtools(() => initialState1, { enabled: true, ...options1 })
newDevtools(() => initialState1, { enabled: true, ...options1 })
)
const api2 = createStore(
devtools(() => initialState2, { enabled: true, ...options2 })
newDevtools(() => initialState2, { enabled: true, ...options2 })
)
;(api1 as any).dispatch = jest.fn()
;(api1 as any).dispatchFromDevtools = true

View File

@ -1,11 +1,13 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "react-jsx",
"esModuleInterop": true,
"moduleResolution": "node",
"module": "esnext",
"moduleResolution": "nodenext",
"skipLibCheck": true /* FIXME remove this once redux fixes it */,
"allowImportingTsExtensions": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"baseUrl": ".",