-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(cdk:utils): add some methods to control subscribers in createSharedComposable #1519
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -223,4 +223,6 @@ export function useInputModalityDetector(options?: InputModalityDetectorOptions) | |
} | ||
} | ||
|
||
export const useSharedInputModalityDetector = createSharedComposable(() => useInputModalityDetector()) | ||
export const { useComposable: useSharedInputModalityDetector } = createSharedComposable(() => | ||
useInputModalityDetector(), | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. with code review The patch above looks valid and should work as expected. To make sure it is error-free, I would suggest running a linter or static analysis tool to check for any potential issues. Additionally, it could be beneficial to add unit tests to ensure the code behaves as intended. Finally, if feasible, consider refactoring the code to make it more readable and maintainable. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,4 +43,4 @@ export function useBreakpoints<T extends string>(value?: Record<T, string>): Rec | |
return match as Record<T, boolean> | ||
} | ||
|
||
export const useSharedBreakpoints = createSharedComposable(() => useBreakpoints()) | ||
export const { useComposable: useSharedBreakpoints } = createSharedComposable(() => useBreakpoints()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. code review. The code patch looks good. It is updating the function useSharedBreakpoints to make it a shared composable. The new code is using the createSharedComposable function, which will enable the use of the useBreakpoints function in multiple components. There are no bugs risks seen in this patch. It can be improved by adding comments to the code, which will help explain the change and clarify why it was done. Additionally, adding error handling to the useBreakpoints function would be beneficial, to ensure that the code handles unexpected errors gracefully. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,13 +5,13 @@ | |
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE | ||
*/ | ||
|
||
import type { DnDContext } from './useDragDropContext' | ||
import type { DnDEventName, DnDEventType, DnDPosition, DraggableOptions } from '../types' | ||
|
||
import { type ComputedRef, computed, ref, watch } from 'vue' | ||
|
||
import { type MaybeElementRef, convertElement, tryOnScopeDispose, useEventListener } from '@idux/cdk/utils' | ||
|
||
import { DnDContext } from './useDragDropContext' | ||
import { withBoundary } from './withBoundary' | ||
import { withDragFree } from './withDragFree' | ||
import { withDragHandle } from './withDragHandle' | ||
|
@@ -37,7 +37,8 @@ export function useDraggable( | |
reset: () => void | ||
stop: () => void | ||
} { | ||
context = initContext(context) | ||
const { context: _context, delSubscribers } = initContext(context) | ||
context = _context | ||
|
||
const registry = context.registry! | ||
const stateRef = ref<DnDState>() | ||
|
@@ -68,6 +69,10 @@ export function useDraggable( | |
} | ||
|
||
const offDraggable = (sourceElement: HTMLElement) => { | ||
if (delSubscribers) { | ||
delSubscribers() | ||
} | ||
|
||
registry.off(sourceElement) | ||
listenerStops.forEach(listenerStop => listenerStop()) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code looks alright. The main issue I can see is that the context variable is not declared with a const or let keyword, which may lead to unexpected behaviour. Also, the code does not have any comments which would help explain what it does and how it works. Other than that, the code looks to be well written and organized. There are no major bug risks that I can see. As for improvement suggestions, I would suggest adding comments to explain the purpose of each function and/or block of code. This would make the code easier to understand and maintain. Additionally, you could also add some type checking to ensure that the variables being passed in are of the correct type. |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,27 +11,37 @@ import { createSharedComposable } from '@idux/cdk/utils' | |
|
||
import { type DnDContext, _dnDContextMap, useDragDropContext } from './composables/useDragDropContext' | ||
|
||
const useDnDContext = createSharedComposable(useDragDropContext) | ||
const { useComposable: useDnDContext, addSubscribers, delSubscribers } = createSharedComposable(useDragDropContext) | ||
|
||
/** | ||
* get context | ||
* | ||
* @param targetContext | ||
*/ | ||
export const initContext = (targetContext?: DnDContext): DnDContext => { | ||
export const initContext = ( | ||
targetContext?: DnDContext, | ||
): { | ||
context: DnDContext | ||
delSubscribers?: () => void | ||
} => { | ||
let context = {} as DnDContext | ||
// default context is window | ||
if (!targetContext) { | ||
const root = document as unknown as HTMLElement | ||
|
||
if (!_dnDContextMap.has(root)) { | ||
context = useDnDContext(root) | ||
_dnDContextMap.set(root, context) | ||
return { context } | ||
} else { | ||
addSubscribers() | ||
context = _dnDContextMap.get(root)! | ||
return { context, delSubscribers } | ||
} | ||
return context | ||
} | ||
return targetContext | ||
return { | ||
context: targetContext, | ||
} | ||
} | ||
|
||
/** | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the code review
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,27 +13,42 @@ import { callEmit } from './props' | |
import { tryOnScopeDispose } from './tryOnScopeDispose' | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
export function createSharedComposable<T extends (...args: any[]) => ReturnType<T>>(composable: T): T { | ||
export function createSharedComposable<T extends (...args: any[]) => ReturnType<T>>( | ||
composable: T, | ||
): { useComposable: T; addSubscribers: () => void; delSubscribers: () => void } { | ||
let subscribers = 0 | ||
let state: ReturnType<T> | undefined | ||
let scope: EffectScope | undefined | ||
|
||
const dispose = () => { | ||
if (scope && --subscribers <= 0) { | ||
subscribers -= 1 | ||
|
||
if (scope && subscribers <= 0) { | ||
scope.stop() | ||
state = scope = undefined | ||
} | ||
} | ||
|
||
return ((...args) => { | ||
const addSubscribers = () => { | ||
subscribers++ | ||
} | ||
|
||
const delSubscribers = () => { | ||
dispose() | ||
} | ||
|
||
const useComposable = ((...args) => { | ||
subscribers++ | ||
|
||
if (!state) { | ||
scope = effectScope(true) | ||
state = scope.run(() => composable(...args)) | ||
} | ||
tryOnScopeDispose(dispose) | ||
return state | ||
}) as T | ||
|
||
return { useComposable, addSubscribers, delSubscribers } | ||
} | ||
|
||
export function useState<T>(defaultOrFactory: T | (() => T), shallow = true): [ComputedRef<T>, (value: T) => void] { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the code review: First, the code appears to be well commented and formatted, which helps to make it easy to read. It also follows best practices, such as using descriptive variable names and disabling eslint for specific lines. The code is creating a function that returns an object with 3 properties - useComposable, addSubscribers, and delSubscribers. The useComposable function is used to create a composable function, while the other two properties are used to add and delete subscribers from the composable. The code also uses tryOnScopeDispose to ensure that any changes to the composable are properly disposed of when there are no more subscribers. The only potential bug risk I can see is if the subscribers count is not updated correctly, which could result in the scope being stopped prematurely. To avoid this, it would be a good idea to use a more reliable method of tracking the number of subscribers, such as an array. Additionally, it might be helpful to add some additional logging to make sure that the subscribers count is accurate. |
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the code review:
The code patch looks good and there do not seem to be any bugs or risks. It looks like the author is trying to create a shared composable for the useFocusMonitor() function. The new syntax used for export is the latest standard and allows for better readability. Overall, it looks like a solid patch.