-
Notifications
You must be signed in to change notification settings - Fork 9
feat: 新增inula-adapter模块适配vue api #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
WalkthroughThis change introduces a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App
participant Adapter
participant OpenInula
participant Store
User->>App: createApp(rootComponent)
App->>Adapter: Initializes AppContext, config, global properties
App->>Adapter: Registers components, directives, plugins
App->>OpenInula: Renders rootComponent via OpenInula
User->>App: app.use(plugin) / app.component() / app.directive()
App->>Adapter: Registers plugin/component/directive globally
User->>App: app.mount(container)
App->>OpenInula: Mounts to DOM container
User->>Adapter: defineStore(options) (Pinia)
Adapter->>Store: Creates or retrieves singleton store instance
Store->>OpenInula: Uses reactive state, actions, getters
User->>Adapter: createStore(options) (Vuex)
Adapter->>Store: Initializes root/module stores, proxies state/getters
Store->>OpenInula: Uses reactive state, mutations, actions, modules
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 77
♻️ Duplicate comments (3)
packages/inula-adapter/examples/$el/TypewriterInput.vue (1)
11-17: Verify the addListener API consistency.Similar to the JSX version, this component uses
addListenerwhich is non-standard for DOM elements. Please verify this is the correct API for the Vue adapter and ensure consistency across both implementations.The same
addListenerAPI issue exists in both component versions. Standard DOM elements useaddEventListener, and the event names should typically be lowercase (keydown,keyupinstead ofkeyDown,keyUp).packages/inula-adapter/tsconfig.vuex.json (1)
1-10: Same trailing-comma issue as intsconfig.vue.jsonReplicate the fix (or suppress the linter rule) to avoid inconsistent build behaviour.
- "declarationDir": "./build/vuex/@types" - }, + "declarationDir": "./build/vuex/@types" + }packages/inula-adapter/tsconfig.pinia.json (1)
1-10: Repeat of trailing-comma / Biome parse errorFor consistency, drop the trailing comma here as well.
- "declarationDir": "./build/pinia/@types" - }, + "declarationDir": "./build/pinia/@types" + }
🧹 Nitpick comments (71)
packages/inula-adapter/tests/utils/globalSetup.js (2)
18-22: PreferglobalThisover Node-specificglobal.
globalis Node-specific, whereasglobalThisis standards-based and works in both browser‐like and Node environments (Vitest’s JSDOM, workers, etc.).
Switching prevents subtle reference errors when a non-Node runtime is introduced.-beforeEach(() => { - // 创建一个 DOM 元素作为渲染目标 - global.container = document.createElement('div'); - document.body.appendChild(global.container); -}); +beforeEach(() => { + // 创建一个 DOM 元素作为渲染目标 + globalThis.container = document.createElement('div'); + document.body.appendChild(globalThis.container); +});
24-27: Guard against missing container & detach safely.If a test crashes before
beforeEachcompletes,afterEachwill currently throw (global.containerisundefined).
Add a null-check and useglobalThisconsistently.-afterEach(() => { - global.container.remove(); - global.container = null; -}); +afterEach(() => { + if (globalThis.container) { + globalThis.container.remove(); + globalThis.container = null; + } +});packages/inula-adapter/examples/$forceUpdate/clock.jsx (1)
1-1: Remove unused props parameter.The
propsparameter is defined but never used in the component.Apply this diff to remove the unused parameter:
-export default function (props) { +export default function Clock() {packages/inula-adapter/examples/$el/TypewriterInput.jsx (1)
4-4: Remove unused props parameter.The
propsparameter is defined but never used in the function, as correctly flagged by ESLint.-export default function (props) { +export default function () {packages/inula-adapter/tsconfig.vue.json (1)
1-10: Trailing comma triggers lint error – consider JSONC‐safe but linter-hostile.
tscaccepts trailing commas intsconfig.json(it is parsed as JSONC), yet Biome flags this as an error. If your CI / pre-commit pipeline uses Biome (or another strict JSON parser), builds might fail.- "compilerOptions": { - "emitDeclarationOnly": true, - "declarationDir": "./build/vue/@types" - }, + "compilerOptions": { + "emitDeclarationOnly": true, + "declarationDir": "./build/vue/@types" + }Confirm whether Biome (or any other JSON-validator) runs in the pipeline. If yes, the diff above silences the error; if not, feel free to keep the trailing comma.
packages/inula-adapter/src/vue/types.ts (1)
16-16: Type alias name deviates from common casing conventions
FNin all-caps reads like a constant; TypeScript community tends to useFn,Noop, or similar for function aliases. Consider:-export type FN = () => void; +export type Fn = () => void;If the alias is already consumed elsewhere, update imports accordingly.
packages/inula-adapter/src/vue/keepAlive/index.ts (1)
1-4: Expose default & named export in a single statement for better DXToday consumers need:
import { KeepAlive } from '.../keepAlive';but cannot do
import KeepAlive from .... You can provide both with a tiny tweak:-import KeepAlive from './keepAlive'; -import { useActivatePro, useUnActivatePro } from './lifeCycleHooks'; - -export { KeepAlive, useActivatePro, useUnActivatePro }; +export { default as KeepAlive } from './keepAlive'; +export { useActivatePro, useUnActivatePro } from './lifeCycleHooks';Same runtime behaviour, leaner code, and dual import style supported.
packages/inula-adapter/examples/emitter/listener.jsx (1)
1-1: Remove unused parameter.The
propsparameter is defined but never used.-export default function (props) { +export default function () {packages/inula-adapter/examples/$t - plugins/App.jsx (1)
3-3: Remove unused parameter.The
propsparameter is defined but never used.-export default function (props) { +export default function () {packages/inula-adapter/examples/$root/root.jsx (1)
3-3: Remove unused props parameter.The
propsparameter is defined but never used in the component. Remove it to clean up the code.-export default function (props) { +export default function () {packages/inula-adapter/examples/emitter/emitter.jsx (2)
1-1: Remove unused props parameter.The
propsparameter is defined but never used.-export default function (props) { +export default function () {
2-4: Optimize useInstance calls for better performance.Calling
useInstance()multiple times is inefficient. Consider storing the instance reference.+import { useInstance } from 'vue-inula'; + export default function () { + const instance = useInstance(); + function clicked() { - useInstance().$refs.emitter.$emit('eventEmitterClicked'); + instance.$refs.emitter.$emit('eventEmitterClicked'); }packages/inula-adapter/examples/$t - plugins/i18n.js (1)
8-8: Fix Spanish translation typo."Ola" should be "Hola" in Spanish.
- introduction: 'Ola, yo soy Dora.', + introduction: 'Hola, yo soy Dora.',packages/inula-adapter/examples/$refs/refresh.jsx (2)
3-3: Remove unused props parameter.The
propsparameter is defined but never used.-export default function (props) { +export default function () {
4-10: Optimize useInstance calls for better performance.Calling
useInstance()multiple times is inefficient. Consider storing the instance reference.export default function () { + const instance = useInstance(); + function validateAndSubmit() { - if (!useInstance().$refs[0].value) { - useInstance().$refs[0].focus(); + if (!instance.$refs[0].value) { + instance.$refs[0].focus(); } else { submit(); } }packages/inula-adapter/examples/$children/FruitList.jsx (1)
3-3: Remove unused props parameter.The
propsparameter is defined but never used in the component.Remove the unused parameter:
-export default function (props) { +export default function () {packages/inula-adapter/.prettierrc.js (1)
16-16: Remove redundant 'use strict' directive.The 'use strict' directive is redundant in ES modules as strict mode is automatically applied.
Remove the redundant directive:
*/ -'use strict'; - module.exports = {packages/inula-adapter/examples/$nextTick/nextTick.jsx (1)
1-1: Remove unusedpropsparameter.The
propsparameter is defined but never used in the component.-export default function (props) { +export default function () {packages/inula-adapter/tsconfig.json (2)
10-10: Consider translating Chinese comments to English.The comment is in Chinese which may limit accessibility for international contributors.
- "noUnusedLocals": false, // 等大部分js代码改成ts之后再启用. + "noUnusedLocals": false, // Enable after most JS code is converted to TS.
28-28: Consider translating Chinese comments to English.The comment is in Chinese which may limit accessibility for international contributors.
- "types": ["jest"], // 赋值为空数组使@types/node不会起作用 + "types": ["jest"], // Setting to empty array prevents @types/node from taking effectpackages/inula-adapter/src/vue/injectProvide.tsx (1)
1-1: Remove unused import.The
useContextimport is not used in this module.-import { createContext, useContext } from 'openinula'; +import { createContext } from 'openinula';packages/inula-adapter/docs/README_vuex.md (1)
75-75: Fix numbering inconsistency in the documentation.There are two sections numbered "4" in the documentation. The section about
store.replaceStateshould be numbered "5", and subsequent sections should be renumbered accordingly.-4、不支持store.replaceState +5、不支持store.replaceStateAlso update the following sections:
- Line 125: "5、store.registerModule不支持传入options参数" → "6、store.registerModule不支持传入options参数"
- Line 139: "5、dispatch不支持传入options参数" → "7、dispatch不支持传入options参数"
- Line 144: "6、不支持action中的root属性" → "8、不支持action中的root属性"
- Line 163: "7、createStore中不支持plugins" → "9、createStore中不支持plugins"
packages/inula-adapter/examples/$set/fruits.jsx (1)
3-3: Remove unused props parameter.The
propsparameter is defined but never used in the component.-export default function (props) { +export default function () {packages/inula-adapter/tests/pinia/pinia.store.test.ts (1)
74-74: Address the skipped test for state replacement.The test for replacing store state is currently skipped. This might indicate missing functionality or a known limitation in the Pinia adapter.
Would you like me to help investigate why this test is skipped and potentially implement the missing functionality for state replacement?
packages/inula-adapter/tests/pinia/pinia.state.test.ts (3)
20-20: Remove unused import.The
reactiveimport is not used in this test file and should be removed.-const { watch, computed, ref, reactive, nextTick } = vueReactive; +const { watch, computed, ref, nextTick } = vueReactive;
122-123: Add description to @ts-expect-error directive.The @ts-expect-error directive should include a description explaining why it's necessary.
- // @ts-expect-error + // @ts-expect-error: intentionally assigning ref to test reactivity behavior store.$state.name = nameRef;
132-133: Add description to @ts-expect-error directive.The @ts-expect-error directive should include a description explaining why it's necessary.
- // @ts-expect-error + // @ts-expect-error: intentionally assigning ref to test state synchronization store.$state.name = ref('Ed');packages/inula-adapter/src/vue/dynamicComponent.tsx (2)
15-15: Remove unused import.The
Inulaimport is not used since JSX transformation is handled by Babel with the automatic runtime.-import Inula, { ComponentType, InulaElement } from 'openinula'; +import { ComponentType, InulaElement } from 'openinula';
50-54: Use optional chaining for safer property access.The code can be made more robust by using optional chaining to prevent potential runtime errors.
// If not found, look in global components if (!Component) { - const app = getCurrentInstance().appContext.app; - Component = app._context.components[pascalCaseName]; + Component = getCurrentInstance()?.appContext?.app?._context?.components?.[pascalCaseName]; }packages/inula-adapter/tests/utils/testingLibrary.js (3)
16-16: Remove unused import.The
Inulaimport is not used anywhere in the file.-import Inula from 'openinula';
21-29: Consider adding cleanup mechanism for rendered components.The
renderfunction creates DOM elements and appends them todocument.bodybut doesn't provide a cleanup mechanism. This could lead to DOM pollution between tests.Consider returning a cleanup function:
export function render(component) { const container = document.createElement('div'); document.body.appendChild(container); const app = createApp(component); app.mount(container); - return { container, app }; + return { + container, + app, + cleanup: () => { + app.unmount(); + document.body.removeChild(container); + } + }; }
67-79: Use optional chaining for safer property access.The
toHaveTextContentmatcher can be improved with optional chaining to handle null/undefined values more safely.toHaveTextContent(received, expected) { - const pass = received && received.textContent.includes(expected); + const pass = received?.textContent?.includes(expected); if (pass) { return { message: () => `expected ${received} not to have text content "${expected}"`, pass: true, }; } else { return { message: () => `expected ${received} to have text content "${expected}"`, pass: false, }; } },packages/inula-adapter/tests/vuex/vuex.component.test.tsx (1)
16-16: Remove unused import.The
viimport from vitest is not used in the tests.-import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it } from 'vitest';packages/inula-adapter/tests/pinia/pinia.storeToRefs.test.ts (1)
16-16: Remove unused import.The
viimport from vitest is not used in the tests.-import { beforeEach, describe, it, vi, expect } from 'vitest'; +import { beforeEach, describe, it, expect } from 'vitest';packages/inula-adapter/tests/vuex/vuex.modules.test.ts (2)
16-16: Remove unused import.The
beforeEachimport is not used in the test file.-import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { describe, it, expect, vi } from 'vitest';
103-103: Fix typo in test name."existance" should be "existence".
- it('dynamic module existance test', () => { + it('dynamic module existence test', () => {packages/inula-adapter/tests/vue/injectProvide.test.tsx (2)
19-19: Remove unused import.The
viimport is not used in the test file.-import { describe, expect, it, vi, beforeEach } from 'vitest'; +import { describe, expect, it, beforeEach } from 'vitest';
22-22: Remove empty beforeEach.The empty beforeEach function serves no purpose and can be removed.
- beforeEach(() => {});packages/inula-adapter/tests/vue/liftcycle.test.tsx (1)
1-1: Fix filename typo.The filename "liftcycle" should be "lifecycle".
Consider renaming the file to
lifecycle.test.tsxto fix the typo.packages/inula-adapter/tests/vue/sfcAPI.test.tsx (1)
16-16: Remove unused import.The
viimport is not used in this test file.-import { describe, it, vi, expect } from 'vitest'; +import { describe, it, expect } from 'vitest';packages/inula-adapter/src/vue/condition.tsx (1)
16-16: Remove unused import.The
Inulaimport is not used anywhere in the file and should be removed.-import Inula, { isValidElement, Children, FC } from 'openinula'; +import { isValidElement, Children, FC } from 'openinula';packages/inula-adapter/tests/vue/props.test.tsx (1)
16-16: Remove unused import.The
viimport from vitest is not used in this test file and should be removed.-import { describe, it, vi, expect } from 'vitest'; +import { describe, it, expect } from 'vitest';packages/inula-adapter/tests/pinia/pinia.getters.test.ts (3)
37-39: Add descriptive comment for @ts-expect-error directive.The
@ts-expect-errordirective should include a description explaining why the error is expected.- // @ts-expect-error + // @ts-expect-error: Testing access to non-existent property state.nope;
54-56: Clean up unused variables.The variables
useBanduseAare declared but never used in the tests.let useStore = createStore(); - let useB; - let useA;
69-71: Add descriptive comment for @ts-expect-error directive.The
@ts-expect-errordirective should include a description explaining why the error is expected.- // @ts-expect-error + // @ts-expect-error: Testing access to non-existent property store.nope;packages/inula-adapter/tests/vue/condition.test.tsx (2)
19-19: Remove unused import.The
viimport from vitest is not used in this test file and should be removed.-import { describe, expect, it, vi } from 'vitest'; +import { describe, expect, it } from 'vitest';
23-23: Remove unused variable.The
useReferencevariable is destructured but never used in the tests.-const { useReactive, useReference } = vueReactive; +const { useReactive } = vueReactive;packages/inula-adapter/src/vue/helper.tsx (1)
94-94: Use const for variables that are never reassigned.The variable
keyis never reassigned and should be declared asconst.Apply this diff:
- for (let key in styleObject) { + for (const key in styleObject) {packages/inula-adapter/src/vue/semiControlledComponent.tsx (1)
16-16: Remove unused import.The
Inulaimport is never used in this file.Apply this diff:
- import Inula, { useState, useEffect, useRef, ChangeEvent, FC } from 'openinula'; + import { useState, useEffect, useRef, ChangeEvent, FC } from 'openinula';packages/inula-adapter/tests/vue/attrs.test.tsx (5)
16-17: Remove unused imports.Several imports are defined but never used in the test file.
Apply this diff:
- import { describe, it, vi, expect } from 'vitest'; - import { render, act, vueReactive, useState, Component, memo, forwardRef } from 'openinula'; + import { describe, it, expect } from 'vitest'; + import { act, useState, Component, memo, forwardRef } from 'openinula';
221-223: Remove unnecessary constructor.The constructor doesn't add any functionality and can be removed.
Apply this diff:
class App extends Component { - constructor(props) { - super(props); - } render() { return <Parent style="background-color:yellow; width: 100%" />; } }
264-266: Remove unnecessary constructor.The constructor doesn't add any functionality and can be removed.
Apply this diff:
class App extends Component { - constructor(props) { - super(props); - } render() { return <Parent style="background-color:yellow; width: 100%" />; } }
307-309: Remove unnecessary constructor.The constructor doesn't add any functionality and can be removed.
Apply this diff:
class App extends Component { - constructor(props) { - super(props); - } render() { return <Parent style="background-color:yellow; width: 100%" />; } }
329-329: Remove unused parameter.The
resolveparameter in the describe function is never used.Apply this diff:
- describe('$attrs: $attrs object', async resolve => { + describe('$attrs: $attrs object', () => {packages/inula-adapter/src/vue/props.tsx (1)
15-15: Remove unused import.The
Inulaimport is never used in this file.Apply this diff:
- import Inula, { vueReactive, useRef, ReactiveRet } from 'openinula'; + import { vueReactive, useRef, ReactiveRet } from 'openinula';packages/inula-adapter/tests/vue/globalAPI.test.tsx (1)
27-27: Remove unused import.The
viimport is not used anywhere in this test file.-import { describe, expect, it, vi, beforeEach } from 'vitest'; +import { describe, expect, it, beforeEach } from 'vitest';packages/inula-adapter/tests/vue/keepAlivePro.test.tsx (2)
19-19: Remove unused import.The
viimport is not used anywhere in this test file.-import { describe, expect, it, vi, beforeEach } from 'vitest'; +import { describe, expect, it, beforeEach } from 'vitest';
29-29: Fix incorrect test suite name.The describe block incorrectly names the test suite as "KeepAlive" when it should be "KeepAlivePro" to match the component being tested.
-describe('component: KeepAlive', () => { +describe('component: KeepAlivePro', () => {packages/inula-adapter/tests/vue/keepAlive.test.tsx (1)
71-71: Remove commented out codeThe commented line appears to be leftover from debugging.
- // await wait(10);packages/inula-adapter/src/pinia/pinia.ts (1)
196-208: Address ESLint warnings for unused parametersThe parameters
appandpluginare part of the Pinia interface but intentionally unused in this stub implementation.const result = { - install: (app: any) => {}, - use: (plugin: any) => result, + install: (_app: any) => {}, + use: (_plugin: any) => result, state: {}, };Alternatively, disable the ESLint rule for these specific lines:
const result = { + // eslint-disable-next-line @typescript-eslint/no-unused-vars install: (app: any) => {}, + // eslint-disable-next-line @typescript-eslint/no-unused-vars use: (plugin: any) => result, state: {}, };packages/inula-adapter/src/vue/directive.tsx (2)
94-103: Use optional chaining for cleaner codeReplace the conditional checks with optional chaining as suggested by Biome.
let directiveObj: Directive = {}; - if (registerDirectives && registerDirectives[name]) { - directiveObj = registerDirectives[name]; - } else { - directiveObj = appDirectives[name]; - } + directiveObj = registerDirectives?.[name] || appDirectives[name]; - if (directiveObj && directiveObj[hook]) { - directiveObj[hook]!(instance['$el']!, { value, oldValue, arg, modifiers }); - } + directiveObj?.[hook]?.(instance['$el']!, { value, oldValue, arg, modifiers });
87-89: Add type annotation for directives parameterThe
directivesparameter in the callback lacks type annotation.const prevDirectiveValues: Record<string, any> = useMemo(() => ({}), []); - const applyDirectives = useCallback((hook: keyof Directive, directives) => { + const applyDirectives = useCallback((hook: keyof Directive, directives: DirectiveComponentProps['directives']) => { directives.forEach(directive => {packages/inula-adapter/src/vue/useScoped.ts (2)
79-80: Consider deferring vnode traversal for better performanceThe
getFirstSingleDomVnodecall happens on every render even when it's only needed for style updates.Consider moving this call inside the effects that use it, or memoize the result:
- const vDomNode = getFirstSingleDomVnode(instance?.$vnode); + const vDomNode = useMemo(() => getFirstSingleDomVnode(instance?.$vnode), [instance?.$vnode]);
172-177: Improve readability of complex conditionConsider extracting the complex condition for better readability.
+ const shouldSkip = shouldSkipSetAttrToEl(instance.$vnode); + const styleUnchanged = shallowCompare(preNodeStyle.current, vDomNode?.props.style); + useLayoutEffect(() => { - if (shouldSkipSetAttrToEl(instance.$vnode) || shallowCompare(preNodeStyle.current, vDomNode?.props.style)) { + if (shouldSkip || styleUnchanged) { return; } preNodeStyle.current = vDomNode?.props.style; mergeStyle(); }, [vDomNode?.props.style]);packages/inula-adapter/scripts/rollup.config.js (1)
95-98: Translate Chinese comments to English for consistency.The codebase should maintain language consistency in comments.
Apply this diff:
- // 判断目标文件夹是否存在 + // Check if the destination directory exists if (!fs.existsSync(destDir)) { - // 目标文件夹不存在,创建它 + // If destination directory doesn't exist, create it fs.mkdirSync(destDir, { recursive: true });packages/inula-adapter/src/vue/keepAlive/keepAlive.tsx (1)
12-13: Translate Chinese comments to English for consistency.Apply this diff:
-// 更新缓存的children节点key数组 -// 当缓存的实例超过max时,移除最久没有使用的组件缓存, 并把最新的key插到尾部 +// Update the array of cached children node keys +// When cached instances exceed max, remove the least recently used component cache and insert the latest key at the endpackages/inula-adapter/src/vue/sfcAPI.tsx (3)
2-2: Update copyright year to match the current year.The copyright year shows 2020, but this is a new file being added in 2025.
- * Copyright (c) 2020 Huawei Technologies Co.,Ltd. + * Copyright (c) 2025 Huawei Technologies Co.,Ltd.
71-72: Translate Chinese comment to English for consistency.Apply this diff:
- // 检查 exposed 是否是一个对象 + // Check if exposed is an object if (typeof exposed === 'object' && exposed !== null) {
89-94: Consider implementing emit validation based on the emits declaration.The
defineEmitsfunction accepts anemitsparameter but doesn't use it for validation. In Vue, this parameter is used to validate emitted events.Consider adding validation logic to ensure only declared events are emitted, similar to Vue's behavior. This would help catch typos and improve type safety.
Would you like me to generate an implementation that validates emitted events against the emits declaration?
packages/inula-adapter/src/vuex/maps.ts (1)
99-101: Simplify argument spreading in commit and dispatch wrappers.The current implementation uses array indexing which is less readable and error-prone.
Apply this diff to improve readability:
- commit = (...args) => { - store.commit(args[0], args[1], args[2], moduleName); - }; + commit = (type, payload, options) => { + store.commit(type, payload, options, moduleName); + };And similarly for dispatch:
- dispatch = (...args) => { - store.dispatch(args[0], args[1], args[2], moduleName); - }; + dispatch = (type, payload, options) => { + store.dispatch(type, payload, options, moduleName); + };Also applies to: 134-136
packages/inula-adapter/src/vue/globalAPI.tsx (1)
218-225: Optimize kebabToCamelCase implementationThe current implementation creates multiple intermediate strings. Consider a more efficient approach.
function kebabToCamelCase(str: string) { - return str - .split('-') - .map(sub => { - return sub.charAt(0).toUpperCase() + sub.substr(1); - }) - .join(''); + return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) + .replace(/^([a-z])/, (_, letter) => letter.toUpperCase()); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (102)
package.json(1 hunks)packages/inula-adapter/.gitignore(1 hunks)packages/inula-adapter/.prettierrc.js(1 hunks)packages/inula-adapter/README.md(1 hunks)packages/inula-adapter/babel.config.js(1 hunks)packages/inula-adapter/docs/README_global_api.md(1 hunks)packages/inula-adapter/docs/README_pinia.md(1 hunks)packages/inula-adapter/docs/README_vue.md(1 hunks)packages/inula-adapter/docs/README_vuex.md(1 hunks)packages/inula-adapter/examples/$children/FruitItem.jsx(1 hunks)packages/inula-adapter/examples/$children/FruitItem.vue(1 hunks)packages/inula-adapter/examples/$children/FruitList.jsx(1 hunks)packages/inula-adapter/examples/$children/FruitList.vue(1 hunks)packages/inula-adapter/examples/$el/TypewriterInput.jsx(1 hunks)packages/inula-adapter/examples/$el/TypewriterInput.vue(1 hunks)packages/inula-adapter/examples/$forceUpdate/clock.jsx(1 hunks)packages/inula-adapter/examples/$forceUpdate/clock.vue(1 hunks)packages/inula-adapter/examples/$nextTick/nextTick.jsx(1 hunks)packages/inula-adapter/examples/$nextTick/nextTick.vue(1 hunks)packages/inula-adapter/examples/$parent/list-item.jsx(1 hunks)packages/inula-adapter/examples/$parent/list-item.vue(1 hunks)packages/inula-adapter/examples/$parent/list.jsx(1 hunks)packages/inula-adapter/examples/$parent/list.vue(1 hunks)packages/inula-adapter/examples/$refs/refresh.jsx(1 hunks)packages/inula-adapter/examples/$refs/refresh.vue(1 hunks)packages/inula-adapter/examples/$root/root.jsx(1 hunks)packages/inula-adapter/examples/$root/root.vue(1 hunks)packages/inula-adapter/examples/$root/themeChanger.jsx(1 hunks)packages/inula-adapter/examples/$root/themeChanger.vue(1 hunks)packages/inula-adapter/examples/$set/fruits.jsx(1 hunks)packages/inula-adapter/examples/$set/fruits.vue(1 hunks)packages/inula-adapter/examples/$t - plugins/App.jsx(1 hunks)packages/inula-adapter/examples/$t - plugins/App.vue(1 hunks)packages/inula-adapter/examples/$t - plugins/i18n.js(1 hunks)packages/inula-adapter/examples/$t - plugins/main.js(1 hunks)packages/inula-adapter/examples/custom functions/main.js(1 hunks)packages/inula-adapter/examples/emitter/emitter.jsx(1 hunks)packages/inula-adapter/examples/emitter/emitter.vue(1 hunks)packages/inula-adapter/examples/emitter/listener.jsx(1 hunks)packages/inula-adapter/examples/emitter/listener.vue(1 hunks)packages/inula-adapter/npm/pinia/package.json(1 hunks)packages/inula-adapter/npm/vuex/package.json(1 hunks)packages/inula-adapter/package.json(1 hunks)packages/inula-adapter/scripts/build-types.js(1 hunks)packages/inula-adapter/scripts/rollup.config.js(1 hunks)packages/inula-adapter/src/pinia/index.ts(1 hunks)packages/inula-adapter/src/pinia/pinia.ts(1 hunks)packages/inula-adapter/src/pinia/types.ts(1 hunks)packages/inula-adapter/src/vue/Teleport.ts(1 hunks)packages/inula-adapter/src/vue/compare.ts(1 hunks)packages/inula-adapter/src/vue/condition.tsx(1 hunks)packages/inula-adapter/src/vue/directive.tsx(1 hunks)packages/inula-adapter/src/vue/dynamicComponent.tsx(1 hunks)packages/inula-adapter/src/vue/globalAPI.tsx(1 hunks)packages/inula-adapter/src/vue/helper.tsx(1 hunks)packages/inula-adapter/src/vue/index.ts(1 hunks)packages/inula-adapter/src/vue/injectProvide.tsx(1 hunks)packages/inula-adapter/src/vue/keepAlive/context.ts(1 hunks)packages/inula-adapter/src/vue/keepAlive/index.ts(1 hunks)packages/inula-adapter/src/vue/keepAlive/keepAlive.tsx(1 hunks)packages/inula-adapter/src/vue/keepAlive/keeper.tsx(1 hunks)packages/inula-adapter/src/vue/keepAlive/lifeCycleHooks.ts(1 hunks)packages/inula-adapter/src/vue/keepAlivePro.tsx(1 hunks)packages/inula-adapter/src/vue/lifecycle.ts(1 hunks)packages/inula-adapter/src/vue/props.tsx(1 hunks)packages/inula-adapter/src/vue/semiControlledComponent.tsx(1 hunks)packages/inula-adapter/src/vue/sfcAPI.tsx(1 hunks)packages/inula-adapter/src/vue/types.ts(1 hunks)packages/inula-adapter/src/vue/useScoped.ts(1 hunks)packages/inula-adapter/src/vue/vShow.ts(1 hunks)packages/inula-adapter/src/vuex/index.ts(1 hunks)packages/inula-adapter/src/vuex/maps.ts(1 hunks)packages/inula-adapter/src/vuex/types.ts(1 hunks)packages/inula-adapter/src/vuex/vuex.ts(1 hunks)packages/inula-adapter/tests/pinia/pinia.actions.test.ts(1 hunks)packages/inula-adapter/tests/pinia/pinia.getters.test.ts(1 hunks)packages/inula-adapter/tests/pinia/pinia.state.test.ts(1 hunks)packages/inula-adapter/tests/pinia/pinia.store.test.ts(1 hunks)packages/inula-adapter/tests/pinia/pinia.storeSetup.test.ts(1 hunks)packages/inula-adapter/tests/pinia/pinia.storeToRefs.test.ts(1 hunks)packages/inula-adapter/tests/utils/globalSetup.js(1 hunks)packages/inula-adapter/tests/utils/testingLibrary.js(1 hunks)packages/inula-adapter/tests/vue/attrs.test.tsx(1 hunks)packages/inula-adapter/tests/vue/condition.test.tsx(1 hunks)packages/inula-adapter/tests/vue/directive.test.tsx(1 hunks)packages/inula-adapter/tests/vue/dynamicComponent.test.tsx(1 hunks)packages/inula-adapter/tests/vue/globalAPI.test.tsx(1 hunks)packages/inula-adapter/tests/vue/injectProvide.test.tsx(1 hunks)packages/inula-adapter/tests/vue/keepAlive.test.tsx(1 hunks)packages/inula-adapter/tests/vue/keepAlivePro.test.tsx(1 hunks)packages/inula-adapter/tests/vue/liftcycle.test.tsx(1 hunks)packages/inula-adapter/tests/vue/props.test.tsx(1 hunks)packages/inula-adapter/tests/vue/sfcAPI.test.tsx(1 hunks)packages/inula-adapter/tests/vuex/vuex.component.test.tsx(1 hunks)packages/inula-adapter/tests/vuex/vuex.maps.test.tsx(1 hunks)packages/inula-adapter/tests/vuex/vuex.modules.test.ts(1 hunks)packages/inula-adapter/tests/vuex/vuex.store.test.ts(1 hunks)packages/inula-adapter/tsconfig.json(1 hunks)packages/inula-adapter/tsconfig.pinia.json(1 hunks)packages/inula-adapter/tsconfig.vue.json(1 hunks)packages/inula-adapter/tsconfig.vuex.json(1 hunks)packages/inula-adapter/vitest.config.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (20)
packages/inula-adapter/examples/$children/FruitList.jsx (1)
packages/inula-adapter/examples/$children/FruitItem.jsx (1)
isChecked(5-5)
packages/inula-adapter/examples/$root/themeChanger.jsx (1)
packages/inula-adapter/examples/$root/root.jsx (1)
theme(4-4)
packages/inula-adapter/examples/$children/FruitItem.jsx (2)
packages/inula-adapter/src/vue/sfcAPI.tsx (1)
defineExpose(67-84)packages/inula-adapter/examples/$set/fruits.jsx (1)
fruitName(16-16)
packages/inula-adapter/src/vue/keepAlive/context.ts (1)
packages/inula-adapter/src/vue/keepAlive/lifeCycleHooks.ts (1)
LifeCycleListener(34-34)
packages/inula-adapter/examples/$t - plugins/main.js (2)
packages/inula-adapter/src/vue/globalAPI.tsx (1)
createApp(93-194)packages/inula-adapter/examples/$t - plugins/i18n.js (1)
i18n(12-16)
packages/inula-adapter/tests/pinia/pinia.storeSetup.test.ts (2)
packages/inula-adapter/tests/pinia/pinia.state.test.ts (2)
increment(32-34)upperCased(37-39)packages/inula-adapter/src/pinia/pinia.ts (1)
defineStore(51-70)
packages/inula-adapter/examples/$root/root.jsx (1)
packages/inula-adapter/src/vue/sfcAPI.tsx (1)
defineExpose(67-84)
packages/inula-adapter/tests/pinia/pinia.store.test.ts (1)
packages/inula-adapter/src/pinia/pinia.ts (1)
defineStore(51-70)
packages/inula-adapter/src/vue/semiControlledComponent.tsx (2)
packages/inula/src/types.ts (2)
ChangeEvent(325-327)FC(93-93)packages/inula/src/jsx-type/baseElement.ts (1)
HTMLInputElement(25-25)
packages/inula-adapter/tests/pinia/pinia.state.test.ts (1)
packages/inula-adapter/src/pinia/pinia.ts (2)
defineStore(51-70)createPinia(196-208)
packages/inula-adapter/src/vue/vShow.ts (2)
packages/inula-adapter/src/vue/directive.tsx (1)
Directive(37-48)packages/inula/src/jsx-type/baseElement.ts (1)
HTMLElement(1-1)
packages/inula-adapter/src/vuex/types.ts (1)
packages/inula/src/inulax/types.ts (1)
StoreObj(67-75)
packages/inula-adapter/src/vue/condition.tsx (2)
packages/inula/src/types.ts (1)
FC(93-93)packages/inula/src/index.ts (1)
Children(130-130)
packages/inula-adapter/src/vue/keepAlive/keeper.tsx (3)
packages/inula/src/jsx-type/baseElement.ts (1)
HTMLElement(1-1)packages/inula-adapter/src/vue/keepAlive/lifeCycleHooks.ts (1)
LifeCycleFunc(9-9)packages/inula-adapter/src/vue/keepAlive/context.ts (1)
NodeKeeperLifeCycleContext(3-3)
packages/inula-adapter/src/vue/keepAlive/lifeCycleHooks.ts (1)
packages/inula-adapter/src/vue/keepAlive/context.ts (1)
NodeKeeperLifeCycleContext(3-3)
packages/inula-adapter/src/vuex/maps.ts (1)
packages/inula-adapter/src/vuex/vuex.ts (1)
moduleGettersProxy(326-335)
packages/inula-adapter/src/vue/sfcAPI.tsx (2)
packages/inula-adapter/examples/$el/TypewriterInput.jsx (1)
instance(5-5)packages/inula-adapter/src/vue/globalAPI.tsx (1)
emit(259-273)
packages/inula-adapter/src/vue/lifecycle.ts (1)
packages/inula-adapter/src/vue/types.ts (1)
FN(16-16)
packages/inula-adapter/tests/pinia/pinia.getters.test.ts (1)
packages/inula-adapter/src/pinia/pinia.ts (1)
defineStore(51-70)
packages/inula-adapter/src/pinia/types.ts (1)
packages/inula/src/renderer/Types.ts (1)
RefType(60-62)
🪛 GitHub Actions: ci
package.json
[error] 1-1: pnpm install failed due to outdated lockfile. The pnpm-lock.yaml is not up to date with package.json. Run 'pnpm install --no-frozen-lockfile' to update the lockfile.
packages/inula-adapter/package.json
[error] 1-1: pnpm install failed due to outdated lockfile. The pnpm-lock.yaml is not up to date with package.json. Run 'pnpm install --no-frozen-lockfile' to update the lockfile.
🪛 ESLint
packages/inula-adapter/examples/$t - plugins/App.jsx
[error] 3-3: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/examples/emitter/listener.jsx
[error] 1-1: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 2-2: 'useInstance' is not defined.
(no-undef)
[error] 4-4: 'ButtonEmitter' is not defined.
(no-undef)
packages/inula-adapter/examples/$children/FruitList.jsx
[error] 3-3: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 8-8: 'useInstance' is not defined.
(no-undef)
packages/inula-adapter/examples/custom functions/main.js
[error] 6-6: 'removeLoadingMsg' is not defined.
(no-undef)
packages/inula-adapter/examples/$forceUpdate/clock.jsx
[error] 1-1: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 4-4: 'useEffect' is not defined.
(no-undef)
[error] 5-5: 'useState' is not defined.
(no-undef)
packages/inula-adapter/tests/pinia/pinia.storeSetup.test.ts
[error] 22-22: '_value' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vue/dynamicComponent.test.tsx
[error] 30-30: Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.
(@typescript-eslint/ban-ts-comment)
[error] 46-46: Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.
(@typescript-eslint/ban-ts-comment)
[error] 65-65: Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.
(@typescript-eslint/ban-ts-comment)
packages/inula-adapter/tests/vuex/vuex.component.test.tsx
[error] 16-16: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/examples/$nextTick/nextTick.jsx
[error] 1-1: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 3-3: 'useEffect' is not defined.
(no-undef)
[error] 7-7: 'useInstance' is not defined.
(no-undef)
packages/inula-adapter/src/vue/injectProvide.tsx
[error] 1-1: 'useContext' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/pinia/pinia.storeToRefs.test.ts
[error] 16-16: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/vue/helper.tsx
[error] 94-94: 'key' is never reassigned. Use 'const' instead.
(prefer-const)
packages/inula-adapter/examples/$root/root.jsx
[error] 3-3: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/examples/$set/fruits.jsx
[error] 3-3: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 16-16: 'useInstance' is not defined.
(no-undef)
[error] 18-18: 'useInstance' is not defined.
(no-undef)
packages/inula-adapter/src/vue/semiControlledComponent.tsx
[error] 16-16: 'Inula' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vue/injectProvide.test.tsx
[error] 19-19: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/pinia/pinia.state.test.ts
[error] 20-20: 'reactive' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 122-122: Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer.
(@typescript-eslint/ban-ts-comment)
[error] 132-132: Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer.
(@typescript-eslint/ban-ts-comment)
packages/inula-adapter/examples/$parent/list.jsx
[error] 10-10: 'filteredItems' is not defined.
(no-undef)
[error] 22-22: 'item' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vue/condition.test.tsx
[error] 19-19: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 23-23: 'useReference' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vue/sfcAPI.test.tsx
[error] 16-16: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/examples/$refs/refresh.jsx
[error] 3-3: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 8-8: 'submit' is not defined.
(no-undef)
packages/inula-adapter/examples/$el/TypewriterInput.jsx
[error] 4-4: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vue/attrs.test.tsx
[error] 16-16: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 17-17: 'render' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 17-17: 'vueReactive' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 329-329: 'resolve' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/vue/condition.tsx
[error] 16-16: 'Inula' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/vue/dynamicComponent.tsx
[error] 15-15: 'Inula' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/examples/emitter/emitter.jsx
[error] 1-1: 'props' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 3-3: 'useInstance' is not defined.
(no-undef)
packages/inula-adapter/tests/vue/props.test.tsx
[error] 16-16: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/utils/testingLibrary.js
[error] 16-16: 'Inula' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vuex/vuex.modules.test.ts
[error] 16-16: 'beforeEach' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/vue/props.tsx
[error] 15-15: 'Inula' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/pinia/pinia.ts
[error] 202-202: 'app' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 203-203: 'plugin' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vue/directive.test.tsx
[error] 77-77: 'el' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 77-77: 'binding' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 87-87: 'binding' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 123-123: 'el' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 123-123: 'binding' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 134-134: 'el' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 139-139: 'el' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 139-139: 'binding' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/vue/keepAlivePro.tsx
[error] 1-1: 'Memo' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 4-4: Don't use String as a type. Use string instead
(@typescript-eslint/ban-types)
[error] 4-4: Don't use String as a type. Use string instead
(@typescript-eslint/ban-types)
[error] 94-94: 'searchComponent' is never reassigned. Use 'const' instead.
(prefer-const)
[error] 97-97: Don't use {} as a type. {} actually means "any non-nullish value".
- If you want a type meaning "any object", you probably want
objectinstead. - If you want a type meaning "any value", you probably want
unknowninstead. - If you want a type meaning "empty object", you probably want
Record<string, never>instead. - If you really want a type meaning "any non-nullish value", you probably want
NonNullable<unknown>instead.
(@typescript-eslint/ban-types)
[error] 104-104: 'data' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 107-107: Don't use {} as a type. {} actually means "any non-nullish value".
- If you want a type meaning "any object", you probably want
objectinstead. - If you want a type meaning "any value", you probably want
unknowninstead. - If you want a type meaning "empty object", you probably want
Record<string, never>instead. - If you really want a type meaning "any non-nullish value", you probably want
NonNullable<unknown>instead.
(@typescript-eslint/ban-types)
[error] 129-129: 'key' is never reassigned. Use 'const' instead.
(prefer-const)
[error] 129-129: 'value' is never reassigned. Use 'const' instead.
(prefer-const)
[error] 145-145: 'activeComponent' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 154-154: Don't use {} as a type. {} actually means "any non-nullish value".
- If you want a type meaning "any object", you probably want
objectinstead. - If you want a type meaning "any value", you probably want
unknowninstead. - If you want a type meaning "empty object", you probably want
Record<string, never>instead. - If you really want a type meaning "any non-nullish value", you probably want
NonNullable<unknown>instead.
(@typescript-eslint/ban-types)
packages/inula-adapter/tests/pinia/pinia.getters.test.ts
[error] 37-37: Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer.
(@typescript-eslint/ban-ts-comment)
[error] 54-54: 'useB' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 55-55: 'useA' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 69-69: Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer.
(@typescript-eslint/ban-ts-comment)
packages/inula-adapter/tests/vue/globalAPI.test.tsx
[error] 27-27: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/vuex/vuex.ts
[error] 20-20: 'useComputed' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 20-20: 'computed' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 278-278: 'state' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/src/vue/globalAPI.tsx
[error] 129-129: 'mixin' is defined but never used.
(@typescript-eslint/no-unused-vars)
packages/inula-adapter/tests/vue/keepAlivePro.test.tsx
[error] 19-19: 'vi' is defined but never used.
(@typescript-eslint/no-unused-vars)
🪛 Biome (1.9.4)
packages/inula-adapter/tsconfig.vue.json
[error] 9-10: Expected a property but instead found '}'.
Expected a property here.
(parse)
packages/inula-adapter/tsconfig.vuex.json
[error] 9-10: Expected a property but instead found '}'.
Expected a property here.
(parse)
packages/inula-adapter/tsconfig.pinia.json
[error] 9-10: Expected a property but instead found '}'.
Expected a property here.
(parse)
packages/inula-adapter/examples/$children/FruitList.jsx
[error] 18-19: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
packages/inula-adapter/examples/custom functions/main.js
[error] 18-18: Illegal use of an import declaration not at the top level
move this declaration to the top level
(parse)
packages/inula-adapter/.prettierrc.js
[error] 15-16: Redundant use strict directive.
The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.
(lint/suspicious/noRedundantUseStrict)
packages/inula-adapter/src/vue/helper.tsx
[error] 84-84: Avoid the use of spread (...) syntax on accumulators.
Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.
(lint/performance/noAccumulatingSpread)
packages/inula-adapter/examples/$set/fruits.jsx
[error] 25-25: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
packages/inula-adapter/examples/$parent/list.jsx
[error] 23-23: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
packages/inula-adapter/tests/vue/attrs.test.tsx
[error] 221-223: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
[error] 264-266: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
[error] 307-309: This constructor is unnecessary.
Unsafe fix: Remove the unnecessary constructor.
(lint/complexity/noUselessConstructor)
packages/inula-adapter/src/vue/dynamicComponent.tsx
[error] 50-51: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
packages/inula-adapter/src/vue/compare.ts
[error] 26-27: Comparing to itself is potentially pointless.
(lint/suspicious/noSelfCompare)
[error] 27-28: Comparing to itself is potentially pointless.
(lint/suspicious/noSelfCompare)
packages/inula-adapter/tests/utils/testingLibrary.js
[error] 68-71: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
packages/inula-adapter/src/vue/directive.tsx
[error] 95-96: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 101-102: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
packages/inula-adapter/src/vue/keepAlivePro.tsx
[error] 4-4: Don't use 'String' as a type.
Use lowercase primitives for consistency.
Safe fix: Use 'string' instead
(lint/complexity/noBannedTypes)
[error] 4-4: Don't use 'String' as a type.
Use lowercase primitives for consistency.
Safe fix: Use 'string' instead
(lint/complexity/noBannedTypes)
[error] 97-97: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
[error] 107-107: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
[error] 161-161: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
[error] 154-154: Don't use '{}' as a type.
Prefer explicitly define the object shape. '{}' means "any non-nullable value".
(lint/complexity/noBannedTypes)
packages/inula-adapter/src/vue/globalAPI.tsx
[error] 175-176: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
🔇 Additional comments (93)
packages/inula-adapter/tests/utils/globalSetup.js (1)
18-27: Consider per-test containers for concurrent tests.Vitest allows
test.concurrent. A single sharedglobalThis.containercan cause race conditions or double-remove errors when tests run in parallel.
Optionally create a fresh, local container per test (returned by a helper) instead of exposing a shared global.
Not blocking, but worth evaluating if you plan to adopt concurrent tests.packages/inula-adapter/examples/$parent/list-item.jsx (1)
1-25: Good implementation of React-style component with vue-inula.The component correctly uses
useInstance()from vue-inula to access parent methods and follows proper React functional component patterns.packages/inula-adapter/.gitignore (1)
1-5: LGTM! Standard gitignore configuration.The gitignore file includes appropriate exclusions for a JavaScript/TypeScript project, covering dependencies, IDE configurations, build artifacts, and lock files.
package.json (2)
22-22: LGTM! Consistent build script pattern.The new build script follows the same pattern as other package-specific build scripts in the project.
1-95: Lockfile regeneration complete
- The pnpm lockfile has been successfully regenerated (
pnpm install --no-frozen-lockfile).- Please commit the updated
pnpm-lock.yamlto this PR to resolve the CI pipeline failure.packages/inula-adapter/src/pinia/index.ts (1)
1-17: LGTM! Clean module entry point structure.The file correctly serves as a simple re-export entry point for the Pinia adapter module. The copyright header and export statement are properly formatted.
packages/inula-adapter/npm/pinia/package.json (1)
1-6: LGTM! Proper package.json configuration.The package.json correctly defines module entry points for different formats (ESM, CJS, and TypeScript declarations), following standard Node.js package conventions.
packages/inula-adapter/src/vuex/index.ts (1)
1-18: LGTM! Comprehensive module exports.The file correctly exports from both the core Vuex adapter and mapping helpers, providing a complete API surface for consumers. The structure follows standard practices.
packages/inula-adapter/examples/$t - plugins/App.jsx (1)
1-7: LGTM! Correct i18n integration pattern.The component correctly demonstrates how to use the
useInstancehook to access Vue's$ttranslation function in a React-style component.packages/inula-adapter/examples/$t - plugins/main.js (1)
1-7: LGTM! Standard Vue app initialization pattern.The code correctly follows Vue 3 application setup patterns with proper import from the vue-inula adapter, plugin installation, and mounting sequence.
packages/inula-adapter/src/vue/keepAlive/context.ts (1)
1-3: LGTM! Properly implemented context creation.The context is correctly typed and initialized with appropriate default value for the keep-alive lifecycle management system.
packages/inula-adapter/npm/vuex/package.json (1)
1-5: LGTM! Package structure follows best practices.The package.json correctly defines entry points for different module systems (ESM, CommonJS) and TypeScript declarations, following standard dual package publishing conventions.
packages/inula-adapter/examples/$root/themeChanger.jsx (1)
1-19: LGTM! Component implementation follows correct patterns.The component correctly uses the
useInstance()hook to access the root instance and implements proper event handling. The JSX structure and prop usage are appropriate for a theme changer component.packages/inula-adapter/examples/$root/root.jsx (1)
12-12: Ignore reactive ref unwrap suggestionThe inula-adapter’s JSX runtime (via openinula.createElement) automatically unwraps reactive refs when assigning props, so passing
themedirectly is correct. No change to<app color={theme} />is needed.Likely an incorrect or invalid review comment.
packages/inula-adapter/examples/$children/FruitItem.jsx (1)
1-25: LGTM! Well-implemented Vue-style functional component.The component correctly demonstrates Vue API compatibility with React-style JSX syntax. The use of
useReffor reactive state anddefineExposefor exposing internal state to parent components follows the expected pattern for the inula-adapter.packages/inula-adapter/vitest.config.ts (2)
18-22: Well-configured alias mapping for OpenInula integration.The alias configuration correctly redirects React imports to OpenInula equivalents, which is essential for the Vue adapter to work properly with the OpenInula framework.
24-32: Proper Vitest configuration for the adapter package.The configuration correctly sets up the React plugin, jsdom environment, and module resolution, providing a solid foundation for testing the Vue adapter functionality.
packages/inula-adapter/.prettierrc.js (1)
18-32: Comprehensive Prettier configuration.The configuration provides appropriate formatting rules for the project, including sensible defaults for line width, indentation, quotes, and other formatting preferences.
packages/inula-adapter/tsconfig.json (1)
1-35: Configuration looks comprehensive and well-structured.The TypeScript configuration covers all necessary compiler options for a mixed JS/TS project with JSX support.
packages/inula-adapter/src/vue/index.ts (1)
16-28: Clean barrel export structure.The module index properly re-exports from all submodules, providing a clean API surface for the Vue adapter package.
packages/inula-adapter/src/vue/injectProvide.tsx (1)
7-16: Ignore React-style Context.Provider advice in Vue adapterThe
provide/injectpair in packages/inula-adapter/src/vue/injectProvide.tsx is a Vue-Composition-API–style implementation that simply stores values by key in a local map. It isn’t part of Inula’s React-style Context.Provider system, so pointing at<Context.Provider>here doesn’t apply. You can safely disregard this suggestion.Likely an incorrect or invalid review comment.
packages/inula-adapter/docs/README_vuex.md (1)
1-188: Documentation provides comprehensive coverage of Vuex limitations.The documentation clearly outlines the key differences and limitations of the Vuex adapter implementation compared to standard Vuex. The code examples effectively demonstrate each limitation, making it easy for developers to understand what features are not supported.
packages/inula-adapter/tests/vuex/vuex.store.test.ts (1)
25-343: Comprehensive test suite with excellent coverage.The test suite provides thorough coverage of the Vuex store functionality including:
- Mutations with both direct and object-style commits
- Synchronous and asynchronous actions with Promise handling
- Getters and their integration with actions
- Subscription mechanisms for both mutations and actions
- Watch API functionality with proper lifecycle testing
- Error handling and edge cases
The tests are well-structured, use appropriate mocking, and properly handle asynchronous operations with
nextTick.packages/inula-adapter/src/vue/vShow.ts (1)
18-38: Correct implementation of v-show directive.The implementation correctly replicates Vue's v-show behavior:
- Uses a Symbol to safely store the original display value
- Properly handles the lifecycle hooks (beforeMount, updated, beforeUnmount)
- Correctly implements the boolean coercion check in the updated hook
- The setDisplay helper function properly toggles between original display and 'none'
The approach of storing the original display value and restoring it when showing the element matches Vue's behavior exactly.
packages/inula-adapter/tests/vue/dynamicComponent.test.tsx (1)
21-68: Well-structured test suite for dynamic components.The test suite effectively covers the main use cases for dynamic components:
- Local component registration and rendering
- Global component registration via app.component()
- DOM element rendering with proper attributes
The test structure is clear and each test case validates the expected behavior appropriately.
packages/inula-adapter/babel.config.js (1)
16-49: LGTM! Well-configured Babel setup for OpenInula JSX transformation.The configuration appropriately sets up TypeScript and JSX transformation with the
openinulaimport source, includes comprehensive plugins for modern JavaScript features, and uses sensible optimization options likeloosemode for better performance.packages/inula-adapter/tests/pinia/pinia.store.test.ts (1)
36-122: LGTM! Comprehensive test coverage for Pinia store functionality.The test suite properly covers store reuse, state initialization, and subscription mechanisms. The test structure is well-organized with proper setup and teardown.
packages/inula-adapter/tests/pinia/pinia.state.test.ts (1)
44-142: LGTM! Comprehensive test coverage for Pinia state functionality.The test suite thoroughly covers state access, reactivity, nested state handling, and watcher functionality. The test structure is well-organized and validates the expected behavior of the Pinia adapter.
packages/inula-adapter/src/vue/dynamicComponent.tsx (1)
38-82: LGTM! Well-implemented dynamic component functionality.The implementation correctly mimics Vue's dynamic component behavior with proper component resolution from both local and global scopes. The
toPascalCasehelper function properly converts Vue-style component names to React-style naming conventions.packages/inula-adapter/tests/vuex/vuex.component.test.tsx (2)
22-67: Good test coverage for Vuex store integration.The test properly verifies store state, mutations, and reactivity within components. The test structure is clean and assertions are comprehensive.
69-116: Excellent test coverage for Vuex helper functions.The test effectively validates the
useMapState,useMapGetters, anduseMapMutationshelper functions, ensuring they work correctly in component contexts.packages/inula-adapter/tests/pinia/pinia.storeToRefs.test.ts (2)
26-32: Well-designed test helper function.The
objectOfRefshelper function is a clever utility for comparing objects containing refs by their values, making the test assertions more readable.
34-141: Comprehensive test coverage for storeToRefs.The test suite thoroughly covers all scenarios including empty states, plain values, setup stores, and computed getters. The tests verify both reading and writing through refs, ensuring proper reactivity.
packages/inula-adapter/scripts/build-types.js (1)
54-64: Good build configuration structure.The
buildTypeConfigfunction and exported configurations are well-structured for bundling TypeScript declarations for the three packages.packages/inula-adapter/tests/pinia/pinia.storeSetup.test.ts (4)
22-22: Type testing function is correctly implemented.The
expectTypefunction is a common pattern for compile-time type checking. The unused parameter is intentional.
24-63: Excellent test coverage for setup store $state behavior.The test thoroughly verifies that
$statecorrectly extracts only state properties, excluding computed values and methods. The reactivity testing is comprehensive.
65-77: Good test for function storage in state.The test properly verifies that functions can be stored as state properties and accessed correctly.
79-156: Comprehensive reactivity and ref unwrapping tests.The tests cover direct state access, reactivity, watchers, and ref unwrapping scenarios. The mixed syntax test (setup vs options) is particularly valuable for ensuring compatibility.
packages/inula-adapter/src/vue/compare.ts (2)
19-31: LGTM! NaN comparison is intentional for Object.is polyfill.The static analysis warnings about "self-compare" are false positives. The
x !== x && y !== ycomparison is the correct way to detect NaN values in the Object.is polyfill, as NaN is the only value that is not equal to itself.
48-50: Potential issue with key comparison logic.The key comparison logic uses
keysX[i]instead ofkeyin the final comparison, which could lead to incorrect results.return keysX.every( - (key, i) => Object.prototype.hasOwnProperty.call(paramY, key) && isSame(paramX[key], paramY[keysX[i]]) + (key) => Object.prototype.hasOwnProperty.call(paramY, key) && isSame(paramX[key], paramY[key]) );Likely an incorrect or invalid review comment.
packages/inula-adapter/tests/vuex/vuex.modules.test.ts (1)
21-480: LGTM! Comprehensive test coverage.The test suite provides excellent coverage of Vuex module functionality including dynamic registration, namespacing, state management, and edge cases. The tests are well-structured and thorough.
packages/inula-adapter/tests/vue/injectProvide.test.tsx (1)
24-111: LGTM! Comprehensive inject/provide tests.The test suite provides good coverage of the inject/provide functionality including basic usage, default values, and symbol keys. The tests are well-structured and validate the expected behavior.
packages/inula-adapter/tests/vue/liftcycle.test.tsx (1)
162-190: LGTM! Well-structured lifecycle tests.The lifecycle tests provide good coverage of the Vue lifecycle hooks and validate their timing correctly. The test structure and assertions (except for the onUnmounted issue noted above) are appropriate.
packages/inula-adapter/tests/vue/sfcAPI.test.tsx (2)
23-72: Well-structured test for defineExpose functionality.The test correctly verifies that:
- Methods exposed via
defineExposeare accessible from parent components- The reactive state updates properly when exposed methods are called
- The ref mechanism works correctly with
useInstance
74-128: Comprehensive test for multiple exposed properties.This test effectively validates that both reactive references and methods can be exposed simultaneously and accessed correctly from parent components.
packages/inula-adapter/tests/vuex/vuex.maps.test.tsx (1)
22-639: Excellent comprehensive test coverage for Vuex mapping utilities.This test suite provides thorough coverage of all Vuex mapping utilities with multiple scenarios:
- Array mapping: Tests simple array-based mapping for all utilities
- Object mapping: Tests object-based mapping with custom names
- Function mapping: Tests function-based mapping with custom logic
- Namespace support: Validates namespaced module functionality
- Integration: Tests all utilities working together
The test patterns correctly validate:
- Reactive state updates for
useMapStateanduseMapGetters- Proper mutation commits for
useMapMutations- Action dispatching for
useMapActions- Mock function usage for action verification
packages/inula-adapter/src/vue/keepAlive/keeper.tsx (4)
10-16: Well-structured component interface and state management.The component properly initializes refs for DOM elements, child nodes, and lifecycle callbacks. The structure is clean and follows React patterns.
18-27: Proper cleanup on component unmount.The cleanup effect correctly removes DOM nodes and triggers deactivation callbacks when the component unmounts, preventing memory leaks.
48-57: Context provider implementation is correct.The component properly provides the lifecycle context to descendant components, enabling them to register activation/deactivation callbacks.
29-46: Verify wrapper existence and add comprehensive keep-alive testsBefore manipulating DOM, it’s safest to guard against missing refs—and without existing tests covering rapid toggle or nested‐component scenarios, we can’t be confident there aren’t subtle race conditions or event-listener losses. Please:
• Add a null check at the top of the effect
• Only move a child if its currentparentElementmatches your expectation
• Expand your test suite underpackages/inula-adapter/tests/to cover:
– Rapid toggling ofactive
– Nested keep-alive components
– Preservation of event listeners after activation/unactivationSuggested diff:
useEffect(() => { + if (!wrapper.current) return; + if (active) { childrenNode.current = Array.from(wrapper.current.children); childrenNode.current.forEach(child => { - wrapper.current?.parentElement?.insertBefore(child, wrapper.current); + if (child.parentElement === wrapper.current && wrapper.current.parentElement) { + wrapper.current.parentElement.insertBefore(child, wrapper.current); + } }); nodeKeeperLifeCycleValue.current[KEEP_ALIVE_LIFECYCLE.ACTIVATE] .forEach(callback => callback()); } else { childrenNode.current.forEach(child => { - wrapper.current?.appendChild(child); + if (wrapper.current && child.parentElement !== wrapper.current) { + wrapper.current.appendChild(child); + } }); nodeKeeperLifeCycleValue.current[KEEP_ALIVE_LIFECYCLE.UNACTIVATE] .forEach(callback => callback()); } }, [active]);packages/inula-adapter/src/vue/condition.tsx (2)
18-31: LGTM: Clean interface definitions and component implementations.The conditional props interface and component implementations are well-structured. The
Ifcomponent correctly renders children based on condition, and theElsecomponent uses proper TypeScript typing withOmit.
37-52: LGTM: Solid ConditionalRenderer implementation.The
ConditionalRenderercorrectly implements the logic to find the first matching condition among children, handling bothIf/ElseIfcomponents with true conditions andElsecomponents. The use ofChildren.toArrayandisValidElementensures safe child element handling.packages/inula-adapter/tests/vue/props.test.tsx (3)
22-69: LGTM: Comprehensive reactive props testing.The first test properly validates that reactive props work with numeric values, including state updates and computed values. The test structure is well-organized with proper setup and assertions.
71-159: LGTM: Thorough array reactivity testing.The second test comprehensively covers array prop reactivity, including:
- Array replacement operations
- Array mutation operations (push)
- Default prop values with functions
- Proper use of
nextTickfor async reactivity
161-194: LGTM: Edge case testing for empty arrays.The third test validates the specific edge case of setting empty arrays and subsequent mutations, ensuring reactivity works correctly in these scenarios.
packages/inula-adapter/tests/pinia/pinia.getters.test.ts (1)
65-97: LGTM: Comprehensive getter testing.The test suite effectively validates:
- Getter computation and reactivity
- State updates triggering getter recalculation
- Getter composition (using other getters)
- Reactivity preservation during state hydration
packages/inula-adapter/tests/pinia/pinia.actions.test.ts (4)
19-69: LGTM: Well-structured store factory function.The
createStorefunction provides a comprehensive test store with state, getters, and actions covering various scenarios including async operations, error handling, and nested state mutations.
77-101: LGTM: Comprehensive action testing.The tests effectively validate:
- Correct
thiscontext binding in actions- State mutations through actions
- Action composition and inter-action calls
- Proper handling of forced context
102-121: LGTM: Thorough error handling testing.The tests properly validate both synchronous and asynchronous error handling, including error catching and propagation.
122-139: LGTM: Robust destructuring and context testing.The test validates that destructured actions work correctly even with altered
thiscontext, which is important for developer experience and debugging scenarios.packages/inula-adapter/tests/vue/condition.test.tsx (3)
26-73: LGTM: Comprehensive conditional rendering testing.The first test effectively validates the
ConditionalRendererlogic with different conditions, ensuring correct branch selection and rendering updates.
75-168: LGTM: Thorough reactive data testing.The second test comprehensively validates conditional rendering with reactive data, covering multiple conditions and state transitions. The test scenarios closely mirror real-world usage patterns.
170-208: LGTM: Edge case testing with ref arrays.The third test validates conditional rendering with object properties and provides good coverage of edge cases where formatters might be undefined.
packages/inula-adapter/src/vue/helper.tsx (2)
22-69: LGTM! Function correctly handles multiple input types.The
setToInstancefunction properly handles objects, arrays, and functions with appropriate error handling and warnings for invalid inputs.
77-120: LGTM! Helper functions are well-implemented.The helper functions handle camelCase conversion and style processing correctly, with proper handling of numeric values and special CSS properties.
packages/inula-adapter/src/vue/semiControlledComponent.tsx (4)
45-57: LGTM! Props handling and state initialization are correct.The component properly handles default values and initializes internal state from props.
70-70: Verify synthetic event structure matches OpenInula expectations.The synthetic event creation should match OpenInula's ChangeEvent interface structure. Ensure the event object has all required properties.
Consider adding more properties to the synthetic event object to match the full ChangeEvent interface:
- onChange({ target: { value: newValue } } as ChangeEvent<HTMLInputElement>); + onChange({ + target: { value: newValue, ...input }, + currentTarget: input, + type: 'change' + } as ChangeEvent<HTMLInputElement>);
98-104: LGTM! Standard event handling is correct.The onChange handler properly manages state updates and event propagation.
60-95: Please validate cross-browser compatibility of thevaluesetter overrideOverriding the native
valueproperty on an<input>is clever but can behave differently across environments. Before merging, manually verify:• Chrome, Firefox, Safari (including mobile browsers)
• Common input types (text, number, email, password, etc.)
• Programmatic updates from external libraries or frameworksNo other instances of this pattern were found in the codebase, so ensure this change doesn’t introduce regressions.
packages/inula-adapter/docs/README_global_api.md (2)
1-268: Comprehensive documentation with clear examples.The documentation provides thorough coverage of the global API features with practical examples and migration guidance. The distinction between supported and unsupported features is clearly communicated.
59-210: Excellent migration example from Vue mixins to hooks.The detailed example showing how to convert Vue mixins to OpenInula hooks is particularly valuable for developers migrating from Vue. The side-by-side comparison makes the migration path clear.
packages/inula-adapter/tests/vue/attrs.test.tsx (1)
21-370: Comprehensive test coverage for $attrs behavior.The test suite thoroughly covers:
- CSS class inheritance and merging
- Style object merging with precedence rules
- Deep merging across component hierarchies
- Scoped attribute inheritance
- Different component types (functional, class, memo, forwardRef)
The tests validate the correct behavior of attribute inheritance in the Vue adapter.
packages/inula-adapter/src/vue/props.tsx (4)
39-54: LGTM! Reactive props hook is well-implemented.The
useReactivePropshook correctly manages reactive props with proper initialization and updates. The use ofuseRefensures reference stability across renders.
77-94: Robust default value handling.The
setFullPropsfunction properly handles both raw props and default values with appropriate precedence rules. The use ofhasOwnPropertychecks ensures proper property ownership validation.
116-130: Smart default value resolution.The
resolvePropValuefunction correctly distinguishes between function defaults and Function-type props, ensuring proper default value application.
51-51: Good integration with scoped attributes.The call to
useScoped()ensures that scoped attributes are properly handled alongside reactive props, maintaining the Vue component model.packages/inula-adapter/tests/vue/globalAPI.test.tsx (1)
16-368: Comprehensive test coverage is excellent.The test suite provides thorough coverage of the global API functionality including app creation, mounting, plugins, dependency injection, component registration, and async components. The tests are well-structured and cover both success and edge cases.
packages/inula-adapter/tests/vue/keepAlivePro.test.tsx (1)
54-262: Comprehensive KeepAlivePro testing.The test suite provides excellent coverage of KeepAlivePro functionality including:
- Basic caching and state preservation
- Maximum instance limits with proper eviction
- Component filtering with include/exclude patterns
- Lifecycle hook integration (onActivated/onDeactivated)
The async handling and DOM assertions are well-implemented.
packages/inula-adapter/src/vue/lifecycle.ts (1)
37-69: Lifecycle hook implementations look correct.The remaining lifecycle hooks (
onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted) are properly implemented using the appropriate openinula hooks with correct timing and cleanup.packages/inula-adapter/tests/vue/directive.test.tsx (2)
77-77: Ignore ESLint warnings for directive callback parameters.The ESLint warnings about unused
elandbindingparameters are false positives. These parameters are part of the Vue directive API contract and should be preserved even if not used in test mocks, as they document the expected interface.Also applies to: 87-87, 123-123, 134-134, 139-139
23-262: Comprehensive directive testing.The test suite provides excellent coverage of directive functionality including:
- DOM element directives with lifecycle hooks (mounted, updated, unmounted)
- Component directives with custom registration
- Built-in v-show directive behavior
- Event simulation and DOM interaction testing
- Proper cleanup and lifecycle management
The tests effectively validate the DirectiveComponent wrapper and directive integration.
packages/inula-adapter/src/vue/keepAlive/lifeCycleHooks.ts (3)
4-7: Well-defined lifecycle events.The enum clearly defines the activation lifecycle events with descriptive names that follow component lifecycle naming conventions.
10-28: Robust lifecycle hook implementation.The
useActivationhook properly:
- Checks for KeepAlive context availability
- Manages callback replacement vs addition logic
- Uses refs to track previous callbacks
- Handles effect dependencies correctly
The implementation ensures callbacks are properly updated when dependencies change.
30-34: Clean API design with bound hooks.The bound hooks (
useActivatePro,useUnActivatePro) provide a clean API for consumers while the type definition properly documents the expected context structure.packages/inula-adapter/tests/vue/keepAlive.test.tsx (2)
52-89: Well-structured test for basic KeepAlive functionalityThe test comprehensively covers state preservation and DOM caching behavior.
91-270: Comprehensive test coverage for KeepAlive featuresThe test suite thoroughly covers:
- Cache size limiting with
maxprop- Include/exclude filtering with string and regex patterns
- Activation/deactivation lifecycle hooks
All tests properly use
act()for state updates and verify DOM structure correctly.packages/inula-adapter/src/pinia/pinia.ts (1)
72-93: Correct implementation of action parameter adjustmentThe function properly removes the first
storeparameter that openinula injects but Pinia doesn't require, ensuring compatibility between the two APIs.packages/inula-adapter/src/vuex/types.ts (1)
1-108: Well-designed type system for Vuex adapterThe type definitions provide comprehensive type safety with:
- Proper generic constraints for state, mutations, actions, and getters
- Utility types that correctly transform function signatures
- Support for nested modules with namespacing
- Integration with openinula's StoreObj type
packages/inula-adapter/src/vuex/vuex.ts (2)
82-114: Well-structured mutation and action dispatchingThe implementation correctly handles:
- Root-level mutations/actions with
options.root- Namespaced module syntax with
/delimiter- Broadcasting to non-namespaced modules
- Promise aggregation for action results
Also applies to: 115-153
313-324: Proper cleanup implementation for dynamic module unregistrationThe
deleteGettersfunction correctly resets property descriptors before deletion, ensuring clean removal of dynamically registered getters.packages/inula-adapter/src/pinia/types.ts (1)
23-103: Well-designed type definitions for Pinia adapterThe type definitions are comprehensive and properly handle:
- Generic constraints for store state, actions, and getters
- Proper
thiscontext binding usingThisType- Complex conditional types for filtering properties
- Type-safe store-to-refs conversion
packages/inula-adapter/src/vue/globalAPI.tsx (2)
259-273: Well-implemented event emission with Vue compatibilityThe
emitfunction properly handles:
- Direct event names and Vue-style 'on' prefixed handlers
- Proper argument forwarding
- Helpful warnings for missing handlers
292-328: Robust window size tracking implementationThe
useWindowSizehook provides:
- Proper event listener cleanup
- Configurable scrollbar inclusion
- Optional orientation change listening
- Safe initial value handling
| <script> | ||
| setInterval(()=>{ | ||
| this.$forceUpdate(); | ||
| },1000) | ||
| </script> No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Vue component structure and lifecycle management.
The current implementation has several critical issues:
- Missing proper Vue component export structure
- The
setIntervalruns immediately when the script loads, not within component lifecycle - No cleanup mechanism, which will cause memory leaks
- Multiple intervals may be created if the component is re-instantiated
Apply this diff to fix the component structure and lifecycle management:
-<script>
- setInterval(()=>{
- this.$forceUpdate();
- },1000)
-</script>
+<script>
+export default {
+ name: 'Clock',
+ data() {
+ return {
+ intervalId: null
+ }
+ },
+ mounted() {
+ this.intervalId = setInterval(() => {
+ this.$forceUpdate();
+ }, 1000);
+ },
+ beforeDestroy() {
+ if (this.intervalId) {
+ clearInterval(this.intervalId);
+ }
+ }
+}
+</script>🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$forceUpdate/clock.vue around lines 5 to 9,
the script incorrectly runs setInterval immediately without proper Vue component
structure or lifecycle management, causing potential memory leaks and multiple
intervals on re-instantiation. Refactor the code to define and export a Vue
component properly, move the setInterval call inside the mounted lifecycle hook,
and clear the interval in the beforeUnmount hook to ensure cleanup.
| useEffect(() => { | ||
| const [b, r] = useState(false); // by toggling this state object, force update is triggered | ||
| const interval = setInterval(() => { | ||
| r(!b); | ||
| }, 1000); | ||
|
|
||
| return () => { | ||
| clearInterval(interval); | ||
| }; | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix critical React hooks usage and missing imports.
The current implementation has several critical issues:
useEffectanduseStateare used but not importeduseStateis incorrectly called insideuseEffect(hooks must be called at the top level)- The force update logic is flawed
Apply this diff to fix the implementation:
+import { useState, useEffect } from 'react';
+
export default function Clock() {
+ const [, forceUpdate] = useState(false);
+
- // useeffect and clearInterval operation mas no sense, but this is necessary
+ // useEffect and clearInterval operation may not make sense, but this is necessary
// to prevent problems between persistent vue components and temporary inula function components
useEffect(() => {
- const [b, r] = useState(false); // by toggling this state object, force update is triggered
const interval = setInterval(() => {
- r(!b);
+ forceUpdate(prev => !prev);
}, 1000);
return () => {
clearInterval(interval);
};
- });
+ }, []);
return <span>{Date.now()}</span>;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useEffect(() => { | |
| const [b, r] = useState(false); // by toggling this state object, force update is triggered | |
| const interval = setInterval(() => { | |
| r(!b); | |
| }, 1000); | |
| return () => { | |
| clearInterval(interval); | |
| }; | |
| }); | |
| import { useState, useEffect } from 'react'; | |
| export default function Clock() { | |
| const [, forceUpdate] = useState(false); | |
| // useEffect and clearInterval operation may not make sense, but this is necessary | |
| // to prevent problems between persistent vue components and temporary inula function components | |
| useEffect(() => { | |
| const interval = setInterval(() => { | |
| forceUpdate(prev => !prev); | |
| }, 1000); | |
| return () => { | |
| clearInterval(interval); | |
| }; | |
| }, []); | |
| return <span>{Date.now()}</span>; | |
| } |
🧰 Tools
🪛 ESLint
[error] 4-4: 'useEffect' is not defined.
(no-undef)
[error] 5-5: 'useState' is not defined.
(no-undef)
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$forceUpdate/clock.jsx around lines 4 to 13,
fix the React hooks usage by importing useEffect and useState at the top of the
file, move the useState call outside of useEffect to the top level of the
component, and update the force update logic by toggling the state correctly
inside the setInterval callback. Also, add an empty dependency array to
useEffect to ensure the interval is set up only once and cleaned up properly.
| <script> | ||
| const { productId,productName,productType } = defineProps([ 'productId', 'productName', 'productType' ]); | ||
|
|
||
| function filterType(type){ | ||
| this.$parent.setFilterType(type); | ||
| } | ||
| </script> No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Vue Composition API syntax and missing imports.
Several issues with the Vue component implementation:
definePropsis used outside of<script setup>context- The
filterTypefunction is not accessible in the template - Missing required imports for Vue composition functions
this.$parentaccess won't work in this context
Apply this diff to fix the component:
-<script>
+<script setup>
+import { inject } from 'vue';
+
- const { productId,productName,productType } = defineProps([ 'productId', 'productName', 'productType' ]);
+ const { productId, productName, productType } = defineProps(['productId', 'productName', 'productType']);
+
+ // Use inject to get parent methods instead of this.$parent
+ const parentMethods = inject('parentMethods', {});
- function filterType(type){
- this.$parent.setFilterType(type);
- }
+ function filterType(type) {
+ parentMethods.setFilterType?.(type);
+ }
</script>🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$parent/list-item.vue around lines 13 to 19,
the script uses defineProps outside of <script setup>, the filterType function
is not exposed to the template, required Vue composition imports are missing,
and this.$parent access is invalid. To fix, convert the script to use <script
setup> syntax, import necessary Vue functions, define filterType as a function
within the setup context, and replace this.$parent with an appropriate emit or
provide/inject pattern to communicate with the parent component.
| Product type | ||
| </td> | ||
| </tr> | ||
| <table-item v-for="item in filteredIdems" productId="item.id" productName="item.name" productType="item.type"></table-item> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix prop binding in v-for directive.
The props are passed as string literals instead of expressions, which will render the literal text "item.id" instead of the actual values.
Apply this diff to fix the prop binding:
- <table-item v-for="item in filteredIdems" productId="item.id" productName="item.name" productType="item.type"></table-item>
+ <table-item v-for="item in filteredIdems" :key="item.id" :productId="item.id" :productName="item.name" :productType="item.type"></table-item>🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$parent/list.vue at line 14, the props
productId, productName, and productType are incorrectly passed as string
literals instead of dynamic expressions. Fix this by binding the props using
v-bind syntax or shorthand, for example :productId="item.id",
:productName="item.name", and :productType="item.type" to pass the actual values
from each item in filteredIdems.
| <script> | ||
| const {items} = defineProps(['items']); | ||
|
|
||
| const filteredIdems = ref(items); | ||
|
|
||
| function setFilterType(type){ | ||
| filteredItems.value = items.filter(item => item.type===type); | ||
| } | ||
|
|
||
| defineExpose({setFilterType}) | ||
| </script> No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix variable naming inconsistency and missing imports.
Multiple issues with the script section:
- Variable name typo:
filteredIdemsvsfilteredItems - Missing required imports for Vue composition functions
- Should use
<script setup>syntax
Apply this diff to fix the issues:
-<script>
+<script setup>
+import { ref, defineProps, defineExpose } from 'vue';
+
const {items} = defineProps(['items']);
- const filteredIdems = ref(items);
+ const filteredItems = ref(items);
function setFilterType(type){
filteredItems.value = items.filter(item => item.type===type);
}
defineExpose({setFilterType})
</script>Also update the template to use the correct variable name:
- <table-item v-for="item in filteredIdems" :key="item.id" :productId="item.id" :productName="item.name" :productType="item.type"></table-item>
+ <table-item v-for="item in filteredItems" :key="item.id" :productId="item.id" :productName="item.name" :productType="item.type"></table-item>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$parent/list.vue around lines 17 to 27, fix
the typo by renaming the variable from filteredIdems to filteredItems for
consistency. Add the missing imports for ref, defineProps, and defineExpose from
'vue' at the top of the script. Change the script tag to use the <script setup>
syntax to align with Vue 3 composition API best practices. Also, update any
template references to use the corrected filteredItems variable name.
| if(!this.$refs[0].value){ | ||
| this.$refs[0].focus(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix $refs access to use the named reference.
The code accesses $refs[0] but should use $refs.myInput to match the ref attribute in the template.
- if(!this.$refs[0].value){
- this.$refs[0].focus();
+ if(!this.$refs.myInput.value){
+ this.$refs.myInput.focus();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if(!this.$refs[0].value){ | |
| this.$refs[0].focus(); | |
| if(!this.$refs.myInput.value){ | |
| this.$refs.myInput.focus(); |
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$refs/refresh.vue around lines 10 to 11, the
code incorrectly accesses this.$refs using an index (this.$refs[0]) instead of
the named reference. Update the code to use this.$refs.myInput to correctly
reference the element by its ref attribute name.
| <template> | ||
| <iv> | ||
| <input ref="myInput" type="text" /> | ||
| <button @click="validateAndSubmit">submit</button> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define the missing validateAndSubmit method.
The template references validateAndSubmit but this method is not defined in the script section.
<script>
+ function validateAndSubmit() {
+ validate();
+ }
+
function validate(){Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$refs/refresh.vue at line 4, the template
uses a method called validateAndSubmit on the button click event, but this
method is not defined in the script section. To fix this, define a
validateAndSubmit method inside the script section of the Vue component that
handles the form validation and submission logic as intended.
| @@ -0,0 +1,16 @@ | |||
| <template> | |||
| <iv> | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the HTML tag typo.
The <iv> tag appears to be a typo and should be <div>.
- <iv>
+ <div>- </iv>
+ </div>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <iv> | |
| <div> | |
| </div> |
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$refs/refresh.vue at line 2, the HTML tag
<iv> is a typo and should be corrected to <div>. Replace the <iv> tag with <div>
to fix the markup.
| if(!this.$refs[0].value){ | ||
| this.$refs[0].focus(); | ||
| } else { | ||
| submit() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define the missing submit function.
The submit() function is called but not defined or imported.
+ function submit() {
+ // TODO: Implement submit logic
+ console.log('Form submitted');
+ }
+
function validate(){📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| submit() | |
| function submit() { | |
| // TODO: Implement submit logic | |
| console.log('Form submitted'); | |
| } | |
| function validate(){ | |
| // existing validate logic… | |
| } |
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$refs/refresh.vue at line 13, the submit()
function is called but not defined or imported. Define the submit function
within the component's script section or import it if it exists externally.
Ensure the function is properly declared before it is called to avoid runtime
errors.
| // this timeout should be wrapped as an adapter that way you can call only $nextClick( ... ) as usual | ||
| const timeout = setTimeout(() => { | ||
| // this must be wrapped, because at the time of render, this element does not exist yet | ||
| useInstance().$refs.inp.$el.attachEventListener('keyUp', e => { | ||
| console.log(e); | ||
| }); | ||
| }, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider abstracting the timeout logic into a proper adapter.
As suggested by the comments, this setTimeout workaround should be wrapped in an adapter to provide a cleaner $nextTick API.
Consider creating a $nextTick adapter function that encapsulates this logic for better reusability and cleaner API usage.
🧰 Tools
🪛 ESLint
[error] 7-7: 'useInstance' is not defined.
(no-undef)
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$nextTick/nextTick.jsx around lines 4 to 10,
the setTimeout logic used to delay attaching the event listener should be
refactored into a dedicated $nextTick adapter function. Create a reusable
$nextTick adapter that wraps this timeout and callback logic, so callers can
simply invoke $nextTick(callback) to run code after the next DOM update,
improving code clarity and reusability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review continued from previous batch...
| @@ -0,0 +1,18 @@ | |||
| export default function (props) { | |||
| // inula rendering is synchronous, so this timeout appends this function at next asynchronous position to execute after render | |||
| useEffect(() => { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing import for useEffect.
The useEffect hook is used but not imported.
+import { useEffect } from 'openinula';
+
export default function (props) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useEffect(() => { | |
| import { useEffect } from 'openinula'; | |
| export default function (props) { | |
| useEffect(() => { | |
| // ... | |
| }); | |
| // rest of component | |
| } |
🧰 Tools
🪛 ESLint
[error] 3-3: 'useEffect' is not defined.
(no-undef)
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$nextTick/nextTick.jsx at line 3, the
useEffect hook is used but not imported. Add an import statement for useEffect
from 'react' at the top of the file along with other React imports to ensure the
hook is available.
| // this timeout should be wrapped as an adapter that way you can call only $nextClick( ... ) as usual | ||
| const timeout = setTimeout(() => { | ||
| // this must be wrapped, because at the time of render, this element does not exist yet | ||
| useInstance().$refs.inp.$el.attachEventListener('keyUp', e => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing import for useInstance.
The useInstance hook is used but not imported.
+import { useInstance } from 'vue-inula';
+
export default function (props) {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useInstance().$refs.inp.$el.attachEventListener('keyUp', e => { | |
| import { useInstance } from 'vue-inula'; | |
| export default function (props) { | |
| useInstance().$refs.inp.$el.attachEventListener('keyUp', e => { |
🧰 Tools
🪛 ESLint
[error] 7-7: 'useInstance' is not defined.
(no-undef)
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$nextTick/nextTick.jsx at line 7, the
useInstance hook is used but not imported. Add an import statement for
useInstance from its appropriate module at the top of the file to ensure it is
properly referenced.
| export function inject(name, defaultValue?) { | ||
| // If variable exists, local value is returned | ||
| if (contextMap.has(name)) { | ||
| const ctx = contextMap.get(name); | ||
| return ctx.value; | ||
| } | ||
| // If there is no fallback value, error is thrown | ||
| if (!defaultValue) { | ||
| throw Error('Injected value is not provided. Make sure to provide it before use or add default value'); | ||
| } | ||
| return defaultValue; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the inject function logic and context usage.
There are several issues with the current implementation:
- The default value check
!defaultValuewill fail for falsy values like0,false, or empty string - The context is not being used properly -
ctx.valueshould be accessed viauseContext(ctx) - The provide/inject pattern needs to work within the React component tree
-export function inject(name, defaultValue?) {
+export function inject(name, defaultValue?) {
// If variable exists, local value is returned
if (contextMap.has(name)) {
const ctx = contextMap.get(name);
- return ctx.value;
+ return useContext(ctx);
}
// If there is no fallback value, error is thrown
- if (!defaultValue) {
+ if (defaultValue === undefined) {
throw Error('Injected value is not provided. Make sure to provide it before use or add default value');
}
return defaultValue;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function inject(name, defaultValue?) { | |
| // If variable exists, local value is returned | |
| if (contextMap.has(name)) { | |
| const ctx = contextMap.get(name); | |
| return ctx.value; | |
| } | |
| // If there is no fallback value, error is thrown | |
| if (!defaultValue) { | |
| throw Error('Injected value is not provided. Make sure to provide it before use or add default value'); | |
| } | |
| return defaultValue; | |
| } | |
| export function inject(name, defaultValue?) { | |
| // If variable exists, local value is returned | |
| if (contextMap.has(name)) { | |
| const ctx = contextMap.get(name); | |
| return useContext(ctx); | |
| } | |
| // If there is no fallback value, error is thrown | |
| if (defaultValue === undefined) { | |
| throw Error('Injected value is not provided. Make sure to provide it before use or add default value'); | |
| } | |
| return defaultValue; | |
| } |
🤖 Prompt for AI Agents
In packages/inula-adapter/src/vue/injectProvide.tsx around lines 18 to 29, the
inject function incorrectly checks for defaultValue using a falsy check which
fails for valid falsy values like 0 or false. Also, it accesses contextMap
values directly instead of using useContext to retrieve the current context
value. To fix this, change the defaultValue check to explicitly check for
undefined, use useContext with the retrieved context from contextMap, and ensure
the function integrates properly with React's provide/inject pattern by
returning the context value from useContext or the defaultValue if provided.
| {fruits.map(fruit => ( | ||
| <li> | ||
| <p>Fruit: {fruit.name}</p> | ||
| <p> | ||
| Amount:{' '} | ||
| <button | ||
| onClick={() => { | ||
| decrement(fruit); | ||
| }} | ||
| > | ||
| - | ||
| </button>{' '} | ||
| {fruit.amount}{' '} | ||
| <button | ||
| onClick={() => { | ||
| increment(fruit); | ||
| }} | ||
| > | ||
| + | ||
| </button> | ||
| </p> | ||
| </li> | ||
| ))} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add missing key prop for list items.
React requires a key prop for each item in a list to help with efficient re-rendering.
- {fruits.map(fruit => (
- <li>
+ {fruits.map((fruit, index) => (
+ <li key={index}>Better yet, if fruits have unique names, use the name as the key:
- {fruits.map(fruit => (
- <li>
+ {fruits.map(fruit => (
+ <li key={fruit.name}>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {fruits.map(fruit => ( | |
| <li> | |
| <p>Fruit: {fruit.name}</p> | |
| <p> | |
| Amount:{' '} | |
| <button | |
| onClick={() => { | |
| decrement(fruit); | |
| }} | |
| > | |
| - | |
| </button>{' '} | |
| {fruit.amount}{' '} | |
| <button | |
| onClick={() => { | |
| increment(fruit); | |
| }} | |
| > | |
| + | |
| </button> | |
| </p> | |
| </li> | |
| ))} | |
| {fruits.map(fruit => ( | |
| <li key={fruit.name}> | |
| <p>Fruit: {fruit.name}</p> | |
| <p> | |
| Amount:{' '} | |
| <button | |
| onClick={() => { | |
| decrement(fruit); | |
| }} | |
| > | |
| - | |
| </button>{' '} | |
| {fruit.amount}{' '} | |
| <button | |
| onClick={() => { | |
| increment(fruit); | |
| }} | |
| > | |
| + | |
| </button> | |
| </p> | |
| </li> | |
| ))} |
🧰 Tools
🪛 Biome (1.9.4)
[error] 25-25: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$set/fruits.jsx between lines 24 and 46, the
list items rendered inside the fruits.map() call are missing a key prop. To fix
this, add a unique key prop to each <li> element, preferably using fruit.name if
it is unique, like key={fruit.name}, to help React efficiently identify and
update list items during re-renders.
| function addFruit() { | ||
| const fruitName = useInstance().$refs.newFruit.value; | ||
| this.$set(fruits, fruits.length, { name: fruitName, amount: 0 }); // how should we do this? Will use of reactive handle this case automaticaly? | ||
| useInstance().$refs.newFruit.value = ''; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix critical issues in addFruit function.
The function has several critical issues:
useInstanceis not imported- Mixing
this.$setwithuseInstance()is incorrect for functional components - With reactive arrays, direct manipulation should work without
$set
+import { useInstance } from 'vue-inula';
+
export default function () {
// ... existing code ...
function addFruit() {
- const fruitName = useInstance().$refs.newFruit.value;
- this.$set(fruits, fruits.length, { name: fruitName, amount: 0 }); // how should we do this? Will use of reactive handle this case automaticaly?
- useInstance().$refs.newFruit.value = '';
+ const instance = useInstance();
+ const fruitName = instance.$refs.newFruit.value;
+ fruits.push({ name: fruitName, amount: 0 }); // reactive arrays handle this automatically
+ instance.$refs.newFruit.value = '';
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function addFruit() { | |
| const fruitName = useInstance().$refs.newFruit.value; | |
| this.$set(fruits, fruits.length, { name: fruitName, amount: 0 }); // how should we do this? Will use of reactive handle this case automaticaly? | |
| useInstance().$refs.newFruit.value = ''; | |
| } | |
| import { useInstance } from 'vue-inula'; | |
| export default function () { | |
| // ... existing code ... | |
| function addFruit() { | |
| const instance = useInstance(); | |
| const fruitName = instance.$refs.newFruit.value; | |
| fruits.push({ name: fruitName, amount: 0 }); // reactive arrays handle this automatically | |
| instance.$refs.newFruit.value = ''; | |
| } | |
| } |
🧰 Tools
🪛 ESLint
[error] 16-16: 'useInstance' is not defined.
(no-undef)
[error] 18-18: 'useInstance' is not defined.
(no-undef)
🤖 Prompt for AI Agents
In packages/inula-adapter/examples/$set/fruits.jsx around lines 15 to 19, fix
the addFruit function by first importing useInstance if needed, then remove the
incorrect use of this.$set since this is a functional component. Instead,
directly push the new fruit object into the reactive fruits array to update it
properly. Also, ensure you access the input value via
useInstance().$refs.newFruit.value and clear it afterward as done currently.
| // 给getters的key增加一个前缀,避免和actions, mutations的key冲突 | ||
| `${GETTER_PREFIX}${key}`, | ||
| // 重新定义getter的方法,绑定this,修改参数: state, getters, rootState, rootGetters | ||
| function (state: Record<string, unknown>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused parameter in getter wrapper
The state parameter in the getter wrapper function is not used.
- function (state: Record<string, unknown>) {
+ function () {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function (state: Record<string, unknown>) { | |
| function () { |
🧰 Tools
🪛 ESLint
[error] 278-278: 'state' is defined but never used.
(@typescript-eslint/no-unused-vars)
🤖 Prompt for AI Agents
In packages/inula-adapter/src/vuex/vuex.ts at line 278, the getter wrapper
function has an unused parameter named 'state'. Remove this 'state' parameter
from the function definition to clean up the code and avoid unused parameter
warnings.
| import { VuexStore, VuexStoreOptions } from './types'; | ||
| import { AnyFunction } from '../vuex/types'; | ||
|
|
||
| const { watch, useComputed, computed } = vueReactive; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused destructured variables
The variables useComputed and computed are destructured from vueReactive but never used in the code.
-const { watch, useComputed, computed } = vueReactive;
+const { watch } = vueReactive;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { watch, useComputed, computed } = vueReactive; | |
| - const { watch, useComputed, computed } = vueReactive; | |
| + const { watch } = vueReactive; |
🧰 Tools
🪛 ESLint
[error] 20-20: 'useComputed' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
[error] 20-20: 'computed' is assigned a value but never used.
(@typescript-eslint/no-unused-vars)
🤖 Prompt for AI Agents
In packages/inula-adapter/src/vuex/vuex.ts at line 20, the variables useComputed
and computed are destructured from vueReactive but never used. Remove
useComputed and computed from the destructuring assignment, keeping only watch
if it is used elsewhere in the code.
| export function useStore(key = storeKey) { | ||
| getStoreXCache!(); | ||
| return storeMap.get(key); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add null check for getStoreXCache
The useStore function uses a non-null assertion on getStoreXCache without validation. This could throw if createStore hasn't been called yet.
export function useStore(key = storeKey) {
- getStoreXCache!();
+ if (!getStoreXCache) {
+ throw new Error('Store has not been created. Call createStore() first.');
+ }
+ getStoreXCache();
return storeMap.get(key);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function useStore(key = storeKey) { | |
| getStoreXCache!(); | |
| return storeMap.get(key); | |
| } | |
| export function useStore(key = storeKey) { | |
| if (!getStoreXCache) { | |
| throw new Error('Store has not been created. Call createStore() first.'); | |
| } | |
| getStoreXCache(); | |
| return storeMap.get(key); | |
| } |
🤖 Prompt for AI Agents
In packages/inula-adapter/src/vuex/vuex.ts around lines 339 to 342, the useStore
function calls getStoreXCache with a non-null assertion but does not check if
getStoreXCache is defined, which can cause a runtime error if createStore hasn't
been called. Add a null or undefined check before calling getStoreXCache to
ensure it is initialized, and handle the case where it is not set, such as
throwing a clear error or returning a fallback value.
| mixin(mixin) { | ||
| // 不支持 | ||
| console.log('Inula中暂时不支持mixin,请用Hook方式进行改造代码。'); | ||
| return app; | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unused parameter from mixin method
The mixin parameter is not used since the feature is unsupported.
- mixin(mixin) {
+ mixin() {
// 不支持
console.log('Inula中暂时不支持mixin,请用Hook方式进行改造代码。');
return app;
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| mixin(mixin) { | |
| // 不支持 | |
| console.log('Inula中暂时不支持mixin,请用Hook方式进行改造代码。'); | |
| return app; | |
| }, | |
| mixin() { | |
| // 不支持 | |
| console.log('Inula中暂时不支持mixin,请用Hook方式进行改造代码。'); | |
| return app; | |
| }, |
🧰 Tools
🪛 ESLint
[error] 129-129: 'mixin' is defined but never used.
(@typescript-eslint/no-unused-vars)
🤖 Prompt for AI Agents
In packages/inula-adapter/src/vue/globalAPI.tsx around lines 129 to 133, the
mixin method has an unused parameter named mixin because the feature is not
supported. Remove the mixin parameter from the method signature to clean up the
code and avoid unused parameter warnings, while keeping the method body
unchanged.
| unmount() { | ||
| if (isMounted) { | ||
| unmountComponentAtNode(app._container); | ||
|
|
||
| delete app._container; | ||
| } | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Replace delete operator with undefined assignment
Using the delete operator can impact performance. Assign undefined instead.
unmount() {
if (isMounted) {
unmountComponentAtNode(app._container);
- delete app._container;
+ app._container = null;
+ isMounted = false;
}
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| unmount() { | |
| if (isMounted) { | |
| unmountComponentAtNode(app._container); | |
| delete app._container; | |
| } | |
| }, | |
| unmount() { | |
| if (isMounted) { | |
| unmountComponentAtNode(app._container); | |
| app._container = null; | |
| isMounted = false; | |
| } | |
| }, |
🤖 Prompt for AI Agents
In packages/inula-adapter/src/vue/globalAPI.tsx around lines 167 to 173, replace
the use of the delete operator on app._container with an assignment of undefined
to app._container to avoid performance issues. Change "delete app._container;"
to "app._container = undefined;" within the unmount method.
新增inula-adapter模块适配vue api,供转换工具使用
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests
Chores