Skip to content

Conversation

@shenjunjian
Copy link
Collaborator

@shenjunjian shenjunjian commented Jan 24, 2025

PR

将renderless/common 中的函数移动到utils目录中去

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

I'll craft concise release notes focusing on the end-user visible changes across the utility packages.

Release Notes for Utility Packages

New Features

  • Added comprehensive utility functions for:
    • Date and time manipulation
    • String formatting and validation
    • Browser and device detection
    • Touch and scroll event handling
    • Form and validation management
    • Tree and array data structure operations

Enhancements

  • Improved cross-browser compatibility for various utility functions
  • Added robust type checking and conversion utilities
  • Enhanced performance with optimized DOM and event handling methods
  • Introduced advanced validation mechanisms for different data types

Breaking Changes

  • Restructured utility package exports for more granular imports
  • Removed some legacy environment detection methods

Performance Improvements

  • Implemented efficient resize and scroll event management
  • Added throttling and debounce utilities for event handling
  • Optimized DOM manipulation methods

Directives and Hooks

  • New Vue directives for:
    • Infinite scrolling
    • Click outside detection
    • Visibility observation
  • New Vue composition hooks for:
    • Touch interactions
    • Event listener management
    • Slot and instance relationship tracking

@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2025

Walkthrough

This pull request introduces a comprehensive set of utility modules and functions across multiple packages, primarily focusing on the @opentiny/utils package. The changes span various domains such as date manipulation, type checking, validation, DOM interaction, event handling, and more. The refactoring aims to enhance the utility library's functionality, providing a robust set of tools for developers to use across different parts of an application.

Changes

File Change Summary
packages/utils/src/ Multiple new utility modules added, including after-leave, array, bigInt, browser, calendar, crypt, dataset, date-util, decimal, dom, espace-ctrl, event, fastdom, fecha, form, fullscreen, function, globalConfig, memorize, object, popper, popup-manager, prop-util, resize-event, resize-observer, scroll-into-view, scroll-width, string, throttle, touch-emulator, touch, tree-model, type, upload-ajax, validate
packages/vue-directive/ New directives added: clickoutside, infinite-scroll, observe-visibility, repeat-click
packages/vue-hooks/ New hooks added: useEventListener, useInstanceSlots, useRect, useRelation, useTouch

Suggested labels

refactoring, utilities, enhancement

Suggested reviewers

  • zzcr
  • gimmyhehe
  • kagol

Poem

🐰 Utilities Hop, Code Takes Flight

Rabbit's toolkit, shining bright
Functions dance, types align
Hooks and directives intertwine
A library of code delight! 🚀

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant Utils as @opentiny/utils
    participant Directives as Vue Directives
    participant Hooks as Vue Hooks

    Dev->>Utils: Import utility functions
    Utils-->>Dev: Provide type checking, validation, etc.
    
    Dev->>Directives: Use custom directives
    Directives-->>Dev: Handle complex interactions
    
    Dev->>Hooks: Utilize composition hooks
    Hooks-->>Dev: Manage component logic
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link

[e2e-test-warn]
The component to be tested is missing.

The title of the Pull request should look like "fix(vue-renderless): [action-menu, alert] fix xxx bug".

Please make sure you've read our contributing guide

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 23

🧹 Nitpick comments (107)
packages/utils/src/fastdom/sandbox.ts (3)

23-26: Improve readability of the remove helper.
The use of !!~index may appear cryptic. For clarity, consider using a straightforward check that avoids bitwise operations:

- return !!~index && !!array.splice(index, 1)
+ if (index !== -1) {
+   array.splice(index, 1)
+   return true
+ }
+ return false

67-73: Consider renaming the exports object for clarity.
Overloading the name exports can cause confusion in some environments. A more descriptive variable name would be beneficial:

