From 0ca42c7d42731fff23be146986fd408cb9c25df8 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Fri, 18 Jun 2021 09:22:35 -0700 Subject: [PATCH 1/6] redux-routine: Add types --- packages/redux-routine/README.md | 4 +-- packages/redux-routine/src/index.js | 4 +-- packages/redux-routine/src/is-action.js | 12 ++++---- packages/redux-routine/src/is-generator.js | 6 ++-- packages/redux-routine/src/rungen.d.ts | 17 +++++++++++ .../src/{runtime.js => runtime.ts} | 30 ++++++++++++------- packages/redux-routine/tsconfig.json | 9 ++++++ 7 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 packages/redux-routine/src/rungen.d.ts rename packages/redux-routine/src/{runtime.js => runtime.ts} (65%) create mode 100644 packages/redux-routine/tsconfig.json diff --git a/packages/redux-routine/README.md b/packages/redux-routine/README.md index 067ae8fb331cb2..0116434c65694c 100644 --- a/packages/redux-routine/README.md +++ b/packages/redux-routine/README.md @@ -70,11 +70,11 @@ execution is not continued. _Parameters_ -- _controls_ `Object`: Object of control handlers. +- _controls_ `Record Promise | boolean>`: Object of control handlers. _Returns_ -- `Function`: Co-routine runtime +- `(store: { dispatch: import('redux').Dispatch }) => (next: (action: import('redux').AnyAction) => Promise) => (action: import('redux').AnyAction) => Promise`: Co-routine runtime diff --git a/packages/redux-routine/src/index.js b/packages/redux-routine/src/index.js index 99414dc56627bb..bbf7286d05f04a 100644 --- a/packages/redux-routine/src/index.js +++ b/packages/redux-routine/src/index.js @@ -12,9 +12,9 @@ import createRuntime from './runtime'; * value of the yield assignment. If the control handler returns undefined, the * execution is not continued. * - * @param {Object} controls Object of control handlers. + * @param {Record Promise | boolean>} controls Object of control handlers. * - * @return {Function} Co-routine runtime + * @return {(store: { dispatch: import('redux').Dispatch }) => (next: (action: import('redux').AnyAction) => Promise) => (action: import('redux').AnyAction) => Promise} Co-routine runtime */ export default function createMiddleware( controls = {} ) { return ( store ) => { diff --git a/packages/redux-routine/src/is-action.js b/packages/redux-routine/src/is-action.js index 152119d001fe29..f9a430b8b8f9a5 100644 --- a/packages/redux-routine/src/is-action.js +++ b/packages/redux-routine/src/is-action.js @@ -3,12 +3,13 @@ */ import { isPlainObject, isString } from 'lodash'; +/* eslint-disable jsdoc/valid-types */ /** * Returns true if the given object quacks like an action. * - * @param {*} object Object to test + * @param {any} object Object to test * - * @return {boolean} Whether object is an action. + * @return {object is import('redux').AnyAction} Whether object is an action. */ export function isAction( object ) { return isPlainObject( object ) && isString( object.type ); @@ -18,11 +19,12 @@ export function isAction( object ) { * Returns true if the given object quacks like an action and has a specific * action type * - * @param {*} object Object to test - * @param {string} expectedType The expected type for the action. + * @param {unknown} object Object to test + * @param {string} expectedType The expected type for the action. * - * @return {boolean} Whether object is an action and is of specific type. + * @return {object is import('redux').AnyAction} Whether object is an action and is of specific type. */ export function isActionOfType( object, expectedType ) { + /* eslint-enable jsdoc/valid-types */ return isAction( object ) && object.type === expectedType; } diff --git a/packages/redux-routine/src/is-generator.js b/packages/redux-routine/src/is-generator.js index 952d267ed4b061..414fc3f9dc17c3 100644 --- a/packages/redux-routine/src/is-generator.js +++ b/packages/redux-routine/src/is-generator.js @@ -1,13 +1,15 @@ +/* eslint-disable jsdoc/valid-types */ /** * Returns true if the given object is a generator, or false otherwise. * * @see https://www.ecma-international.org/ecma-262/6.0/#sec-generator-objects * - * @param {*} object Object to test. + * @param {any} object Object to test. * - * @return {boolean} Whether object is a generator. + * @return {object is Generator} Whether object is a generator. */ export default function isGenerator( object ) { + /* eslint-enable jsdoc/valid-types */ // Check that iterator (next) and iterable (Symbol.iterator) interfaces are satisfied. // These checks seem to be compatible with several generator helpers as well as the native implementation. return ( diff --git a/packages/redux-routine/src/rungen.d.ts b/packages/redux-routine/src/rungen.d.ts new file mode 100644 index 00000000000000..0d2c93ae3d6b5e --- /dev/null +++ b/packages/redux-routine/src/rungen.d.ts @@ -0,0 +1,17 @@ +declare module 'rungen' { + type Control = ( + value: any, + next: any, + iterate: any, + yieldNext: ( result: boolean ) => void, + yieldError: ( err: Error ) => void + ) => Promise< boolean > | boolean; + + function create( + ...args: any[] + ): ( + action: any, + successCallback: ( result: any ) => void, + errorCallaback: () => void + ) => void; +} diff --git a/packages/redux-routine/src/runtime.js b/packages/redux-routine/src/runtime.ts similarity index 65% rename from packages/redux-routine/src/runtime.js rename to packages/redux-routine/src/runtime.ts index 1148ea1af5ccdd..05eb3a52f18124 100644 --- a/packages/redux-routine/src/runtime.js +++ b/packages/redux-routine/src/runtime.ts @@ -2,8 +2,11 @@ * External dependencies */ import { create } from 'rungen'; +// eslint-disable-next-line no-duplicate-imports +import type { Control } from 'rungen'; import { map } from 'lodash'; import isPromise from 'is-promise'; +import type { Dispatch, AnyAction } from 'redux'; /** * Internal dependencies @@ -13,18 +16,22 @@ import { isActionOfType, isAction } from './is-action'; /** * Create a co-routine runtime. * - * @param {Object} controls Object of control handlers. - * @param {Function} dispatch Unhandled action dispatch. - * - * @return {Function} co-routine runtime + * @param controls Object of control handlers. + * @param dispatch Unhandled action dispatch. */ -export default function createRuntime( controls = {}, dispatch ) { +export default function createRuntime( + controls: Record< + string, + ( value: any ) => Promise< boolean > | boolean + > = {}, + dispatch: Dispatch +) { const rungenControls = map( controls, - ( control, actionType ) => ( + ( control, actionType ): Control => ( value, - next, - iterate, + _, + __, yieldNext, yieldError ) => { @@ -42,7 +49,10 @@ export default function createRuntime( controls = {}, dispatch ) { } ); - const unhandledActionControl = ( value, next ) => { + const unhandledActionControl = ( + value: AnyAction | unknown, + next: () => void + ) => { if ( ! isAction( value ) ) { return false; } @@ -54,7 +64,7 @@ export default function createRuntime( controls = {}, dispatch ) { const rungenRuntime = create( rungenControls ); - return ( action ) => + return ( action: AnyAction | Generator ) => new Promise( ( resolve, reject ) => rungenRuntime( action, diff --git a/packages/redux-routine/tsconfig.json b/packages/redux-routine/tsconfig.json new file mode 100644 index 00000000000000..f108b30216124f --- /dev/null +++ b/packages/redux-routine/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "declarationDir": "build-types", + "noUnusedParameters": false + }, + "include": [ "src/**/*" ] +} From e6eb8ae4fa0d0a6565c10ff9d7de80ee9532f0e1 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Mon, 21 Jun 2021 06:58:13 -0700 Subject: [PATCH 2/6] Various fixes --- package-lock.json | 1 + packages/redux-routine/CHANGELOG.md | 4 ++++ packages/redux-routine/README.md | 4 ++-- packages/redux-routine/package.json | 2 ++ packages/redux-routine/src/index.js | 4 ++-- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9e25be4310a5be..1a46b5c62e7a80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14610,6 +14610,7 @@ "@babel/runtime": "^7.13.10", "is-promise": "^4.0.0", "lodash": "^4.17.21", + "redux": "^4.1.0", "rungen": "^0.3.2" } }, diff --git a/packages/redux-routine/CHANGELOG.md b/packages/redux-routine/CHANGELOG.md index bf149958f0a098..18f38c6079938e 100644 --- a/packages/redux-routine/CHANGELOG.md +++ b/packages/redux-routine/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### New Features + +- Added and published TypeScript annotations + ## 4.1.0 (2021-05-20) ## 4.0.0 (2021-05-14) diff --git a/packages/redux-routine/README.md b/packages/redux-routine/README.md index 0116434c65694c..2a4f428461ae09 100644 --- a/packages/redux-routine/README.md +++ b/packages/redux-routine/README.md @@ -70,11 +70,11 @@ execution is not continued. _Parameters_ -- _controls_ `Record Promise | boolean>`: Object of control handlers. +- _controls_ `Record Promise | boolean>`: Object of control handlers. _Returns_ -- `(store: { dispatch: import('redux').Dispatch }) => (next: (action: import('redux').AnyAction) => Promise) => (action: import('redux').AnyAction) => Promise`: Co-routine runtime +- `import('redux').Middleware`: Co-routine runtime diff --git a/packages/redux-routine/package.json b/packages/redux-routine/package.json index 6caa9ce2e5c9b4..7cc921fdc1d315 100644 --- a/packages/redux-routine/package.json +++ b/packages/redux-routine/package.json @@ -26,11 +26,13 @@ "main": "build/index.js", "module": "build-module/index.js", "react-native": "src/index", + "types": "build-types", "sideEffects": false, "dependencies": { "@babel/runtime": "^7.13.10", "is-promise": "^4.0.0", "lodash": "^4.17.21", + "redux": "^4.1.0", "rungen": "^0.3.2" }, "publishConfig": { diff --git a/packages/redux-routine/src/index.js b/packages/redux-routine/src/index.js index bbf7286d05f04a..cd7101a61d99bf 100644 --- a/packages/redux-routine/src/index.js +++ b/packages/redux-routine/src/index.js @@ -12,9 +12,9 @@ import createRuntime from './runtime'; * value of the yield assignment. If the control handler returns undefined, the * execution is not continued. * - * @param {Record Promise | boolean>} controls Object of control handlers. + * @param {Record Promise | boolean>} controls Object of control handlers. * - * @return {(store: { dispatch: import('redux').Dispatch }) => (next: (action: import('redux').AnyAction) => Promise) => (action: import('redux').AnyAction) => Promise} Co-routine runtime + * @return {import('redux').Middleware} Co-routine runtime */ export default function createMiddleware( controls = {} ) { return ( store ) => { From b3b7f17e4a30ba844e1112781711cf07f0da1bed Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Tue, 22 Jun 2021 06:06:46 -0700 Subject: [PATCH 3/6] Put back unused parameter names --- packages/redux-routine/src/runtime.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/redux-routine/src/runtime.ts b/packages/redux-routine/src/runtime.ts index 05eb3a52f18124..f8d326a1a8d8e2 100644 --- a/packages/redux-routine/src/runtime.ts +++ b/packages/redux-routine/src/runtime.ts @@ -30,8 +30,8 @@ export default function createRuntime( controls, ( control, actionType ): Control => ( value, - _, - __, + next, + iterate, yieldNext, yieldError ) => { From fd2457bafd34ca7958c913744239c034360a32ab Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Tue, 22 Jun 2021 06:07:30 -0700 Subject: [PATCH 4/6] Deduplicate rungen import --- packages/redux-routine/src/runtime.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/redux-routine/src/runtime.ts b/packages/redux-routine/src/runtime.ts index f8d326a1a8d8e2..3f88a56c6a4f38 100644 --- a/packages/redux-routine/src/runtime.ts +++ b/packages/redux-routine/src/runtime.ts @@ -1,9 +1,7 @@ /** * External dependencies */ -import { create } from 'rungen'; -// eslint-disable-next-line no-duplicate-imports -import type { Control } from 'rungen'; +import { create, Control } from 'rungen'; import { map } from 'lodash'; import isPromise from 'is-promise'; import type { Dispatch, AnyAction } from 'redux'; From 2b21f859560b1c5059da220c05d10ca262cfe20e Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Wed, 23 Jun 2021 14:10:57 -0700 Subject: [PATCH 5/6] Add redux-routine to data --- packages/data/tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/data/tsconfig.json b/packages/data/tsconfig.json index 574fdc56223364..471410eceef0fe 100644 --- a/packages/data/tsconfig.json +++ b/packages/data/tsconfig.json @@ -11,8 +11,7 @@ { "path": "../element" }, { "path": "../is-shallow-equal" }, { "path": "../priority-queue" }, - // Needs to be added once it is typed - // { "path": "../redux-routine" } + { "path": "../redux-routine" } ], "include": [ "src/redux-store/metadata/actions.js" From 38d80171a1c520d47648549fe725c5ce3365f8b3 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Thu, 24 Jun 2021 06:09:39 -0700 Subject: [PATCH 6/6] Move redux to a peerDependency --- package-lock.json | 1 - packages/data/package.json | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1a46b5c62e7a80..b23f5fbad982cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13881,7 +13881,6 @@ "is-promise": "^4.0.0", "lodash": "^4.17.21", "memize": "^1.1.0", - "redux": "^4.1.0", "turbo-combine-reducers": "^1.0.2", "use-memo-one": "^1.1.1" } diff --git a/packages/data/package.json b/packages/data/package.json index f54851feaf6fd9..4799899d676666 100644 --- a/packages/data/package.json +++ b/packages/data/package.json @@ -38,10 +38,12 @@ "is-promise": "^4.0.0", "lodash": "^4.17.21", "memize": "^1.1.0", - "redux": "^4.1.0", "turbo-combine-reducers": "^1.0.2", "use-memo-one": "^1.1.1" }, + "peerDependencies": { + "redux": "^4.1.0" + }, "publishConfig": { "access": "public" }