From 921393c81c5d0869f1f28657e062a4abedfb51c1 Mon Sep 17 00:00:00 2001 From: Viktor Pasynok Date: Thu, 6 Nov 2025 14:24:54 +0700 Subject: [PATCH 1/4] Update Payload type to use ReactNode instead of React.JSX.Element for Component props, enhancing type compatibility in TypeScript. Closes #10 --- src/payload.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/payload.ts b/src/payload.ts index f03c7d6..45e7e10 100644 --- a/src/payload.ts +++ b/src/payload.ts @@ -1,4 +1,5 @@ import type { Event, EventPayload } from 'effector'; +import type { ReactNode } from 'react'; import type { EmptyObject } from './helpers'; type ExtractWhenPayload = T extends Event ? P : T extends Event[] ? EventPayload : never; @@ -6,7 +7,7 @@ type ExtractWhenPayload = T extends Event ? P : T extends Event type Payload = { // When mapProps is provided with when | Event[]>(params: { - Component: (props: unknown extends R ? EmptyObject : R extends void ? EmptyObject : R) => React.JSX.Element; + Component: (props: unknown extends R ? EmptyObject : R extends void ? EmptyObject : R) => ReactNode; mapProps: (arg: T, whenPayload: ExtractWhenPayload) => R; order?: number; when: W; @@ -14,7 +15,7 @@ type Payload = { // When mapProps is provided without when (params: { - Component: (props: unknown extends R ? EmptyObject : R extends void ? EmptyObject : R) => React.JSX.Element; + Component: (props: unknown extends R ? EmptyObject : R extends void ? EmptyObject : R) => ReactNode; mapProps: (arg: T) => R; order?: number; when?: undefined; @@ -22,7 +23,7 @@ type Payload = { // When mapProps is not provided (params: { - Component: (props: unknown extends T ? EmptyObject : T extends void ? EmptyObject : T) => React.JSX.Element; + Component: (props: unknown extends T ? EmptyObject : T extends void ? EmptyObject : T) => ReactNode; mapProps?: undefined; order?: number; when?: undefined; From 2940d0709423a9a1053b107c8c1ea2e7d0ef3794 Mon Sep 17 00:00:00 2001 From: Viktor Pasynok Date: Thu, 6 Nov 2025 15:13:45 +0700 Subject: [PATCH 2/4] changed: try to fix type inference --- sandbox.tsx | 2 +- src/__tests__/payload.spec-d.tsx | 42 +++++++++++++++++++++++++++----- src/payload.ts | 8 +++--- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/sandbox.tsx b/sandbox.tsx index 4f5a52f..dd06437 100644 --- a/sandbox.tsx +++ b/sandbox.tsx @@ -4,7 +4,7 @@ import { createSlotIdentifier, createSlots } from './src'; const { slotsApi } = createSlots({ ConfirmScreenBottom: createSlotIdentifier<{ id: number }>(), -} as const); +}); const appGate = createGate(); diff --git a/src/__tests__/payload.spec-d.tsx b/src/__tests__/payload.spec-d.tsx index 002fd6a..d8f2097 100644 --- a/src/__tests__/payload.spec-d.tsx +++ b/src/__tests__/payload.spec-d.tsx @@ -1,12 +1,13 @@ -import { createEvent } from 'effector'; +import { createEffect, createEvent, createStore, UnitValue } from 'effector'; import React from 'react'; import { expectTypeOf } from 'vitest'; import { EmptyObject } from '../helpers'; import { createSlotIdentifier, createSlots } from '../index'; +import { ExtractWhenPayload } from '../payload'; const slotWithProps = createSlotIdentifier<{ text: string }>(); const noPropsSlot = createSlotIdentifier(); -const signal = createEvent(); +const triggerEvent = createEvent(); const { slotsApi } = createSlots({ Top: slotWithProps, @@ -22,7 +23,7 @@ slotsApi.Top.insert({ }); slotsApi.Top.insert({ - when: signal, + when: triggerEvent, mapProps: (__, signalPayload) => ({ text: String(signalPayload) }), Component: (props) => { expectTypeOf<{ text: string }>(props); @@ -31,7 +32,7 @@ slotsApi.Top.insert({ }); slotsApi.Top.insert({ - when: [signal], + when: [triggerEvent], mapProps: (__, signalPayload) => ({ text: String(signalPayload) }), Component: (props) => { expectTypeOf<{ text: string }>(props); @@ -40,7 +41,7 @@ slotsApi.Top.insert({ }); slotsApi.Top.insert({ - when: [signal, createEvent()], + when: [triggerEvent, createEvent()], mapProps: (__, signalPayload) => { const text = Array.isArray(signalPayload) ? signalPayload[0] : String(signalPayload); @@ -72,7 +73,7 @@ slotsApi.Top.insert({ }); slotsApi.Top.insert({ - when: signal, + when: triggerEvent, mapProps: (slotPayload, signalPayload) => ({ data: { signalPayload, slotPayload } }), Component: (props) => { expectTypeOf<{ @@ -82,8 +83,37 @@ slotsApi.Top.insert({ }, }); +slotsApi.Top.insert({ + when: [createEvent(), createStore(''), createEffect((x: string[]) => x)], + mapProps: (__, signalPayload) => { + return null; + }, + Component: () => '', +}); + +slotsApi.Top.insert({ + when: [createEvent(), createStore(''), createEffect((x: null) => x)], + mapProps: (__, signalPayload) => { + return null; + }, + Component: () => '', +}); + +slotsApi.Top.insert({ + when: [createEvent(), createEffect((x: string) => x)], + mapProps: (__, signalPayload) => { + return ''; + }, + Component: () => '', +}); + slotsApi.Top.insert({ mapProps: (data) => ({ text: data.text }), // @ts-expect-error Component: (_: { wrong: number }) =>
, }); + + +const $a = createEffect((x: string) => x) +const list = [$a] +type N = ExtractWhenPayload diff --git a/src/payload.ts b/src/payload.ts index 45e7e10..22b6808 100644 --- a/src/payload.ts +++ b/src/payload.ts @@ -1,12 +1,12 @@ -import type { Event, EventPayload } from 'effector'; +import type { Unit, UnitValue } from 'effector'; import type { ReactNode } from 'react'; import type { EmptyObject } from './helpers'; -type ExtractWhenPayload = T extends Event ? P : T extends Event[] ? EventPayload : never; +type ExtractWhenPayload = T extends Unit ? P : T extends Unit[] ? UnitValue : never; type Payload = { // When mapProps is provided with when - | Event[]>(params: { + | Unit[]>(params: { Component: (props: unknown extends R ? EmptyObject : R extends void ? EmptyObject : R) => ReactNode; mapProps: (arg: T, whenPayload: ExtractWhenPayload) => R; order?: number; @@ -30,4 +30,4 @@ type Payload = { }): void; }; -export type { Payload }; +export type { ExtractWhenPayload, Payload }; From 41afed3113ba12f8139f65ea161ee0c5965f59a4 Mon Sep 17 00:00:00 2001 From: Viktor Pasynok Date: Thu, 6 Nov 2025 16:04:33 +0700 Subject: [PATCH 3/4] Update dependencies and enhance type inference in payload handling. Closes #11 --- package-lock.json | 148 +++++++++++---------- package.json | 3 +- src/__tests__/extractWhenPayload.spec-d.ts | 43 ++++++ src/__tests__/payload.spec-d.tsx | 35 +++-- src/payload.ts | 4 +- 5 files changed, 150 insertions(+), 83 deletions(-) create mode 100644 src/__tests__/extractWhenPayload.spec-d.ts diff --git a/package-lock.json b/package-lock.json index 0c946cf..e47ccd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,11 @@ "version": "3.0.1", "license": "MIT", "devDependencies": { - "@rslib/core": "0.17.0", + "@rslib/core": "0.17.1", "@size-limit/preset-small-lib": "11.2.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "clean-publish": "6.0.1", + "patronum": "2.3.0", "prettier": "3.6.2", "prettier-plugin-organize-imports": "4.3.0", "size-limit": "11.2.0", @@ -1065,13 +1066,13 @@ ] }, "node_modules/@rsbuild/core": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.6.1.tgz", - "integrity": "sha512-zC5Pinm5MpQwlSMQosGgrtXH8zuoHSuxNbnzY702NUYImWDagqmFaUnB5dp5vQRPgYV/5p5hCtz88jUguX0jgQ==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.6.2.tgz", + "integrity": "sha512-ELlc23tDCYaXCwB//bOIF/Gnx1TtFey/DBgFDD/oN6PK7aKpAGIVSk6n9aHH3GRNXNtG/sLFtjucVm7Le3lvCA==", "dev": true, "license": "MIT", "dependencies": { - "@rspack/core": "1.6.0", + "@rspack/core": "1.6.1", "@rspack/lite-tapable": "~1.0.1", "@swc/helpers": "^0.5.17", "core-js": "~3.46.0", @@ -1085,14 +1086,14 @@ } }, "node_modules/@rslib/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@rslib/core/-/core-0.17.0.tgz", - "integrity": "sha512-8oQTnyxeqHB0vFJf8eihxsvpizSdwFOhuEYHWPLjGNvGxvlujt6nhzms6UeopLvtYh7ZMZAzSj0hAIlc/G1u6w==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@rslib/core/-/core-0.17.1.tgz", + "integrity": "sha512-7mqrktQuHMkGcgIW6pBdw7xpBy5KmvTN22+RhSkj1y4FKfen/PqOPDGqGlN+kTbPSXs20kBepNkYWYV8t+6ryA==", "dev": true, "license": "MIT", "dependencies": { - "@rsbuild/core": "~1.6.0", - "rsbuild-plugin-dts": "0.17.0" + "@rsbuild/core": "~1.6.2", + "rsbuild-plugin-dts": "0.17.1" }, "bin": { "rslib": "bin/rslib.js" @@ -1114,28 +1115,28 @@ } }, "node_modules/@rspack/binding": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.6.0.tgz", - "integrity": "sha512-RqlCjvWg/LkJjHpsbI48ebo2SYpIBJsV1eh9SEMfXo1batAPvB5grhAbLX0MRUOtzuQOnZMCDGdr2v7l2L8Siw==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.6.1.tgz", + "integrity": "sha512-6duvh3CbDA3c4HpNkzIOP9z1wn/mKY1Mrxj+AqgcNvsE0ppp1iKlMsJCDgl7SlUauus2AgtM1dIEU+0sRajmwQ==", "dev": true, "license": "MIT", "optionalDependencies": { - "@rspack/binding-darwin-arm64": "1.6.0", - "@rspack/binding-darwin-x64": "1.6.0", - "@rspack/binding-linux-arm64-gnu": "1.6.0", - "@rspack/binding-linux-arm64-musl": "1.6.0", - "@rspack/binding-linux-x64-gnu": "1.6.0", - "@rspack/binding-linux-x64-musl": "1.6.0", - "@rspack/binding-wasm32-wasi": "1.6.0", - "@rspack/binding-win32-arm64-msvc": "1.6.0", - "@rspack/binding-win32-ia32-msvc": "1.6.0", - "@rspack/binding-win32-x64-msvc": "1.6.0" + "@rspack/binding-darwin-arm64": "1.6.1", + "@rspack/binding-darwin-x64": "1.6.1", + "@rspack/binding-linux-arm64-gnu": "1.6.1", + "@rspack/binding-linux-arm64-musl": "1.6.1", + "@rspack/binding-linux-x64-gnu": "1.6.1", + "@rspack/binding-linux-x64-musl": "1.6.1", + "@rspack/binding-wasm32-wasi": "1.6.1", + "@rspack/binding-win32-arm64-msvc": "1.6.1", + "@rspack/binding-win32-ia32-msvc": "1.6.1", + "@rspack/binding-win32-x64-msvc": "1.6.1" } }, "node_modules/@rspack/binding-darwin-arm64": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.6.0.tgz", - "integrity": "sha512-IrigOWnGvQgugsTZgf3dB5uko+y+lkNLYg/8w0DiobxkWhpLO97RAeR1w0ofIPXYVu3UWVf7dgHj3PjTqjC9Tw==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.6.1.tgz", + "integrity": "sha512-am7gVsqicKY/FhDfNa/InHxrBd3wRt6rI7sFTaunKaPbPERjWSKr/sI47tB3t8uNYmLQFFhWFijomAhDyrlHMg==", "cpu": [ "arm64" ], @@ -1147,9 +1148,9 @@ ] }, "node_modules/@rspack/binding-darwin-x64": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.6.0.tgz", - "integrity": "sha512-UYz+Y1XqbHGnkUOsaZRuwiuQaQaQ5rEPSboBPlIVDtblwmB71yxo3ET0nSoUhz8L/WXqQoARiraTCxUP6bvSIg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.6.1.tgz", + "integrity": "sha512-uadcJOal5YTg191+kvi47I0b+U0sRKe8vKFjMXYOrSIcbXGVRdBxROt/HMlKnvg0u/A83f6AABiY6MA2fCs/gw==", "cpu": [ "x64" ], @@ -1161,9 +1162,9 @@ ] }, "node_modules/@rspack/binding-linux-arm64-gnu": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.6.0.tgz", - "integrity": "sha512-Jr7aaxrtwOnh7ge7tZP+Mjpo6uNltvQisL25WcjpP+8PnPT0C9jziKDJso7KxeOINXnQ2yRn2h65+HBNb7FQig==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.6.1.tgz", + "integrity": "sha512-n7UGSBzv7PiX+V1Q2bY3S1XWyN3RCykCQUgfhZ+xWietCM/1349jgN7DoXKPllqlof1GPGBjziHU0sQZTC4tag==", "cpu": [ "arm64" ], @@ -1175,9 +1176,9 @@ ] }, "node_modules/@rspack/binding-linux-arm64-musl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.6.0.tgz", - "integrity": "sha512-hl17reUhkjgkcLao6ZvNiSRQFGFykqUpIj1//v/XtVd/2XAZ0Kt7jv9UUeaR+2zY8piH+tgCkwgefmjmajMeFg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.6.1.tgz", + "integrity": "sha512-P7nx0jsKxx7g3QAnH9UnJDGVgs1M2H7ZQl68SRyrs42TKOd9Md22ynoMIgCK1zoy+skssU6MhWptluSggXqSrA==", "cpu": [ "arm64" ], @@ -1189,9 +1190,9 @@ ] }, "node_modules/@rspack/binding-linux-x64-gnu": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.6.0.tgz", - "integrity": "sha512-xdlb+ToerFU/YggndCfIrZI/S/C80CP9ZFw6lhnEFSTJDAG88KptxstsoKUh8YzyPTD45CYaOjYNtUtiv0nScg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.6.1.tgz", + "integrity": "sha512-SdiurC1bV/QHnj7rmrBYJLdsat3uUDWl9KjkVjEbtc8kQV0Ri4/vZRH0nswgzx7hZNY2j0jYuCm5O8+3qeJEMg==", "cpu": [ "x64" ], @@ -1203,9 +1204,9 @@ ] }, "node_modules/@rspack/binding-linux-x64-musl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.6.0.tgz", - "integrity": "sha512-IkXEW/FBPPz4EJJTLNZvA+94aLaW2HgUMYu7zCIw5YMc9JJ/UXexY1zjX/A7yidsCiZCRy/ZrB+veFJ5FkZv7w==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.6.1.tgz", + "integrity": "sha512-JoSJu29nV+auOePhe8x2Fzqxiga1YGNcOMWKJ5Uj8rHBZ8FPAiiE+CpLG8TwfpHsivojrY/sy6fE8JldYLV5TQ==", "cpu": [ "x64" ], @@ -1217,9 +1218,9 @@ ] }, "node_modules/@rspack/binding-wasm32-wasi": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.6.0.tgz", - "integrity": "sha512-XGwX35XXnoTYVUGwDBsKNOkkk/yUsT/RF59u9BwT3QBM5eSXk767xVw/ZeiiyJf5YfI/52HDW2E4QZyvlYyv7g==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.6.1.tgz", + "integrity": "sha512-u5NiSHxM7LtIo4cebq/hQPJ9o39u127am3eVJHDzdmBVhTYYO5l7XVUnFmcU8hNHuj/4lJzkFviWFbf3SaRSYA==", "cpu": [ "wasm32" ], @@ -1231,9 +1232,9 @@ } }, "node_modules/@rspack/binding-win32-arm64-msvc": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.6.0.tgz", - "integrity": "sha512-HOA/U7YC6EB74CpIrT2GrvPgd+TLr0anNuOp/8omw9hH1jjsP5cjUMgWeAGmWyXWxwoS8rRJ0xhRA+UIe3cL3g==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.6.1.tgz", + "integrity": "sha512-u2Lm4iyUstX/H4JavHnFLIlXQwMka6WVvG2XH8uRd6ziNTh0k/u9jlFADzhdZMvxj63L2hNXCs7TrMZTx2VObQ==", "cpu": [ "arm64" ], @@ -1245,9 +1246,9 @@ ] }, "node_modules/@rspack/binding-win32-ia32-msvc": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.6.0.tgz", - "integrity": "sha512-ThczdltBOFcq+IrTflCE+8q0GvKoISt6pTupkuGnI1/bCnqhCxPP6kx8Z06fdJUFMhvBtpZa0gDJvhh3JBZrKA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.6.1.tgz", + "integrity": "sha512-/rMU4pjnQeYnkrXmlqeEPiUNT1wHfJ8GR5v2zqcHXBQkAtic3ZsLwjHpucJjrfRsN5CcVChxJl/T7ozlITfcYw==", "cpu": [ "ia32" ], @@ -1259,9 +1260,9 @@ ] }, "node_modules/@rspack/binding-win32-x64-msvc": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.6.0.tgz", - "integrity": "sha512-Bhyvsh1m6kIpr1vqZlcdUDUTh0bheRe9SF+f6jw0kPDPbh8FfrRbshPKmRHpRZAUHt20NqgUKR2z2BaKb0IJvQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.6.1.tgz", + "integrity": "sha512-8qsdb5COuZF5Trimo3HHz3N0KuRtrPtRCMK/wi7DOT1nR6CpUeUMPTjvtPl/O/QezQje+cpBFTa5BaQ1WKlHhw==", "cpu": [ "x64" ], @@ -1273,14 +1274,14 @@ ] }, "node_modules/@rspack/core": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.6.0.tgz", - "integrity": "sha512-u2GDSToEhmgIsy0QbOPA81i9tu87J2HgSsRA3HHZfWIR8Vt8KdlAriQnG8CatDnvFSY/UQEumVf5Z1HUAQwxCg==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.6.1.tgz", + "integrity": "sha512-hZVrmiZoBTchWUdh/XbeJ5z+GqHW5aPYeufBigmtUeyzul8uJtHlWKmQhpG+lplMf6o1RESTjjxl632TP/Cfhg==", "dev": true, "license": "MIT", "dependencies": { "@module-federation/runtime-tools": "0.21.2", - "@rspack/binding": "1.6.0", + "@rspack/binding": "1.6.1", "@rspack/lite-tapable": "1.0.1" }, "engines": { @@ -1851,6 +1852,16 @@ "dev": true, "license": "MIT" }, + "node_modules/patronum": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/patronum/-/patronum-2.3.0.tgz", + "integrity": "sha512-BfKIOpoymVz6XnkOn8Fi5QZ1a3r/3lXdd8BcdHmYDbIXPTIRnD1EPFBFev/DheWnOge6/ZswEqgNF2ANLGOxLw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "effector": "^23" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2019,9 +2030,9 @@ } }, "node_modules/rsbuild-plugin-dts": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/rsbuild-plugin-dts/-/rsbuild-plugin-dts-0.17.0.tgz", - "integrity": "sha512-GHfdTj5V3rscsVwfsh1cOPrQe1hwVvw9uE3aaqp0Mk9YGCTdjDS9Qczlohf8PwEHAlAL+qhvh6RQqAKZe7tuNg==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/rsbuild-plugin-dts/-/rsbuild-plugin-dts-0.17.1.tgz", + "integrity": "sha512-fEykqICjrvB0dqzm0WqZSQ5rXZ5r+ZYYxqIDgTDU6mHlhlAGJ+AOnX8vgujAdiyuqDF2ZiHcN0QYjxB2UwddtQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2109,11 +2120,14 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", - "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.15", @@ -2174,9 +2188,9 @@ } }, "node_modules/vite": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", - "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.1.tgz", + "integrity": "sha512-qTl3VF7BvOupTR85Zc561sPEgxyUSNSvTQ9fit7DEMP7yPgvvIGm5Zfa1dOM+kOwWGNviK9uFM9ra77+OjK7lQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 24bceb7..ce5800e 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,11 @@ "author": "Viktor Pasynok", "license": "MIT", "devDependencies": { - "@rslib/core": "0.17.0", + "@rslib/core": "0.17.1", "@size-limit/preset-small-lib": "11.2.0", "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "clean-publish": "6.0.1", + "patronum": "2.3.0", "prettier": "3.6.2", "prettier-plugin-organize-imports": "4.3.0", "size-limit": "11.2.0", diff --git a/src/__tests__/extractWhenPayload.spec-d.ts b/src/__tests__/extractWhenPayload.spec-d.ts new file mode 100644 index 0000000..557b61a --- /dev/null +++ b/src/__tests__/extractWhenPayload.spec-d.ts @@ -0,0 +1,43 @@ +import { createEffect, createEvent, createStore } from 'effector'; +import { expectTypeOf } from 'vitest'; +import { ExtractWhenPayload } from '../payload'; + +const event = createEvent(); +const $store = createStore(0); +const effectFx = createEffect(); +const effectWithArrayFx = createEffect(); + +// --- Single Units --- + +expectTypeOf>().toEqualTypeOf(); +expectTypeOf>().toEqualTypeOf(); +expectTypeOf>().toEqualTypeOf(); +expectTypeOf>().toEqualTypeOf(); + +// --- Array of Units --- + +// Single type array +expectTypeOf>().toEqualTypeOf(); +expectTypeOf>().toEqualTypeOf(); +expectTypeOf>().toEqualTypeOf(); +expectTypeOf>().toEqualTypeOf(); + +// Mixed array +expectTypeOf< + ExtractWhenPayload<[typeof event, typeof $store, typeof effectFx, typeof effectWithArrayFx]> +>().toEqualTypeOf(); + +// Mixed array with duplicates +expectTypeOf>().toEqualTypeOf(); + +// --- Edge Cases --- + +// Empty array should resolve to never +expectTypeOf>().toBeNever(); + +// Non-unit types should resolve to never +expectTypeOf>().toBeNever(); +expectTypeOf>().toBeNever(); +expectTypeOf>().toBeNever(); +expectTypeOf>().toBeNever(); +expectTypeOf>().toBeNever(); diff --git a/src/__tests__/payload.spec-d.tsx b/src/__tests__/payload.spec-d.tsx index d8f2097..d727a44 100644 --- a/src/__tests__/payload.spec-d.tsx +++ b/src/__tests__/payload.spec-d.tsx @@ -1,13 +1,15 @@ -import { createEffect, createEvent, createStore, UnitValue } from 'effector'; +import { createEffect, createEvent, createStore } from 'effector'; +import { once } from 'patronum'; import React from 'react'; import { expectTypeOf } from 'vitest'; import { EmptyObject } from '../helpers'; import { createSlotIdentifier, createSlots } from '../index'; -import { ExtractWhenPayload } from '../payload'; const slotWithProps = createSlotIdentifier<{ text: string }>(); const noPropsSlot = createSlotIdentifier(); const triggerEvent = createEvent(); +const triggerFx = createEffect((x: string[]) => [x]); +const $trigger = createStore(true); const { slotsApi } = createSlots({ Top: slotWithProps, @@ -84,25 +86,37 @@ slotsApi.Top.insert({ }); slotsApi.Top.insert({ - when: [createEvent(), createStore(''), createEffect((x: string[]) => x)], + when: [triggerEvent, triggerFx], mapProps: (__, signalPayload) => { - return null; + expectTypeOf(signalPayload); + return {}; }, Component: () => '', }); slotsApi.Top.insert({ - when: [createEvent(), createStore(''), createEffect((x: null) => x)], + when: [triggerEvent, triggerFx, $trigger], mapProps: (__, signalPayload) => { - return null; + expectTypeOf(signalPayload); + return {}; }, Component: () => '', }); slotsApi.Top.insert({ - when: [createEvent(), createEffect((x: string) => x)], + when: [triggerEvent, once({ source: triggerFx.doneData }), $trigger], mapProps: (__, signalPayload) => { - return ''; + expectTypeOf(signalPayload); + return {}; + }, + Component: () => '', +}); + +slotsApi.Top.insert({ + when: [triggerEvent, once({ source: triggerFx.done }), $trigger], + mapProps: (__, signalPayload) => { + expectTypeOf(signalPayload); + return {}; }, Component: () => '', }); @@ -112,8 +126,3 @@ slotsApi.Top.insert({ // @ts-expect-error Component: (_: { wrong: number }) =>
, }); - - -const $a = createEffect((x: string) => x) -const list = [$a] -type N = ExtractWhenPayload diff --git a/src/payload.ts b/src/payload.ts index 22b6808..9cca136 100644 --- a/src/payload.ts +++ b/src/payload.ts @@ -8,7 +8,7 @@ type Payload = { // When mapProps is provided with when | Unit[]>(params: { Component: (props: unknown extends R ? EmptyObject : R extends void ? EmptyObject : R) => ReactNode; - mapProps: (arg: T, whenPayload: ExtractWhenPayload) => R; + mapProps: (slotProps: T, whenPayload: ExtractWhenPayload) => R; order?: number; when: W; }): void; @@ -16,7 +16,7 @@ type Payload = { // When mapProps is provided without when (params: { Component: (props: unknown extends R ? EmptyObject : R extends void ? EmptyObject : R) => ReactNode; - mapProps: (arg: T) => R; + mapProps: (slotProps: T) => R; order?: number; when?: undefined; }): void; From 5778153e9fe0bc685aef7c14ed98b6dd29ba4905 Mon Sep 17 00:00:00 2001 From: Viktor Pasynok Date: Thu, 6 Nov 2025 16:14:04 +0700 Subject: [PATCH 4/4] Upgrade to version 3.1.0 --- CHANGELOG.md | 16 ++++++++++++++-- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb510fd..81b979f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,21 @@ -# Change Log +# Changelog The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](http://semver.org). -## 3.0.1 +## v3.1.0 + +### Added + +- Now `when` supports any `Unit` from Effector. (#11) + +### Changed + +- `Component` return type from `React.JSX.Element` to `React.ReactNode`. (#10) + +Big thanks to @TheCoffeeFox for spotting the type improvements! + +## v3.0.1 ### Fixed diff --git a/package-lock.json b/package-lock.json index e47ccd5..b3f91d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@grlt-hub/react-slots", - "version": "3.0.1", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@grlt-hub/react-slots", - "version": "3.0.1", + "version": "3.1.0", "license": "MIT", "devDependencies": { "@rslib/core": "0.17.1", diff --git a/package.json b/package.json index ce5800e..b46789d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@grlt-hub/react-slots", - "version": "3.0.1", + "version": "3.1.0", "type": "module", "private": false, "main": "dist/index.js",