- const exports = {
+ const sandboxExports = {
   sandbox() {
     return new Sandbox(this.fastdom)
   }
 }
 ...
- const fastdomSandbox = fastdomSingleton.extend(exports)
+ const fastdomSandbox = fastdomSingleton.extend(sandboxExports)

28-66: Add TypeScript type annotations.
Although this file is a .ts module, it currently lacks any type annotations for class properties, method parameters, or return values. Consider adding types to improve maintainability and enable better IDE support.

packages/vue-hooks/src/useEventListener.ts (2)

9-10: Avoid assignment in arrow function expressions.
Static analysis warns about the inline assignment in an arrow function, which can be less clear. Consider wrapping the assignment in a block for better readability.

- nextTick(() => (mounted = true))
+ nextTick(() => {
+   mounted = true
+ })
🧰 Tools
🪛 Biome (1.9.4)

[error] 10-10: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


16-65: Optional chain for function calls
At line 61, you can simplify the conditional call of stopWatch with optional chaining. This approach makes the code more concise and clear.

- stopWatch && stopWatch()
+ stopWatch?.()
🧰 Tools
🪛 Biome (1.9.4)

[error] 61-61: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/vue-directive/src/observe-visibility.ts (2)

55-73: Efficient handling of DOM changes
Using MutationObserver to monitor children is effective. However, in large DOM trees, be mindful of performance if numerous mutations occur. Ensure that your throttling or debouncing mechanisms remain sufficient to maintain performance when the tree is large or deeply nested.


128-129: Performance note on sorting
Sorting instances on every DOM mutation could become expensive in complex interfaces. Consider caching or reducing sort calls if performance becomes a concern.

packages/vue-hooks/src/useRelation.ts (2)

55-73: DOM-based approach for relation order
Setting up a MutationObserver to reorder child components is creative. However, significant dynamic updates or frequent reflows might affect performance. Keep an eye on large-scale usage.


128-130: Cautious sorting logic
The sortPublicInstances utility works, but repeated sorting can be costly. If you experience latency in complex trees, consider incremental or targeted updates instead of sorting the entire list each time.

packages/utils/src/index.ts (1)

6-6: Consolidate or reorganize exports for better maintainability.

This file aggregates a large number of utility exports from various modules in a single index. While this is convenient, it can lead to bloat or reduced maintainability should the project grow. Consider:

  1. Grouping related exports in smaller, domain-focused index files (e.g. date, string, array).
  2. Ensuring any method flagged as "待移除" or "should be removed" is properly tracked in an issue.
  3. Documenting each export’s intended usage to prevent confusion or duplication.

Do you want me to open a follow-up PR or create an issue to facilitate reorganizing these exports or removing obsolete ones?

Also applies to: 8-8, 9-9, 10-19, 21-36, 38-70, 72-73, 75-76, 78-92, 94-95, 97-111, 113-114, 116-120, 122-133, 135-135, 137-138, 140-140, 142-144, 146-146, 148-183, 185-186, 188-208, 210-211, 213-213, 215-216, 218-219, 220-220, 222-223, 225-225, 227-228, 230-231, 232-232

packages/vue-directive/src/infinite-scroll.ts (2)

49-54: Avoid using the delete operator for performance reasons.

The delete el[CONTEXT_KEY].observer statement can cause unexpected performance penalties. Instead, assign undefined to the property.

- delete el[CONTEXT_KEY].observer
+ el[CONTEXT_KEY].observer = undefined
🧰 Tools
🪛 Biome (1.9.4)

[error] 53-53: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


110-114: Eliminate assignment within logical expressions for clarity.

The assignment cache[str] = fn(str) inside the logical expression can diminish readability. Consider separating it out to make the logic clearer.

-  return (str) => cache[str] || (cache[str] = fn(str))
+  return (str) => {
+    if (!cache[str]) {
+      cache[str] = fn(str)
+    }
+    return cache[str]
+  }
🧰 Tools
🪛 Biome (1.9.4)

[error] 112-112: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/popup-manager/index.ts (2)

68-69: Replace delete with property reassignment.

Using delete instances[id] de-optimizes the object. Set the property to undefined instead if removal is for logical rather than dynamic structural reasons.

-      delete instances[id]
+      instances[id] = undefined

141-142: Consider optional chaining for cleaner null checks.

In places where you check if (instance && instance.closeOnClickModal) or if (topPopup && topPopup.id === id), you could simplify the logic by using optional chaining, for example instance?.closeOnClickModal.

Also applies to: 161-163

🧰 Tools
🪛 Biome (1.9.4)

[error] 141-142: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/decimal/index.ts (1)

15-16: Remove commented-out code.
The comment “// 待移除, 已经从bigInt导出过了” indicates these lines can be safely removed to reduce clutter.

-// 待移除, 已经从bigInt导出过了
-export { roundFixed }
packages/utils/src/espace-ctrl/index.ts (2)

84-85: Clear the heartbeat timer in all paths.
In sendHeartbeat, the timer is cleared only if connected is false. Consider a final cleanup in more scenarios (e.g., explicit teardown).


400-414: Guard repeated init calls.
initialized is used to skip multiple inits, but ensure repeated calls won't reset or conflict with existing timers, localStorage flags, or callbacks.

packages/utils/src/validate/schema.ts (3)

16-24: Consider using ES6 class syntax instead of a function constructor.
Defining Schema as a regular function that manually assigns properties can be less clear compared to using the class keyword in modern JavaScript/TypeScript. Switching to an ES6 class might help readability and maintainability.

-function Schema(descriptor, translate) {
+export class Schema {
+  constructor(descriptor, translate) {
     Schema.getSystemMessage = () => Schema.getDefaultMessage(translate)
     Schema.messages = Schema.getSystemMessage(translate)
     Schema.systemMessages = Schema.messages

     this.rules = null
     this._messages = Schema.systemMessages
     this.define(descriptor)
+  }
}

31-56: Validate callback merging is well-handled, but consider micro-optimizations.
The getCompleteFn function nicely aggregates errors and fields, but it might benefit from early exits when no errors have been found, rather than pushing all results and then checking at line 48. This can simplify logic and possibly improve performance with large rule arrays.


161-161: Use optional chaining to simplify the conditional.
Static analysis suggests replacing node && node.setChecked(...) with optional chaining for readability.

- node && node.setChecked(true, !this.checkStrictly)
+ node?.setChecked(true, !this.checkStrictly)
packages/utils/src/tree-model/tree-store.ts (2)

124-124: Use optional chaining for cleaner conditional property access.
At line 124, refNode && refNode.parent can be replaced with optional chaining if you'd like to reduce nesting.

- const refNode = this.getNode(insertData)
- refNode.parent.insertBefore({ data }, refNode)
+ const refNode = this.getNode(insertData)
+ refNode?.parent?.insertBefore({ data }, refNode)
🧰 Tools
🪛 Biome (1.9.4)

[error] 124-124: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


383-385: Avoid complex assignments inside expressions.
You assign this.currentNode && (this.currentNode.isCurrent = false) on one line. This can be clarified with separate statements to avoid confusion and potential side effects.

- this.currentNode && (this.currentNode.isCurrent = false)
+ if (this.currentNode) {
+   this.currentNode.isCurrent = false
+ }
🧰 Tools
🪛 Biome (1.9.4)

[error] 383-385: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/bigInt/index.ts (1)

321-321: Replace isNaN with Number.isNaN for clarity.
This ensures you avoid unintentional type coercion.

- if (isNaN(target)) {
+ if (Number.isNaN(target)) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 321-321: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/utils/src/object/index.ts (2)

29-40: Validate callback usage in each function.
This function provides an early-break mechanism if the callback returns false. Consider documenting this behavior, so callers are aware that returning false stops the iteration.


49-50: Clarify deferred assignment for extend.
Currently, extend is declared here, but its implementation is assigned later on at line 250. This pattern works, but can be unintuitive. Consider defining extend after its logic or bundling the declaration and assignment together for clarity.

packages/utils/src/tree-model/node.ts (3)

36-60: Short-circuit evaluations in getChildState.
This function detects whether child nodes are all checked, none checked, or partially checked. The logic is correct. However, consider short-circuiting as soon as you know “none” is false, which might save time in large node sets.


169-169: Optional chaining refactor.
Multiple places use defensive checks like this.store && this.store.props. Optional chaining could improve readability, e.g., this.store?.props. Consider applying this pattern if supported by your environment.

Also applies to: 258-258, 351-351, 388-388, 604-604, 608-608, 616-616

🧰 Tools
🪛 Biome (1.9.4)

[error] 169-169: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


374-405: Streamline lazy-loading expansion.
When shouldLoadData() is true, the node loads data and then expands. This logic is clear but can be slightly decoupled: load the data in one method, then call an expand() method after loading, to keep responsibilities separate and easy to test.

🧰 Tools
🪛 Biome (1.9.4)

[error] 388-388: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/date/index.ts (2)

254-254: Use Number.isNaN instead of isNaN(Number(…)).
Using isNaN() can be confusing due to type coercion. Consider updating these lines to use Number.isNaN(...) for clarity and to align with best practices.

Also applies to: 282-282

🧰 Tools
🪛 Biome (1.9.4)

[error] 254-254: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


407-444: Promise-based or callback-based approach in format.
format is purely synchronous, but references date parsing from a user-provided string. If future expansions include async data or additional validation, consider returning a safe default or error for invalid inputs.

packages/utils/src/resize-observer/index.ts (5)

50-56: Consider using optional chaining for cleaner property access.

Currently, the line return entry && entry[1] could be replaced by optional chaining for enhanced readability and safety:

- return entry && entry[1]
+ return entry?.[1]
🧰 Tools
🪛 Biome (1.9.4)

[error] 54-54: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


253-253: Use optional chaining to simplify checks before disconnecting.

Here is the current pattern:

this.mutationsObserver_ && this.mutationsObserver_.disconnect()

Use optional chaining for better readability:

- this.mutationsObserver_ && this.mutationsObserver_.disconnect()
+ this.mutationsObserver_?.disconnect()
🧰 Tools
🪛 Biome (1.9.4)

[error] 253-253: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


304-304: Replace chained logical operators with optional chaining.

- const ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView
+ const ownerGlobal = target?.ownerDocument?.defaultView

This clarifies your code and avoids nested short-circuits.

🧰 Tools
🪛 Biome (1.9.4)

[error] 304-304: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


533-538: Remove unnecessary aliasing of 'this'.

The arrow function inherits 'this' from the enclosing scope. Instead of:

const me = this
...
observation.isActive() && me.activeObservations_.push(observation)

Directly call:

observation.isActive() && this.activeObservations_.push(observation)
🧰 Tools
🪛 Biome (1.9.4)

[error] 533-533: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)


596-597: Refactor the assignment within the return statement for clarity.

The expression:

return (_a = observers.get(this))[method].apply(_a, arguments)

can be broken into smaller steps:

- return (_a = observers.get(this))[method].apply(_a, arguments)
+ const observer = observers.get(this)
+ return observer[method].apply(observer, arguments)

This approach is more readable and reduces confusion about side effects in expressions.

🧰 Tools
🪛 Biome (1.9.4)

[error] 596-596: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/popper/index.ts (3)

44-46: Use modern numeric checks instead of global isNaN() and isFinite().

Here, you are checking:

const isNumeric = (n) => n !== '' && !isNaN(parseFloat(n)) && isFinite(n)

Modern best practice favors Number.isNaN() and Number.isFinite(), which avoid implicit type coercion:

- const isNumeric = (n) => n !== '' && !isNaN(parseFloat(n)) && isFinite(n)
+ const isNumeric = (n) => n !== '' && !Number.isNaN(Number.parseFloat(n)) && Number.isFinite(Number.parseFloat(n))
🧰 Tools
🪛 Biome (1.9.4)

[error] 44-44: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 44-44: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.

(lint/suspicious/noGlobalIsFinite)


325-326: Replace usage of Function type with more explicit function signatures.

Currently, the type definitions use Function[] or Function:

modifierFns: Function[] 
...
modifiers: Record<string, Function> = {}
...

It’s recommended to define more specific function signatures for clarity and maintainability:

- modifierFns: Function[]
+ modifierFns: Array<(data: UpdateData) => UpdateData>

- modifiers: Record<string, Function>
+ modifiers: Record<string, (data: UpdateData) => UpdateData>

Also applies to: 386-387, 481-483

🧰 Tools
🪛 Biome (1.9.4)

[error] 325-325: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


369-369: Refine the object type usage.

Currently:

popperOuterSize = null as unknown as { width: number; height: number }

Avoid casting to overly general object types (like {} or any). Instead, define an explicit interface if needed:

interface PopperSize {
  width: number
  height: number
}
private popperOuterSize: PopperSize | null = null
🧰 Tools
🪛 Biome (1.9.4)

[error] 369-369: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

packages/utils/src/form/index.ts (1)

1-6: Add tests for newly introduced constants.

The constants FORM_ITEM and FORM_EVENT are straightforward. However, consider adding unit tests or integration tests to verify their usage in the broader form handling logic, preventing accidental regressions or typos in future changes.

packages/utils/src/globalConfig/index.ts (1)

4-7: Note on planned deprecation.
You’ve noted in the comment that getWindow may not be needed long term. Consider referencing an internal tracking item or issue to avoid losing context on eventual removal.

packages/vue-hooks/src/useRect.ts (1)

20-20: Optional chaining suggestion from static analysis.
While the existing if (el && el.getBoundingClientRect) check is valid, you could replace it with an optional chain for conciseness. For instance:

- if (el && el.getBoundingClientRect) {
-   return el.getBoundingClientRect()
- }
+ if (el?.getBoundingClientRect) {
+   return el.getBoundingClientRect()
+ }

This is purely a syntactic preference rather than a functional requirement.

🧰 Tools
🪛 Biome (1.9.4)

[error] 20-20: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/function/index.ts (2)

3-3: Consider specifying the return type.

Currently, noop lacks a type signature, which can be helpful in TypeScript for clarity. You could define it as:

export const noop: () => void = () => {}

5-27: Add explicit parameter types and ensure that error is always callable.

This function is missing type annotations for interceptor, args, done, canceled, and error. In TypeScript, consider specifying each parameter’s type for better clarity and maintainability. Also, ensure that error is indeed a function or handle the case where it is undefined or non-callable, to avoid runtime exceptions.

packages/utils/src/validate/rules/whitespace.ts (1)

15-19: Add TypeScript definitions for parameters.

The function parameters rule, checkValue, source, errors, and options would benefit from explicit types, improving readability and preventing potential type mismatches.

packages/utils/src/validate/validations/required.ts (1)

15-21: Validate callback usage to prevent potential runtime errors.
Currently, there is no validation to ensure callback is a valid function. If callback is undefined or not a function, it may trigger a runtime error or fail silently. Consider adding a simple check or fallback behavior.

 export default function (rule, checkValue, callback, source, options) {
   const errors = []
   const type = Array.isArray(checkValue) ? 'array' : typeof checkValue
   rules.required({ rule, checkValue, source, errors, options, type })
-  callback(errors)
+  if (typeof callback === 'function') {
+    callback(errors)
+  } else {
+    console.warn('Validation callback is not a function:', callback)
+  }
 }
packages/utils/src/validate/rules/enum.ts (1)

17-23: Add optional message fallback or verification for options.messages[ENUM].
If options.messages[ENUM] is absent or undefined, util.format(options.messages[ENUM], ...) may yield an unclear error message or throw. For safety, consider providing a fallback message or verifying its presence before usage.

 if (!rule[ENUM].includes(checkValue)) {
-  errors.push(util.format(options.messages[ENUM], '', rule[ENUM].join(', ')))
+  const messageTemplate = options.messages[ENUM] || 'Value is not in enum: %s'
+  errors.push(util.format(messageTemplate, '', rule[ENUM].join(', ')))
 }
packages/utils/src/tree-model/util.ts (1)

22-33: Safeguard against missing or undefined node.id.
If node.id is undefined, the $treeNodeId property will be assigned an unexpected undefined value on the data object. Consider adding a guard for node.id and, if needed, log a warning or throw an error.

Here’s an example modification:

 export const markNodeData = function (node, data) {
   if (!data || data[NODE_KEY]) {
     return
   }

+  if (typeof node.id === 'undefined') {
+    console.warn('node.id is not defined, marking data may cause inconsistencies.')
+    return
+  }

   Object.defineProperty(data, NODE_KEY, {
     value: node.id,
     enumerable: false,
     configurable: false,
     writable: false
   })
 }
packages/utils/src/validate/rules/pattern.ts (1)

16-29: Handle invalid string patterns gracefully.
If rule.pattern is set but not a valid regex, the new RegExp(rule.pattern) call might throw an error. Consider catching invalid patterns or validating them beforehand to ensure robust error handling.

packages/utils/src/validate/validations/pattern.ts (1)

21-31: Consider adding dedicated test coverage for pattern validation.

Currently, the function runs rules.pattern if the value is not empty. It can be helpful to have separate tests for different types of patterns (e.g., regex, string patterns). This ensures that the pattern-checking behavior meets your expectations and remains stable against future changes.

Would you like me to help draft a suite of tests for various pattern types?

packages/utils/src/validate/validations/enum.ts (1)

35-35: Confirm error structure.

As with other validations, you pass errors to callback directly. Ensure each error within the array follows a consistent format across all validators (for instance, including the field name, type of validation, etc.). This consistency will streamline error consumption in UI components or logging.

packages/utils/src/validate/validations/float.ts (1)

21-31: Ensure correct float validations.

You’ve invoked rules.type and rules.range once checkValue is not undefined. If checkValue is a string that needs numeric conversion, confirm that rules.type is either converting or properly rejecting non-numeric strings. You may want to test edge cases like '123.45', 'abc', and 123.0 to confirm consistency.

packages/utils/src/validate/validations/integer.ts (1)

21-31: Validate numeric strings properly.

You only run rules.type and rules.range if checkValue !== '' and checkValue !== undefined. If integer fields arrive as strings, confirm your rules.type handles string parsing or rejects them outright. For example, '42' or '0' might need special handling if your validations are strict.

packages/utils/src/validate/validations/array.ts (3)

19-20: Clarify the validation condition.

The expression rule.required || (!rule.required && hasOwn.call(source, rule.field)) is functionally correct but may be difficult to parse at first glance. Consider splitting or renaming intermediate variables for clarity.

-  const validate = rule.required || (!rule.required && hasOwn.call(source, rule.field))
+  const isFieldPresent = hasOwn.call(source, rule.field)
+  const validate = rule.required || (!rule.required && isFieldPresent)

28-31: Conditional ordering for multiple validations.

When rules.type fails (e.g., checkValue is not an array), it might be beneficial to skip rules.range immediately to avoid extra checks or potential confusion. You can refactor to short-circuit once a type mismatch is detected.

rules.type(rule, checkValue, source, errors, options)
+ if (errors.length > 0) {
+   return
+ }
rules.range(rule, checkValue, source, errors, options)

34-35: Ensure consistent error-handling flow.

Invoking callback(errors) works as intended, but if you anticipate common code for error logging or additional processing before returning, consider encapsulating it in a helper. This approach can improve consistency and maintainability.

packages/vue-directive/src/repeat-click.ts (2)

22-23: Pass event context to the handler function.

Currently, the long-press callback doesn't receive any parameters. Passing the event or element context can offer more flexibility for the callback, such as preventing default behavior or referencing the target.

-  typeof binding.value === 'function' && binding.value.apply()
+  typeof binding.value === 'function' && binding.value(e)

35-45: Add touch event support.

This directive only listens to mouse events at the moment. If you need to support mobile devices, consider adding touchstart and touchend listeners or a unified pointer event approach.

packages/utils/src/after-leave/index.ts (2)

20-20: Use a more descriptive error message.

Throwing a generic error if instance or callback is missing might not provide enough clarity. Add more context, such as which of the two was null or undefined, to help users debug quickly.

- throw new Error('instance & callback is required')
+ throw new Error(`Either 'instance' or 'callback' is missing and both are required.`)

43-44: Confirm necessity of the delay.

The additional + 100 in setTimeout(eventCallback, speed + 100) may need justification. If it compensates for an animation or transitional effect in the UI, consider adding inline documentation to explain its purpose.

packages/utils/src/validate/validations/type.ts (2)

20-20: Promote readability of 'validate' expression.

Similar to array validation, splitting the validation expression can help maintain clarity. Use well-named variables to express intent and minimize confusion.


36-39: Short-circuit after type check.

Once rules.type fails, subsequent logic likely isn’t needed. Consider early-returning after type validation errors to reduce unnecessary checks.

packages/utils/src/fastdom/async.ts (2)

14-34: Consider simplifying the callback creation with arrow functions.
Using arrow functions in the promise executor and fastdom[type] callback can improve readability and maintain the lexical this.

-  const promise = new Promise(function (resolve, reject) {
-    task = fastdom[type](function () {
+  const promise = new Promise((resolve, reject) => {
+    task = fastdom[type](() => {

36-55: Rename “exports” object to avoid confusion with native module exports.
“exports” may read ambiguously. Consider using a more descriptive name such as fastdomMethods for clarity.

-const exports = {
+const fastdomMethods = {
   initialize() {
     ...
   }
}
...
-const fastdomAsync = fastdomSingleton.extend(exports)
+const fastdomAsync = fastdomSingleton.extend(fastdomMethods)
packages/utils/src/validate/validations/number.ts (1)

17-39: Name the default-exported function for better debugging.
Providing a function name can enhance stack traces, making debugging easier.

-export default function (rule, checkValue, callback, source, options) {
+export default function validateNumber(rule, checkValue, callback, source, options) {
   // ...
}
packages/utils/src/validate/validations/index.ts (1)

25-55: Consider grouping or modularizing verbose list of validations.
Maintaining such a large object with numerous validation keys in one place can become unwieldy. Grouping related validations or splitting into smaller modules might improve maintainability.

packages/utils/src/scroll-into-view/index.ts (1)

15-43: Optionally implement smooth scrolling.
If user experience warrants a smooth scroll, you could optionally use an API that supports it.

-  container.scrollTop = top
+  container.scrollTo({
+    top,
+    behavior: 'smooth'
+  })
packages/utils/src/touch/index.ts (2)

13-13: Consider making the threshold configurable

While 10 is a good default value for minimum touch-distance, certain gestures or devices may benefit from a configurable threshold.


34-43: Single-touch approach recognized

Currently, the code only uses the first finger's position. If multi-touch features are on the roadmap, consider additional logic or parameterization.

packages/utils/src/validate/validations/string.ts (1)

17-47: Name the default export for better debugging

While anonymous default exports are valid, using a named function can improve stack traces and maintainability. Otherwise, the validation logic here is coherent and consistent with the rest of the framework.

packages/utils/src/resize-event/index.ts (2)

32-44: Ensure callbacks aren’t duplicated

The current approach allows multiple registrations of the same callback. If that is unwanted, deduplicate to prevent repeated calls.


46-58: Avoid using the delete operator for performance reasons

Consider marking el.__ro__ as undefined instead of deleting it.

-    delete el.__ro__
+    el.__ro__ = undefined
🧰 Tools
🪛 Biome (1.9.4)

[error] 56-56: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

packages/utils/src/scroll-width/index.ts (1)

16-50: Remove the container element from the DOM

Currently, only the inner div is removed from the container, leaving the container appended to document.body. This can lead to minor memory leaks if called repeatedly.

 document.body.appendChild(container)
 ...
 const widthWithScroll = inner.offsetWidth
-(outer.parentNode as HTMLElement).removeChild(outer)
+document.body.removeChild(container)
 scrollBarWidth = widthNoScroll - widthWithScroll
packages/utils/src/validate/validations/date.ts (2)

17-18: Add explicit typing in a .ts file.
This function is missing explicit TypeScript definitions for rule, checkValue, callback, source, and options. Declaring parameter and return types will improve clarity and make the code more maintainable.


32-36: Consider more explicit handling for non-number, non-valid-string inputs.
When neither a number nor a valid date string is detected, this logic assigns checkValue directly to dateObject. You might want to handle or report an error if checkValue is an unexpected type, instead of silently passing it along.

packages/vue-hooks/src/useTouch.ts (3)

11-11: Revisit hook factory pattern.
Exporting a function that returns another function is unconventional. Usually, a Vue hook is directly invoked like useTouch(). Consider refactoring to a more standard usage pattern:

-export const useTouch = (ref) => () => {
+export const useTouch = (ref) => {

40-57: Document the rationale behind ignoring negative clientX.
You’re resetting negative clientX to zero, which handles Safari’s “back swipe” scenario. Adding a comment about why negative values must be clamped to zero will help future maintainers understand the reasoning.


48-52: Replace magic numbers with descriptive constants.
The LOCK_DIRECTION_DISTANCE is currently hardcoded. Using a named constant or referencing a config value makes the code more self-descriptive.

- const LOCK_DIRECTION_DISTANCE = 10
+ const LOCK_DIRECTION_DISTANCE = 10 // e.g. consider a top-level constant or config
packages/utils/src/validate/rules/range.ts (1)

17-17: Consider renaming the helper function.
getErro might be a typo or shorthand. Renaming it (e.g., checkRangeError or pushRangeError) better communicates its purpose.

packages/utils/src/event/index.ts (1)

64-85: Validate browser compatibility for rewriting event.target.
Object.defineProperty on an event object may not be fully supported in older browsers. This approach is powerful but could lead to unexpected side effects if third-party libraries rely on the native event.target. Consider applying a more cautious fallback or feature detection.

packages/utils/src/fastdom/singleton.ts (3)

74-74: Avoid assignment within the while condition.
Some linters or style guides flag assignments in expressions as confusing. Refactor the loop to increase clarity and reduce the risk of hidden bugs.

- while ((task = tasks.shift())) task()
+ let task = tasks.shift()
+ while (task) {
+   task()
+   task = tasks.shift()
+ }
🧰 Tools
🪛 Biome (1.9.4)

[error] 74-74: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


45-49: Consider renaming the catch callback.
Using the property name "catch" can be confusing since it shadows a reserved keyword in JavaScript. Consider renaming it to something like onError or handleError for clarity.


64-114: Concurrency and re-entrancy checks.
FastDom processes reads and writes asynchronously; be aware of potential re-entrancy if tasks schedule additional tasks. Monitoring queue depth can help detect infinite or runaway loops.

🧰 Tools
🪛 Biome (1.9.4)

[error] 74-74: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/touch-emulator/index.ts (1)

98-101: Use optional chaining to simplify the null check.
Inline checks for eventTarget && eventTarget.dispatchEvent can be replaced with optional chaining if the codebase supports modern JS syntax.

-if (eventTarget && eventTarget.dispatchEvent) {
-  triggerTouch(touchType, ev)
-}
+eventTarget?.dispatchEvent && triggerTouch(touchType, ev)
🧰 Tools
🪛 Biome (1.9.4)

[error] 100-101: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/browser/index.ts (2)

27-36: Avoid using delete operator on performance-critical objects
In isEdge, the direct usage of delete browser.chrome (line 31) may impact performance if you rely heavily on dynamic object properties. A simpler, recommended pattern is setting to undefined instead of using delete.

-    delete browser.chrome
+    browser.chrome = undefined
🧰 Tools
🪛 Biome (1.9.4)

[error] 31-31: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


43-100: Consolidate version detection logic
The version detection logic scattered across browser can be simplified by extracting user agent checks into dedicated helper functions, enhancing maintainability. Otherwise, the existing approach is clear and workable.

packages/utils/src/throttle/index.ts (1)

38-38: Use a more specific return type than “Function”
Instead of returning a generic Function, define a more explicit type for the throttled wrapper and its _cancel property. This can help catch potential type errors and improve code readability.

-export function throttle(delay, noTrailing, callback, debounceMode?: string): Function {
+interface ThrottleWrapper extends Function {
+  _cancel?: () => void
+}
+
+export function throttle(
+  delay: number,
+  noTrailing: boolean,
+  callback: (...args: any[]) => void,
+  debounceMode?: string
+): ThrottleWrapper {
🧰 Tools
🪛 Biome (1.9.4)

[error] 38-38: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/utils/src/calendar/index.ts (1)

22-23: Correct parameter name in JSDoc
The JSDoc for getWeek uses @param {Number} month - 日 at line 19 instead of @param {Number} day.

- * @param {Number} month - 日
+ * @param {Number} day - 日
packages/vue-directive/src/clickoutside.ts (2)

37-57: Leverage optional chaining for clarity
In createDocumentHandler, consider using optional chaining for vnode.context?.popperElm or vnode.context?.state?.popperElm, rather than complex logical expressions for fallback.

-    let popperElm = vnode.context.popperElm || (vnode.context.state && vnode.context.state.popperElm)
+    let popperElm = vnode.context?.popperElm || vnode.context?.state?.popperElm
🧰 Tools
🪛 Biome (1.9.4)

[error] 39-39: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 55-55: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


55-56: Use optional chaining to simplify
Where you have:

el[nameSpace].bindingFn && el[nameSpace].bindingFn()

you can consider:

el[nameSpace].bindingFn?.()
🧰 Tools
🪛 Biome (1.9.4)

[error] 55-55: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/dataset/index.ts (2)

70-71: Use optional chaining for improved readability and safety.
Refactoring this condition by utilizing optional chaining helps reduce nested conditional checks and makes the code more concise.

-    const orderBy = sort && sort.property ? sort.property + ' ' + sort.order : ''
+    const orderBy = sort?.property ? `${sort.property} ${sort.order}` : ''
🧰 Tools
🪛 Biome (1.9.4)

[error] 71-71: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


122-123: Guard $service.network with optional chaining.
If there's any scenario where $service or its network property might be undefined, switching to optional chaining will help prevent potential runtime errors.

-      $service.network
+      $service?.network
         .request(config)
         .then((response) => {
           ...
         })
🧰 Tools
🪛 Biome (1.9.4)

[error] 122-123: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/type/index.ts (2)

13-13: Rename this constant to avoid shadowing the global toString.
Exporting a constant named toString can create confusion. Rename it to make the intent clearer and prevent collisions with the built-in toString method.

- export const toString = Object.prototype.toString
+ export const objectToString = Object.prototype.toString
🧰 Tools
🪛 Biome (1.9.4)

[error] 13-13: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


122-122: Use Number.isFinite() instead of isFinite().
isFinite() implicitly coerces values to numbers, which might cause unexpected outcomes. Number.isFinite() is stricter and safer for numeric checks.

-export const isNumber = (value: any) => typeof value === 'number' && isFinite(value)
+export const isNumber = (value: any) => typeof value === 'number' && Number.isFinite(value)
packages/utils/src/fullscreen/apis.ts (3)

17-22: Consider stricter typing for defaults.
The defaults object might benefit from an interface or type definition to ensure clarity about its shape, especially for callback, pageOnly, and teleport.


57-75: Caching inline styles is great – watch for newly added properties.
setTargetStyle() caches the original inline styles. Consider making that cache more generic in case other style properties exist that also need restoring later.


77-89: Avoid reassigning function parameters.
Reassigning options = extend({}, defaults, options) can confuse some tools or developers. Instead, define a new variable, e.g. const mergedOptions = extend({}, defaults, options).

-const getOptions = (screenfull, options, target) => {
-  options = extend({}, defaults, options)
+const getOptions = (screenfull, incomingOptions, target) => {
+  const mergedOptions = extend({}, defaults, incomingOptions)
   ...
 }
🧰 Tools
🪛 Biome (1.9.4)

[error] 77-77: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/fullscreen/screenfull.ts (2)

78-81: Utilize optional chaining or safe lookups.
For instance, fullscreenEvents && fullscreenEvents.fullscreenchange could be replaced with an optional chain, e.g. fullscreenEvents?.fullscreenchange, for clarity. This is a stylistic preference but can improve readability.

🧰 Tools
🪛 Biome (1.9.4)

[error] 79-79: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 80-80: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


160-176: Consider optional chaining for document[fullscreenEvents && fullscreenEvents.fullscreenElement].
Using a condition with && in bracket notation can be less expressive than optional chaining.

-return !!document[fullscreenEvents && fullscreenEvents.fullscreenElement]
+return !!(fullscreenEvents?.fullscreenElement 
+  && document[fullscreenEvents.fullscreenElement])
🧰 Tools
🪛 Biome (1.9.4)

[error] 162-165: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 168-171: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/array/index.ts (1)

198-223: Consider large data sets.
transformPidToChildren() is straightforward for moderate data sets. If extremely large trees or frequent updates are expected, consider potential performance or memory overhead.

packages/utils/src/validate/util.ts (2)

45-47: Avoid using Function as a type.
Explicitly define the function signature for i18nTemplate rather than using Function. This enhances type safety.

-export function format(i18nTemplate: Function | string, ...rest: string[]) {
+type TemplateFn = (...args: string[]) => string
+export function format(i18nTemplate: TemplateFn | string, ...rest: string[]) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 47-47: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


274-276: Optional chaining to guard objects.
if (!sources) is good, but you might also check for typeof sources === 'object'. If minimal overhead is desired, be consistent with how you handle undefined or null.

🧰 Tools
🪛 Biome (1.9.4)

[error] 274-276: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/common/index.ts (1)

13-107: Consider namespacing or creating a dedicated interface for key codes.
The KEY_CODE object is quite large. A more structured approach (e.g., splitting into smaller enums or separate objects) might help maintain readability and make it easier to locate specific keys.

packages/utils/src/dom/index.ts (3)

16-17: Leverage isServer consistently across utilities.
isServer is declared once here as typeof window === 'undefined'. Ensure other utilities reference this shared definition to stay uniform and avoid duplicative logic.


28-33: Enhance type definitions for event parameters.
Using any for event types is flexible but loses valuable IntelliSense. Consider importing or declaring more specific event parameter types from DOM or custom definitions.


288-307: Check performance impact of repeated getComputedStyle calls.
isDisplayNone recursively calls getComputedStyle. For large nested DOM trees, this might impact performance. Consider memoizing or short-circuiting once a hidden ancestor is found.

packages/utils/src/date-util/index.ts (2)

70-80: Review month check for clarity.
~[3, 5, 8, 10].indexOf(month) works, but a more descriptive check (e.g., const THIRTY_DAY_MONTHS = [3, 5, 8, 10]) clarifies intent.


118-140: Avoid possible duplication in hour range logic.
getRangeHours can produce an array populated with both allowed and disallowed hours. Consider short-circuiting if ranges is empty or merging repeated logic into a helper function.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f80d683 and e6a412c.

📒 Files selected for processing (82)
  • packages/utils/src/after-leave/index.ts (1 hunks)
  • packages/utils/src/array/index.ts (1 hunks)
  • packages/utils/src/bigInt/index.ts (1 hunks)
  • packages/utils/src/browser/index.ts (1 hunks)
  • packages/utils/src/calendar/index.ts (1 hunks)
  • packages/utils/src/common/index.ts (1 hunks)
  • packages/utils/src/crypt/index.ts (1 hunks)
  • packages/utils/src/dataset/index.ts (1 hunks)
  • packages/utils/src/date-util/index.ts (1 hunks)
  • packages/utils/src/date/index.ts (1 hunks)
  • packages/utils/src/debounce/index.ts (1 hunks)
  • packages/utils/src/decimal/index.ts (1 hunks)
  • packages/utils/src/dom/index.ts (1 hunks)
  • packages/utils/src/espace-ctrl/index.ts (1 hunks)
  • packages/utils/src/event/index.ts (1 hunks)
  • packages/utils/src/fastdom/async.ts (1 hunks)
  • packages/utils/src/fastdom/index.ts (1 hunks)
  • packages/utils/src/fastdom/sandbox.ts (1 hunks)
  • packages/utils/src/fastdom/singleton.ts (1 hunks)
  • packages/utils/src/fecha/index.ts (1 hunks)
  • packages/utils/src/form/index.ts (1 hunks)
  • packages/utils/src/fullscreen/apis.ts (1 hunks)
  • packages/utils/src/fullscreen/index.ts (1 hunks)
  • packages/utils/src/fullscreen/screenfull.ts (1 hunks)
  • packages/utils/src/function/index.ts (1 hunks)
  • packages/utils/src/globalConfig/index.ts (1 hunks)
  • packages/utils/src/index.ts (1 hunks)
  • packages/utils/src/logger/index.ts (1 hunks)
  • packages/utils/src/memorize/index.ts (1 hunks)
  • packages/utils/src/object/index.ts (1 hunks)
  • packages/utils/src/popper/index.ts (1 hunks)
  • packages/utils/src/popup-manager/index.ts (1 hunks)
  • packages/utils/src/prop-util/index.ts (1 hunks)
  • packages/utils/src/resize-event/index.ts (1 hunks)
  • packages/utils/src/resize-observer/index.ts (1 hunks)
  • packages/utils/src/scroll-into-view/index.ts (1 hunks)
  • packages/utils/src/scroll-width/index.ts (1 hunks)
  • packages/utils/src/string/index.ts (1 hunks)
  • packages/utils/src/throttle/index.ts (1 hunks)
  • packages/utils/src/touch-emulator/index.ts (1 hunks)
  • packages/utils/src/touch/index.ts (1 hunks)
  • packages/utils/src/tree-model/index.ts (1 hunks)
  • packages/utils/src/tree-model/node.ts (1 hunks)
  • packages/utils/src/tree-model/tree-store.ts (1 hunks)
  • packages/utils/src/tree-model/util.ts (1 hunks)
  • packages/utils/src/type/index.ts (1 hunks)
  • packages/utils/src/upload-ajax/index.ts (1 hunks)
  • packages/utils/src/validate/index.ts (1 hunks)
  • packages/utils/src/validate/messages.ts (1 hunks)
  • packages/utils/src/validate/rules/enum.ts (1 hunks)
  • packages/utils/src/validate/rules/index.ts (1 hunks)
  • packages/utils/src/validate/rules/pattern.ts (1 hunks)
  • packages/utils/src/validate/rules/range.ts (1 hunks)
  • packages/utils/src/validate/rules/required.ts (1 hunks)
  • packages/utils/src/validate/rules/type.ts (1 hunks)
  • packages/utils/src/validate/rules/whitespace.ts (1 hunks)
  • packages/utils/src/validate/schema.ts (1 hunks)
  • packages/utils/src/validate/util.ts (1 hunks)
  • packages/utils/src/validate/validations/array.ts (1 hunks)
  • packages/utils/src/validate/validations/date.ts (1 hunks)
  • packages/utils/src/validate/validations/enum.ts (1 hunks)
  • packages/utils/src/validate/validations/float.ts (1 hunks)
  • packages/utils/src/validate/validations/index.ts (1 hunks)
  • packages/utils/src/validate/validations/integer.ts (1 hunks)
  • packages/utils/src/validate/validations/method.ts (1 hunks)
  • packages/utils/src/validate/validations/number.ts (1 hunks)
  • packages/utils/src/validate/validations/pattern.ts (1 hunks)
  • packages/utils/src/validate/validations/required.ts (1 hunks)
  • packages/utils/src/validate/validations/string.ts (1 hunks)
  • packages/utils/src/validate/validations/type.ts (1 hunks)
  • packages/utils/src/window.ts (0 hunks)
  • packages/vue-directive/package.json (1 hunks)
  • packages/vue-directive/src/clickoutside.ts (1 hunks)
  • packages/vue-directive/src/infinite-scroll.ts (1 hunks)
  • packages/vue-directive/src/observe-visibility.ts (1 hunks)
  • packages/vue-directive/src/repeat-click.ts (1 hunks)
  • packages/vue-hooks/package.json (2 hunks)
  • packages/vue-hooks/src/useEventListener.ts (1 hunks)
  • packages/vue-hooks/src/useInstanceSlots.ts (1 hunks)
  • packages/vue-hooks/src/useRect.ts (1 hunks)
  • packages/vue-hooks/src/useRelation.ts (1 hunks)
  • packages/vue-hooks/src/useTouch.ts (1 hunks)
⛔ Files not processed due to max files limit (5)
  • packages/vue-hooks/src/useUserAgent.ts
  • packages/vue-hooks/src/useWindowSize.ts
  • packages/vue-hooks/src/vue-emitter.ts
  • packages/vue-hooks/src/vue-popper.ts
  • packages/vue-hooks/src/vue-popup.ts
💤 Files with no reviewable changes (1)
  • packages/utils/src/window.ts
✅ Files skipped from review due to trivial changes (4)
  • packages/utils/src/logger/index.ts
  • packages/utils/src/fastdom/index.ts
  • packages/utils/src/validate/rules/index.ts
  • packages/utils/src/fullscreen/index.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/utils/src/fecha/index.ts

[error] 22-22: The regular expression includes this negated empty character class.

Negated empty character classes match anything.
If you want to match against [, escape it [.
Otherwise, remove the character class or fill it.

(lint/correctness/noEmptyCharacterClassInRegex)


[error] 233-233: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/utils/src/browser/index.ts

[error] 31-31: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

packages/utils/src/debounce/index.ts

[error] 15-15: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/vue-directive/src/clickoutside.ts

[error] 39-39: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 55-55: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/resize-event/index.ts

[error] 56-56: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

packages/vue-hooks/src/useRect.ts

[error] 20-20: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/tree-model/tree-store.ts

[error] 124-124: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 161-165: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 175-176: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 179-180: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 330-334: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 353-353: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 360-363: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 383-385: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 404-405: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/dataset/index.ts

[error] 71-71: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 103-104: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 122-123: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 125-126: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/memorize/index.ts

[error] 116-116: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 118-118: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/utils/src/fastdom/singleton.ts

[error] 74-74: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/throttle/index.ts

[error] 38-38: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/utils/src/fullscreen/screenfull.ts

[error] 79-79: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 80-80: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 162-165: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 168-171: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 174-178: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/vue-hooks/src/useEventListener.ts

[error] 10-10: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 61-61: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/validate/rules/type.ts

[error] 125-125: Invalid typeof comparison value: this expression is not a string literal

not a string literal

(lint/suspicious/useValidTypeof)

packages/utils/src/popup-manager/index.ts

[error] 141-142: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 161-163: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/popper/index.ts

[error] 408-413: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 726-726: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 814-815: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 44-44: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 44-44: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.

(lint/suspicious/noGlobalIsFinite)


[error] 325-325: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


[error] 369-369: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)


[error] 386-386: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


[error] 481-481: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


[error] 483-483: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/utils/src/tree-model/node.ts

[error] 169-169: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 258-258: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 351-351: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 388-388: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 604-604: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 608-608: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 616-616: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/touch-emulator/index.ts

[error] 100-101: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/validate/util.ts

[error] 173-175: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 274-276: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 47-47: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/utils/src/bigInt/index.ts

[error] 16-16: Do not shadow the global "BigInt" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 274-276: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 350-353: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 62-62: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 67-67: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 321-321: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 342-342: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/utils/src/array/index.ts

[error] 190-190: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 121-122: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 125-125: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/vue-directive/src/infinite-scroll.ts

[error] 53-53: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)


[error] 112-112: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/date/index.ts

[error] 254-254: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 282-282: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/utils/src/type/index.ts

[error] 13-13: Do not shadow the global "toString" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 133-133: isFinite is unsafe. It attempts a type coercion. Use Number.isFinite instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isFinite instead.

(lint/suspicious/noGlobalIsFinite)

packages/utils/src/decimal/index.ts

[error] 243-244: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/resize-observer/index.ts

[error] 54-54: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 253-253: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 304-304: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 596-596: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 533-533: This aliasing of this is unnecessary.

Arrow functions inherits this from their enclosing scope.
Safe fix: Use this instead of an alias.

(lint/complexity/noUselessThisAlias)

packages/utils/src/calendar/index.ts

[error] 134-137: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/fullscreen/apis.ts

[error] 77-77: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/validate/schema.ts

[error] 160-160: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 166-167: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 316-318: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 349-349: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/object/index.ts

[error] 159-159: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 159-159: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 163-163: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 163-164: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 273-274: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/string/index.ts

[error] 62-62: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 323-323: Do not shadow the global "escape" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)


[error] 568-568: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 651-651: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)


[error] 755-755: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/utils/src/date-util/index.ts

[error] 252-252: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 45-45: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

🔇 Additional comments (96)
packages/utils/src/fastdom/sandbox.ts (2)

1-10: Documentation is clear and concise.
The header comment adequately describes the purpose of the utility, including authorship and its role in mitigating layout thrashing by batching DOM reads & writes.


58-64: Clear method logic looks correct.
The clear method properly delegates to clearAll when no argument is provided and uses remove() otherwise. This functionality is straightforward and meets typical FastDom usage needs.

packages/vue-hooks/src/useEventListener.ts (1)

1-2: Imports look good.
The initial import statements are concise and follow best practices in referencing shared utility functions.

packages/vue-directive/src/observe-visibility.ts (2)

1-4: Initial setup is clear.
The use of throttle and isEqual from @opentiny/utils is appropriate, and the context key approach clearly namespaces your directive’s internal state.


83-85: IntersectionObserver fallback
The explicit check and error throw for IntersectionObserver unavailability is excellent. This ensures a clear error message in unsupported browsers, rather than silent failures.

packages/vue-hooks/src/useRelation.ts (1)

27-29: Mandatory relation key check
Throwing an error when relationKey is missing is a good defensive measure, preventing errors further down the pipeline.

packages/utils/src/decimal/index.ts (2)

245-247: Validate integer parsing edge cases.
Ensure extremely large or small integer parts, or inputs with leading zeros, are correctly formatted and do not break the final string assembly.

Would you like a shell script to test these edge cases in other files referencing formatNumber?


133-133: Ensure negative subtraction handles large numbers properly.
When performing sub with large or very small values, confirm it behaves consistently with floating-point or large decimal inputs.

✅ Verification successful

Subtraction implementation verified as robust for large numbers
The implementation uses string-based arithmetic with proper exponent handling, ensuring consistent behavior with both large and small values while maintaining precision.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Use ephemeral test checks for decimal subtraction
rg --multiline --context 3 "Decimal\.sub" 

Length of output: 3007


Script:

#!/bin/bash
# Check for test files and add method implementation
rg -A 10 "class Decimal" packages/utils/src/decimal/index.ts

Length of output: 62


Script:

#!/bin/bash
# Search for the implementation details using multiple approaches
echo "=== Checking function declarations ==="
ast-grep --pattern 'function $NAME($ARGS) { $$$ }' packages/utils/src/decimal/index.ts

echo -e "\n=== Checking exports and declarations ==="
rg -A 5 "export" packages/utils/src/decimal/index.ts

echo -e "\n=== Looking for add implementation ==="
rg -B 2 -A 5 "\.add = " packages/utils/src/decimal/index.ts

Length of output: 5100

packages/utils/src/espace-ctrl/index.ts (1)

50-69: Check error handling when WebSocket is not ready.
If connected is false, the code short-circuits and returns. Confirm that the user receives helpful feedback or retries appropriately in real-world usage.

✅ Verification successful

Error handling for WebSocket connection is properly implemented
The current implementation provides appropriate error handling with:

  • Immediate feedback to users when disconnected
  • Automatic reconnection attempts with configurable polling interval
  • Custom error handling through error callbacks
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Confirm no missed call sites that rely on the send logic unconditionally
rg -A 3 "out\.init|out\.ready"

Length of output: 2758


Script:

#!/bin/bash
# Check WebSocket connection handling and error callbacks
rg -A 5 "ws = new WebSocket|connected = |out\.error = "

Length of output: 4383

packages/utils/src/fecha/index.ts (1)

22-22: Ignore the false positive from static analysis regarding an “empty character class.”
'[^\\s]+' correctly matches non-whitespace characters. This usage is valid and intentional.

🧰 Tools
🪛 Biome (1.9.4)

[error] 22-22: The regular expression includes this negated empty character class.

Negated empty character classes match anything.
If you want to match against [, escape it [.
Otherwise, remove the character class or fill it.

(lint/correctness/noEmptyCharacterClassInRegex)

packages/utils/src/validate/schema.ts (2)

316-318: Potential false positive from static analysis regarding optional chaining.
The code at lines 316-318 only passes seriesData and options into asyncMap; there is no property access or short-circuiting that would benefit from optional chaining. Verify whether you truly need to check if seriesData or options exist before usage.

🧰 Tools
🪛 Biome (1.9.4)

[error] 316-318: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


349-349: Likely a false positive from static analysis on optional chaining.
You’re directly checking rule.validator with isFunction(). Optional chaining is only helpful if you need to safely access properties of rule.validator, but here it’s an existence check plus type check, which is already valid.

🧰 Tools
🪛 Biome (1.9.4)

[error] 349-349: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/tree-model/tree-store.ts (2)

160-165: Evaluate possibility of optional chaining.
If node or childNodes are consistently defined, you might not need && checks. But if there's a scenario where these references can be null/undefined, optional chaining could simplify conditions.

🧰 Tools
🪛 Biome (1.9.4)

[error] 161-165: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


404-405: Optional chaining suggestion might be unnecessary.
If precision === 0, returning numberWithoutDecimal is straightforward and not a property access scenario. Static analysis likely triggered a false positive here.

🧰 Tools
🪛 Biome (1.9.4)

[error] 404-405: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/bigInt/index.ts (1)

350-353: Check optional chaining usage carefully.
Lines 350-353 use a direct property access on target.negate(). This is valid if target is guaranteed to be an instantiated decimal object. If target could be null/undefined, consider optional chaining to avoid potential runtime errors.

🧰 Tools
🪛 Biome (1.9.4)

[error] 350-353: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/object/index.ts (2)

159-159: Static Analysis False Positive.
No suspicious assignment is found here. This likely reflects a false positive from the static analysis.

🧰 Tools
🪛 Biome (1.9.4)

[error] 159-159: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 159-159: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


420-436: Confirm shallow merging logic in merge.
The merge function merges only the top level of each source object. For deeper merges, consider using the existing extend function or confirm that a shallow merge is intended.

packages/utils/src/tree-model/node.ts (1)

90-134: Validate existence of store in Node’s constructor.
Throwing an error when store is missing is good for debugging. Ensure that higher-level code handles this scenario gracefully, as this is a hard failure.

packages/utils/src/date/index.ts (1)

374-376: Protect against null or invalid date returns.
When parsing or converting dates, if date is null or invalid, the current code returns date. Ensure callers handle the possibility of a null or undefined return.

packages/utils/src/popper/index.ts (1)

814-815: Double-check condition structure.

if (this._options.bubbling || PopupManager.globalScroll) {
  let targets = getAllScrollParents(this._reference)
  ...
}

Ensure you truly want to rely on both bubbling and PopupManager.globalScroll as a single combined condition, and confirm no unexpected side effects occur when enabling both. Verify you have test coverage for each scenario.

✅ Verification successful

The condition structure is correct and intentional

The bubbling || PopupManager.globalScroll condition is properly designed to:

  • Allow individual control through the bubbling option
  • Provide a global override through PopupManager.globalScroll for specific scrolling scenarios
  • Handle ancestor scroll listeners consistently

This is confirmed by the implementation comments and changelog documentation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Search for PopupManager.globalScroll usages
echo "=== PopupManager.globalScroll usages ==="
rg "PopupManager\.globalScroll" -A 2

echo -e "\n=== Test files containing PopupManager ==="
fd "test|spec" -e ts -e js | xargs rg "PopupManager" -l

echo -e "\n=== Documentation or comments about bubbling and globalScroll ==="
rg -B 2 "bubbling.*globalScroll|globalScroll.*bubbling" --type ts

Length of output: 3924

🧰 Tools
🪛 Biome (1.9.4)

[error] 814-815: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

packages/utils/src/tree-model/index.ts (3)

1-1: Re-exports look good for modular usage.
All three utility exports (NODE_KEY, getNodeKey, markNodeData) from ./util align well with the tree-model design, providing a clean and direct API for downstream usage.


3-3: Seamless node management.
Exporting getChildState and Node from ./node ensures centralized, reusable logic for node state handling throughout the tree model.


5-5: TreeStore export confirms cohesive structure.
Making TreeStore public promotes a clear entry point for managing the entire tree and eases integration.

packages/utils/src/globalConfig/index.ts (3)

1-2: Environment check logic is consistent.
isWeb() correctly distinguishes between web and non-web environments, enabling platform-specific fallbacks.


10-12: Global config object fosters modular configuration.
Maintaining viewportWindow here is a clean, decoupled approach, especially for micro-frontend scenarios.


14-14: Fallback logic to default window object is robust.
getViewportWindow ensures that a suitable global context is always returned, preventing undefined references in typical web contexts.

packages/vue-hooks/src/useRect.ts (2)

1-9: Window check & DOMRect constructor are logically sound.
isWindow and makeDOMRect form a clear separation of concerns: environment detection vs. DOMRect-like data creation.


11-25: Reactive element dimension retrieval works as intended.
useRect effectively handles both window and element references, returning a standard structure for dimension metrics.

🧰 Tools
🪛 Biome (1.9.4)

[error] 20-20: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/crypt/index.ts (1)

1-1: Import source transition aligns with global config.
Switching getWindow to import from globalConfig improves alignment with the new central environment logic.

packages/utils/src/validate/index.ts (2)

17-18: Confirm that validators and getDefaultMessage are assigned correctly.

Overwriting properties on Schema is acceptable, but verify that neither property is sealed or overridden elsewhere. Maintaining a single definition source might reduce confusion over time.


20-20: The export looks good.

Exporting Validator as Schema ensures the validation logic is accessible without duplicating code.

packages/utils/src/validate/rules/required.ts (1)

16-20: Consider handling edge cases when rule.field is undefined.
If rule.field is missing or undefined, hasOwn.call(source, rule.field) might produce unexpected results. Ensure that rule.field is always a valid identifier or handle such cases gracefully.

packages/utils/src/tree-model/util.ts (2)

13-13: No issues found with this constant declaration.
Defining NODE_KEY as '$treeNodeId' is clear and concise.


15-20: Consider verifying the presence of the fallback key in all usage contexts.
Currently, if key is falsy, this function retrieves data[NODE_KEY]. In scenarios where data doesn’t contain NODE_KEY, the result could be undefined. Ensure that the calling code properly handles this edge case.

packages/vue-hooks/src/useInstanceSlots.ts (3)

1-3: Well-structured composition function signature.
Using destructuring for environment detection (isVue2) and lifecycle hooks is a clean approach.


11-13: Clever solution for avoiding Vue 3 warnings.
Defining $scopedSlots as null on the Vue 3 instance helps mute unwanted warnings. This approach cleanly supports dual compatibility between Vue 2 and Vue 3.


20-28: Confirm the need for property deletion on unmount.
Deleting $scopedSlots and instanceSlots may enhance memory cleanup, but confirm that no reactivity-based usage is needed post-unmount. If reactivity is not a concern at this stage, this approach is fine.

packages/utils/src/validate/validations/method.ts (1)

17-31: Validate behavior for null or other falsey values.
This function correctly skips type checking when checkValue is undefined. However, if checkValue can be null or an empty string, confirm if type checking should also be skipped or performed. Otherwise, some unexpected values might bypass type validation.

packages/utils/src/validate/validations/pattern.ts (2)

33-33: Ensure the callback usage is consistent with your validation framework.

You pass an errors array to callback whether it's empty or not. Confirm that your overall validation system expects an array here, as some frameworks expect callback(null, errors) upon success or callback(errors, null) upon failure. If this code works as intended in your environment, you can disregard this note.


17-20: Check the conditional validation logic carefully.

Your logic for validate determines whether to run validation based on rule.required or the presence of the field in source. This is a solid approach but can create subtle issues if some fields aren't strictly required but still need to be validated. Make sure this condition aligns with your overall validation strategy across the codebase.

To confirm consistency across the repository, run:

✅ Verification successful

The validation logic is well-designed and consistently implemented

The conditional validation pattern is correctly implemented and consistently used across all validation types in the codebase. It properly handles both required and optional fields while ensuring that present fields are validated appropriately.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
rg "(!rule\.required" -A 5

Length of output: 96


Script:

#!/bin/bash
# Search for validation patterns with proper escaping
rg "\(!?rule\.required.*source" -A 3

# Find all validation-related files
fd "valid" --type f

# Search for rule.required usage
rg "rule\.required" -A 2

Length of output: 38383

packages/utils/src/validate/validations/enum.ts (2)

19-22: Clarify the enum-check activation logic.

The condition rule.required || (!rule.required && hasOwn.call(source, rule.field)) ensures validation is triggered if the field is required or present in the source. This is identical to the pattern used in other validation files, which is consistent. Just ensure that your enum rules correctly handle optional fields when rule.required is false.


23-32: Validate behavior for undefined vs. empty.

In line 24, you check isEmptyValue and call callback() if the field is not required. Later, if checkValue !== undefined, you proceed with rules[ENUM]. Confirm whether you also need to differentiate an empty string from an undefined value. If not, this logic is acceptable.

packages/utils/src/validate/validations/float.ts (2)

17-20: Revisit the hasOwn-based validation check.

The expression rule.required || (!rule.required && hasOwn.call(source, rule.field)) is repeated across these validations. It reads well, but if you ever want a field validated only when provided (even if not required), confirm you intend to skip it entirely when absent. This can be a valid choice but merits re-verification in the broader schema usage.


34-34: Propagate errors consistently.

The callback is invoked with an errors array, matching the pattern in other validations. If your system consistently expects an array, this looks good. If a different callback signature is used in certain edge cases, confirm that no unexpected behavior arises from passing an empty array vs. null.

packages/utils/src/validate/validations/integer.ts (2)

17-20: Consider integer-specific checks for edge cases.

Similarly to your float validation, you’re only skipping validation when the field isn’t required and not present in source. Make sure that truly optional integer fields don’t inadvertently bypass other rules that might still apply (e.g., a custom minimum integer check).


34-34: Finalize standard error format.

As with the other files, passing an errors array into callback is consistent with your established pattern. Validate that each error item is properly structured to feed seamlessly into your UI or logging system.

packages/utils/src/after-leave/index.ts (1)

25-35: Consider validating instance interface.

The code assumes instance.$once and instance.$on are available, suggesting a Vue instance. If there's a scenario where afterLeave is called with a custom object, you may need additional checks or a fallback to avoid runtime errors.

packages/utils/src/validate/validations/type.ts (1)

22-25: Handle early exit more explicitly.

When the value is empty and not required, you return immediately. This logic is valid, but double-check that you don’t need any finalization or logging before returning to ensure consistent flow with other validation paths.

packages/utils/src/fastdom/async.ts (2)

1-10: Documentation is clear and well-structured.
The file header and author credits are properly documented. This ensures clarity regarding the purpose and authorship of this utility.


57-59: LGTM
Exporting the extended singleton as fastdomAsync is a neat approach and aligns with the intended usage.

packages/utils/src/validate/validations/number.ts (1)

1-16: License and imports are consistent with project standards.
No issues found.

packages/utils/src/validate/validations/index.ts (2)

1-11: LGTM
The header section follows the standard documentation and licensing format.


13-24: Import statements are well-organized.
No concerns about the chosen named imports for validation utilities.

packages/utils/src/scroll-into-view/index.ts (2)

1-11: Documentation and license block look good.
No issues found in the header.


13-13: Server-side check is succinct and sufficient.
The isServer variable elegantly captures server-render context.

packages/utils/src/touch/index.ts (3)

15-25: Direction detection appears correct

The simple checks for horizontal or vertical based on a 10px threshold are valid and straightforward.


27-33: Check event.touches availability

In non-touch environments or certain edge cases, event.touches might be missing or empty. Consider runtime checks or fallbacks for multi-platform usage.


45-51: Reset logic is concise and effective

No concurrency or safety issues spotted. This function cleanly re-initializes the state.

packages/utils/src/validate/validations/date.ts (2)

20-21: Ensure date string validation covers edge cases.
isValidDateStr checks against the classic "Invalid Date" string, but some date edge cases (e.g., timezone formatting quirks, partial date strings) might still slip through. Confirm that this helper sufficiently covers all formats you need to support.


38-42: Verify that date/time range logic meets functional requirements.
The code calls rules.type followed by rules.range based on dateObject.getTime(). Ensure that the intended time boundaries correctly match any required business logic (e.g., offset from current time, epoch boundaries, etc.).

packages/vue-hooks/src/useTouch.ts (1)

54-56: Clarify tap detection logic.
isTap is set to false if offsetX or offsetY exceeds 5. Confirm that this offsets-based approach is sufficient for your use cases (e.g., detecting very small drags on high-resolution screens).

packages/utils/src/validate/rules/range.ts (1)

61-67: Refine len vs. min, max logic.
The function uses len strictly and otherwise checks min, max. Confirm that numeric values do not need both len and min, max to be simultaneously validated in some scenarios (e.g., exact length vs. within range).

packages/utils/src/event/index.ts (1)

57-62: Add robust fallback in getActualTarget.
If e.composedPath is not supported, you may need additional logic for older browsers. Provide a fallback or document that certain browsers might not be fully compatible.

packages/utils/src/fastdom/singleton.ts (2)

1-10: Great use of descriptive header comments.
These lines clearly communicate the purpose of the module and credit the authors. No issues found.


116-118: Exporting a singleton is fine for most use cases.
If multiple independent batching queues are needed, consider exporting a factory function that returns new instances.

packages/utils/src/upload-ajax/index.ts (2)

51-53: Confirm robust fallback handling.
If XMLHttpRequest is undefined, the function returns prematurely. Ensure that your code checks for compatibility or provides graceful fallbacks for legacy environments.


58-65: Check presence of onProgress.
Similar to onError, confirm that option.onProgress exists or guard it. If the user fails to provide an onProgress callback, calling it would cause an error.

packages/utils/src/validate/messages.ts (2)

36-36: Confirm correct translation key usage.
specialch2 reuses translate('validation.types.hex'), which might be unintentional if you need a distinct message. Verify that this is correct or change it to a unique key.


41-73: Well-structured validation messages.
The exported function systematically covers all needed validation cases. No immediate issues found.

packages/utils/src/touch-emulator/index.ts (2)

81-92: Guard early returns.
The event flow is straightforward. No concurrency or data-race concerns appear. Just ensure that the correct event propagation strategy suits your UI needs.


110-124: Logical separation of touch emulation.
Isolating this in emulate is beneficial for code clarity. No issues here.

packages/utils/src/browser/index.ts (2)

13-25: Validate fallback logic for older Internet Explorer versions
The getIEVersion function correctly identifies IE versions 8 through 11 using standard feature detection. Consider adding an extra safeguard for environments that may lack certain APIs, in case users rely on a legacy document mode.


38-40: Ensure environment detection covers edge cases
isBrowser effectively checks for browser presence, but in certain SSR or hybrid rendering environments (e.g., partial DOM mocking), some conditions may pass or fail unexpectedly. Keep that in mind if your code might run on advanced server setups.

packages/utils/src/throttle/index.ts (1)

38-89: Overall design looks robust
Your throttle implementation, including the wrapper for execution control, cancel, and the optional “begin or end” mode, provides a flexible solution for event rate limiting. Good job!

🧰 Tools
🪛 Biome (1.9.4)

[error] 38-38: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/utils/src/calendar/index.ts (3)

10-12: Be mindful of zero-based months
month - 1 for indexing the days array can introduce off-by-one errors if month data is not validated. Ensure the caller always passes months in 1–12 range.


68-112: Check boundary conditions for edge months
getCalendar covers standard month transitions effectively. As an extra precaution, consider validating that year and month are in a permissible range (e.g., year >= 0).


121-138: Consider using optional chaining carefully
A static analysis hint suggests optional chaining. Since you explicitly allocate result[i] = [], the indexing is safe. If you prefer safer null checks or more robust logic around array, optional chaining might help, but it’s not strictly required.

🧰 Tools
🪛 Biome (1.9.4)

[error] 134-137: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/vue-directive/src/clickoutside.ts (2)

71-86: Overall directive design is solid
The logic for mousedown vs. mouseup triggers is neatly handled via modifiers, and the approach of storing directive metadata in el[nameSpace] is well-structured.


115-116: Deletion pattern is acceptable
delete el[nameSpace] is used at unbind. Considering el[nameSpace] is a property specifically injected by the directive, it’s a valid approach. This is less critical than performance-based runtime deletions on frequently accessed objects.

packages/utils/src/fullscreen/apis.ts (2)

91-190: Validate event unbinding and concurrency.
In the main fullscreen api, the event unbinding happens in fullScreenCallback and exit methods. Confirm that repeated calls to toggle() or calls in quick succession won’t cause race conditions where listeners remain bound or states become inconsistent.

✅ Verification successful

Event handling implementation is safe and race-condition free
The code properly manages event listeners and state transitions. The implementation prevents concurrent operations through state gates, ensures proper cleanup of event listeners, and maintains consistent state through atomic updates. No evidence of concurrent or rapid-fire calls in the codebase that could cause race conditions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Look for concurrent calls to `api.request` or `api.exit` from across the codebase.
rg -A 5 'api\.request|api\.exit'

Length of output: 2649


36-55: Confirm restoration logic for resetElement().
When resetting a fullscreen element, it's good that you restore original styles and reinsert the element in its parent node if teleport was used. Ensure that this logic also gracefully handles cases where the parent node is absent or the node changes asynchronously.

✅ Verification successful

resetElement() implementation verified as safe and robust

The function properly handles asynchronous DOM changes through:

  • Guarded DOM operations with null checks
  • Proper cleanup of resources and event listeners
  • Consistent state management via Promise-based control flow
  • Safe restoration of element position and styles
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for references to resetElement in the codebase 
# to confirm that all call sites handle possible asynchronous DOM changes.
rg -A 5 'resetElement'

Length of output: 3976


Script:

#!/bin/bash
# Find the definition and usage context of parentNode and token variables
rg -B 10 -A 2 'const resetElement' packages/utils/src/fullscreen/apis.ts

Length of output: 408


Script:

#!/bin/bash
# Get the complete file content to understand variable scope and initialization
cat packages/utils/src/fullscreen/apis.ts

Length of output: 4915

packages/utils/src/fullscreen/screenfull.ts (1)

78-81: Validate cross-browser support.
screenfull comprehensively checks multiple APIs, but confirm that older prefixes (moz, webkit, ms) are still relevant. Some modern browsers may have phased them out.

Also applies to: 160-176

🧰 Tools
🪛 Biome (1.9.4)

[error] 79-79: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 80-80: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/array/index.ts (1)

31-41: Fallback checks in indexOf.
When Array.isArray(arr) is false, you return -1. Ensure that upstream usage gracefully handles non-array inputs or an unexpected -1 result.

packages/utils/src/validate/util.ts (1)

173-175: Check indexing logic in asyncSerialArray.
When fn(arr[original], checkNext) is called, ensure that edge cases (e.g., modifications to arr) won’t cause skipping or duplication.

🧰 Tools
🪛 Biome (1.9.4)

[error] 173-175: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/utils/src/common/index.ts (3)

116-117: Validate IP threshold usage.
IPTHRESHOLD.Max is set to 255, presumably for octet-based IP addresses. If IPv6 or other address forms are considered, ensure that references to this constant handle them correctly or are restricted to IPv4 contexts only.


118-127: Double-check date format correctness.
While these date formats appear standard, confirm consistency with the rest of the codebase to avoid discrepancies in usage (e.g., 12-hour vs. 24-hour).


223-228: Validate fallback of version environment variable.
If process.env.RUNTIME_VERSION is undefined or removed in certain build environments, ensure that this export either defaults to a safe string or gracefully handles missing environment variables.

packages/utils/src/dom/index.ts (2)

144-159: Edge cases for isScroll detection.
The current implementation checks the overflow property for "scroll|auto", but modern browsers may return "overlay". You properly handle "overlay" in your regex. Confirm that any upstream usage is tested in browsers (e.g., Chrome, Safari) where overlay might not be recognized.


236-240: Ensure safe alternative for scrollTop retrieval in older browsers.
Accessing el.scrollTop directly is fine in most modern browsers, but if supporting older browsers or special contexts, fallback logic might be necessary. Currently it looks good, just keep an eye on cross-browser coverage.

packages/utils/src/date-util/index.ts (1)

170-198: Watch out for large ranges in getRangeMinutes.
If ranges includes many intervals, building an array of 60 flags for each hour is still efficient, but ensure it meets performance demands under heavy usage.

packages/utils/src/string/index.ts (2)

812-834: Consider a safer fallback for 2D context retrieval.
In some non-browser or limited DOM contexts, canvas.getContext('2d') may be null. Consider gracefully handling this scenario.


651-659: ⚠️ Potential issue

Use Number.isNaN for numeric validation.
Replacing isNaN with Number.isNaN helps ensure more predictable numeric checks.

- return NaN

(Apply similarly within logic blocks where you check isNaN or do numeric conversions.)

Likely invalid or redundant comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 651-651: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

packages/vue-hooks/package.json (2)

18-18: LGTM! Dependency addition aligns with PR objectives.

The addition of @opentiny/utils as a workspace dependency aligns with the PR objective of refactoring from renderless/common.


5-7: Complete the package metadata fields.

The following fields are empty or need verification:

  • author: Should include the package maintainer's information
  • keywords: Add relevant keywords to improve package discoverability
  • license: Verify if ISC is the intended license (most OpenTiny packages typically use MIT)

Run this script to check the license consistency across the monorepo:

packages/vue-directive/package.json (2)

5-7: Complete the package metadata fields.

The following fields are empty or need verification:

  • author: Should include the package maintainer's information
  • keywords: Consider adding relevant keywords like "vue-directive", "infinite-scroll", "clickoutside", "intersection-observer" to improve package discoverability
  • license: Verify if ISC is the intended license (most OpenTiny packages typically use MIT)

17-19: LGTM! Dependencies are properly organized.

The addition of @opentiny/utils as a workspace dependency and the reordering of dependencies improve the package organization while aligning with the PR objective of refactoring from renderless/common.

Comment on lines +34 to +44
measure(fn, ctx) {
const tasks = this.tasks
const task = this.fastdom.measure(function () {
tasks.splice(tasks.indexOf(task))
return fn.call(ctx)
})

tasks.push(task)

return task
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix splice usage to remove only one task.
Using tasks.splice(tasks.indexOf(task)) without a second argument removes everything from that index to the end of the array. This is likely unintended. Update the code to remove exactly one element:

- tasks.splice(tasks.indexOf(task))
+ tasks.splice(tasks.indexOf(task), 1)
📝 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.

Suggested change
measure(fn, ctx) {
const tasks = this.tasks
const task = this.fastdom.measure(function () {
tasks.splice(tasks.indexOf(task))
return fn.call(ctx)
})
tasks.push(task)
return task
}
measure(fn, ctx) {
const tasks = this.tasks
const task = this.fastdom.measure(function () {
tasks.splice(tasks.indexOf(task), 1)
return fn.call(ctx)
})
tasks.push(task)
return task
}

Comment on lines +46 to +56
mutate(fn, ctx) {
const tasks = this.tasks
const task = this.fastdom.mutate(function () {
tasks.splice(tasks.indexOf(task))
return fn.call(ctx)
})

this.tasks.push(task)

return task
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Apply the same splice fix in mutate.
As in the measure method, ensure only the single matching item is removed from the tasks array:

- tasks.splice(tasks.indexOf(task))
+ tasks.splice(tasks.indexOf(task), 1)
📝 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.

Suggested change
mutate(fn, ctx) {
const tasks = this.tasks
const task = this.fastdom.mutate(function () {
tasks.splice(tasks.indexOf(task))
return fn.call(ctx)
})
this.tasks.push(task)
return task
}
mutate(fn, ctx) {
const tasks = this.tasks
const task = this.fastdom.mutate(function () {
tasks.splice(tasks.indexOf(task), 1)
return fn.call(ctx)
})
this.tasks.push(task)
return task
}


reslut = roundFixed(reslut.toString(), fraction, rounding)

format.zeroize === false && reslut.match(/\./) && (reslut = reslut.replace(/\.?0+$/g, ''))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid side-effect assignment in the expression.
This assignment within logical operators can be confusing. Consider a conditional block instead.

- format.zeroize === false && reslut.match(/\./) && (reslut = reslut.replace(/\.?0+$/g, ''))
+ if (format.zeroize === false && reslut.match(/\./)) {
+   reslut = reslut.replace(/\.?0+$/g, '')
+ }
📝 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.

Suggested change
format.zeroize === false && reslut.match(/\./) && (reslut = reslut.replace(/\.?0+$/g, ''))
if (format.zeroize === false && reslut.match(/\./)) {
reslut = reslut.replace(/\.?0+$/g, '')
}

Comment on lines +233 to +234
if (!isDate(dateObj) || isNaN(dateObj.getTime())) {
throw new Error('Invalid Date in fecha.format')
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use Number.isNaN instead of isNaN.
Use Number.isNaN for stricter checking without type coercion.

- if (!isDate(dateObj) || isNaN(dateObj.getTime())) {
+ if (!isDate(dateObj) || Number.isNaN(dateObj.getTime())) {
📝 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.

Suggested change
if (!isDate(dateObj) || isNaN(dateObj.getTime())) {
throw new Error('Invalid Date in fecha.format')
if (!isDate(dateObj) || Number.isNaN(dateObj.getTime())) {
throw new Error('Invalid Date in fecha.format')
🧰 Tools
🪛 Biome (1.9.4)

[error] 233-233: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

import { fillChar } from '../string'
import { isBrowser } from '../browser'

const BigInt = isBrowser ? window.BigInt : global.BigInt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Rename local BigInt variable to avoid overshadowing the global.
Shadowing the global BigInt can lead to confusion. Consider renaming it to reflect its purpose.

- const BigInt = isBrowser ? window.BigInt : global.BigInt
+ const GlobalBigInt = isBrowser ? window.BigInt : global.BigInt
📝 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.

Suggested change
const BigInt = isBrowser ? window.BigInt : global.BigInt
const GlobalBigInt = isBrowser ? window.BigInt : global.BigInt
🧰 Tools
🪛 Biome (1.9.4)

[error] 16-16: Do not shadow the global "BigInt" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

Comment on lines +252 to +257
let minTempDate = (minDate = new Date(Math.min(nrange[0], minDate)))
maxDate = new Date(Math.max(nrange[1], minTempDate))
})

const ret = ndate < minDate ? minDate : maxDate
return modifyDate(ret, date.getFullYear(), date.getMonth(), date.getDate())
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Refactor assignment in expression to improve clarity.
Expressions with an assignment may be confusing. Extract the assignment into a separate statement.

- let minTempDate = (minDate = new Date(Math.min(nrange[0], minDate)))
+ minDate = new Date(Math.min(nrange[0], minDate))
+ let minTempDate = minDate
📝 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.

Suggested change
let minTempDate = (minDate = new Date(Math.min(nrange[0], minDate)))
maxDate = new Date(Math.max(nrange[1], minTempDate))
})
const ret = ndate < minDate ? minDate : maxDate
return modifyDate(ret, date.getFullYear(), date.getMonth(), date.getDate())
minDate = new Date(Math.min(nrange[0], minDate))
let minTempDate = minDate
maxDate = new Date(Math.max(nrange[1], minTempDate))
})
const ret = ndate < minDate ? minDate : maxDate
return modifyDate(ret, date.getFullYear(), date.getMonth(), date.getDate())
🧰 Tools
🪛 Biome (1.9.4)

[error] 252-252: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

}

const camelizeRE = /-(\w)/g
export const camelize = cached((str) => str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : '')))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid assignment inside expression for clarity.
Rewriting any assignment within the function body helps maintain code clarity and avoids confusion in expressions.

🧰 Tools
🪛 Biome (1.9.4)

[error] 62-62: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

}

let level = 0
for (let i = 0; i < index && (value <= -1024 || value >= 1024); i++) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use Number.isNaN for the same reason.
Again, avoid global isNaN.

🧰 Tools
🪛 Biome (1.9.4)

[error] 755-755: isNaN is unsafe. It attempts a type coercion. Use Number.isNaN instead.

See the MDN documentation for more details.
Unsafe fix: Use Number.isNaN instead.

(lint/suspicious/noGlobalIsNan)

Comment on lines +292 to +312
export const escape = (string, escapeType, isReplaceSpace) => {
if (!string || typeof string !== 'string') {
return string
}

if (typeof escapeType === 'boolean') {
isReplaceSpace = !!escapeType
}

if (escapeType === 'uri') {
return encodeURIComponent(string)
} else if (escapeType === 'html') {
return escapeHtml(string, isReplaceSpace)
} else if (escapeType === 'prop') {
string = escapeHtml(string, isReplaceSpace)
return string.replace(/[[\]]/g, (chr) => escapeChars[chr])
}

string = string.replace(/[<>"]/g, (chr) => escapeChars[chr])
return isReplaceSpace ? string.replace(/\s/g, '&#160;') : string
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Rename the escape function to avoid shadowing the global escape method.
This can cause confusion and potential naming collisions, especially in browsers. Consider a more descriptive name, e.g., escapeString.

-export const escape = (string, escapeType, isReplaceSpace) => {
+export const escapeString = (string, escapeType, isReplaceSpace) => {
📝 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.

Suggested change
export const escape = (string, escapeType, isReplaceSpace) => {
if (!string || typeof string !== 'string') {
return string
}
if (typeof escapeType === 'boolean') {
isReplaceSpace = !!escapeType
}
if (escapeType === 'uri') {
return encodeURIComponent(string)
} else if (escapeType === 'html') {
return escapeHtml(string, isReplaceSpace)
} else if (escapeType === 'prop') {
string = escapeHtml(string, isReplaceSpace)
return string.replace(/[[\]]/g, (chr) => escapeChars[chr])
}
string = string.replace(/[<>"]/g, (chr) => escapeChars[chr])
return isReplaceSpace ? string.replace(/\s/g, '&#160;') : string
}
export const escapeString = (string, escapeType, isReplaceSpace) => {
if (!string || typeof string !== 'string') {
return string
}
if (typeof escapeType === 'boolean') {
isReplaceSpace = !!escapeType
}
if (escapeType === 'uri') {
return encodeURIComponent(string)
} else if (escapeType === 'html') {
return escapeHtml(string, isReplaceSpace)
} else if (escapeType === 'prop') {
string = escapeHtml(string, isReplaceSpace)
return string.replace(/[[\]]/g, (chr) => escapeChars[chr])
}
string = string.replace(/[<>"]/g, (chr) => escapeChars[chr])
return isReplaceSpace ? string.replace(/\s/g, '&#160;') : string
}

Comment on lines +508 to +522
/**
* 尝试按指定函数转换字符串,如果转换结果为 NaN,则返回 defaultValue。
*
* tryToConvert(toInt, null, 0) // 0
*
* @param {Function} convert 指定的转换的函数
* @param {Number|String} defaultValue 若为 NaN 时,返回的缺省值
* @param {Number|String} value 要转换的字符串或多个参数
* @returns {Number|String}
*/
export const tryToConvert = (convert, defaultValue, ...args) => {
// eslint-disable-next-line prefer-spread
const result = convert.apply(null, args)
return isNaN(result) ? defaultValue : result
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use Number.isNaN for safer checks.
The usage of isNaN(result) can lead to unexpected outcomes due to type coercion.

- return isNaN(result) ? defaultValue : result
+ return Number.isNaN(result) ? defaultValue : result
📝 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.

Suggested change
/**
* 尝试按指定函数转换字符串,如果转换结果为 NaN,则返回 defaultValue。
*
* tryToConvert(toInt, null, 0) // 0
*
* @param {Function} convert 指定的转换的函数
* @param {Number|String} defaultValue 若为 NaN 时,返回的缺省值
* @param {Number|String} value 要转换的字符串或多个参数
* @returns {Number|String}
*/
export const tryToConvert = (convert, defaultValue, ...args) => {
// eslint-disable-next-line prefer-spread
const result = convert.apply(null, args)
return isNaN(result) ? defaultValue : result
}
/**
* 尝试按指定函数转换字符串,如果转换结果为 NaN,则返回 defaultValue。
*
* tryToConvert(toInt, null, 0) // 0
*
* @param {Function} convert 指定的转换的函数
* @param {Number|String} defaultValue 若为 NaN 时,返回的缺省值
* @param {Number|String} value 要转换的字符串或多个参数
* @returns {Number|String}
*/
export const tryToConvert = (convert, defaultValue, ...args) => {
// eslint-disable-next-line prefer-spread
const result = convert.apply(null, args)
return Number.isNaN(result) ? defaultValue : result
}

@zzcr zzcr merged commit 457c1f4 into opentiny:dev Jan 26, 2025
6 checks passed
@shenjunjian shenjunjian deleted the dev-refactor-common-to-utils branch March 10, 2025 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants