Skip to content

feat(common): use the hotspot function provided by the ArkWeb JS engine to optimize the execution of defineProperties function in the common adaptation layer #3530

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

Merged
merged 1 commit into from
Jun 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions packages/vue-common/src/__longque__.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
interface ILongque {
/**
* Harmony API version.
*
* @since 1
*/
version: number

/**
* Create a delegate object for `underlyingObject` or make the `initObject` a delegate for `underlyingObject`.
*
* @param underlyingObject The underlying object to be delegated.
* @param initObject Optional initial delegate object.
* @param propertyFilterFlags Optional property filter flags, must use predefined filter flags.
* @return If no error throwed, returns the new created delegate object or the `initObject`.
*
* @since 1
*/
createDelegate: (underlyingObject: object, initObject?: object, propertyFilterFlags?: number) => object

/**
* The filter flag for `createDelegate`, skip all properties in prototype chain of `underlyingObject`.
*
* @since 1
*/
SKIP_PROTOTYPE_CHAIN: 1

/**
* The filter flag for `createDelegate`, skip all properties that starts with '_'.
*
* @since 1
*/
SKIP_PREFIX_UNDERSCORE: 2

/**
* The filter flag for `createDelegate`, skip all properties that starts with '$'.
*
* @since 1
*/
SKIP_PREFIX_DOLLAR: 4

/**
* The filter flag for `createDelegate`, skip the 'constructor' property.
*
* @since 1
*/
SKIP_CONSTRUCTOR: 8
}

interface Window {
__Longque__: ILongque
}
Comment on lines +50 to +52
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Make __Longque__ optional to match runtime reality

__Longque__ is not guaranteed to exist – your own runtime guard (typeof window === 'undefined' ? null : window.__Longque__) proves that.
Marking the property as mandatory will break type-checking when strictNullChecks is on, or when the file is imported in non-ArkWeb environments.

-interface Window {
-  __Longque__: ILongque
-}
+interface Window {
+  /** Present only when running inside ArkWeb JS engine */
+  __Longque__?: ILongque
+}
📝 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
interface Window {
__Longque__: ILongque
}
interface Window {
/** Present only when running inside ArkWeb JS engine */
__Longque__?: ILongque
}
🤖 Prompt for AI Agents
In packages/vue-common/src/__longque__.d.ts around lines 50 to 52, the Window
interface declares __Longque__ as a mandatory property, but it is not guaranteed
to exist at runtime. To fix this, make the __Longque__ property optional by
adding a question mark after its name in the interface declaration. This change
will align the type definition with the runtime reality and prevent
type-checking errors when strictNullChecks is enabled or in environments where
__Longque__ is absent.

4 changes: 4 additions & 0 deletions packages/vue-common/src/adapter/__longque__.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// 龙雀: ArkWeb JS引擎名称
const __TINY__ = typeof window === 'undefined' ? null : window.__Longque__

export { __TINY__ }
12 changes: 10 additions & 2 deletions packages/vue-common/src/adapter/vue2.7/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Vue from 'vue'
import * as hooks from 'vue'
import { emitter, bindFilter, getElementCssClass, getElementStatusClass } from '../utils'
import teleport from '../teleport'
import { __TINY__ } from '../__longque__'

const Teleport = teleport(hooks)

Expand Down Expand Up @@ -183,8 +184,8 @@ const generateChildren = ($children) => {
return children
}

const defineProperties = (vm, instance, filter) => {
for (let name in instance) {
const originalDefineProperties = (vm, instance, filter) => {
for (const name in instance) {
if (typeof filter === 'function' && filter(name)) continue

Object.defineProperty(vm, name, {
Expand All @@ -198,6 +199,13 @@ const defineProperties = (vm, instance, filter) => {
return vm
}

const harmonyDefineProperties = (vm, instance) => {
const propertyFilterFlags = __TINY__.SKIP_PREFIX_UNDERSCORE | __TINY__.SKIP_PREFIX_DOLLAR | __TINY__.SKIP_CONSTRUCTOR
__TINY__.createDelegate(instance, vm, propertyFilterFlags)
}

const defineProperties = __TINY__ ? harmonyDefineProperties : originalDefineProperties

const filter = (name) => name.indexOf('$') === 0 || name.indexOf('_') === 0 || name === 'constructor'

const createVm = (vm, instance, context = undefined) => {
Expand Down
10 changes: 9 additions & 1 deletion packages/vue-common/src/adapter/vue2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as compositionHooks from '@vue/composition-api'
import * as vueHooks from 'vue'
import { bindFilter, emitter, getElementCssClass, getElementStatusClass } from '../utils'
import teleport from '../teleport'
import { __TINY__ } from '../__longque__'

// vue2.7有version字段
const isVueHooks = Boolean(Vue.version?.includes('2.7'))
Expand Down Expand Up @@ -179,7 +180,7 @@ const generateChildren = ($children) => {
return children
}

const defineProperties = (vm, instance, filter) => {
const originalDefineProperties = (vm, instance, filter) => {
for (const name in instance) {
if (typeof filter === 'function' && filter(name)) continue

Expand All @@ -194,6 +195,13 @@ const defineProperties = (vm, instance, filter) => {
return vm
}

const harmonyDefineProperties = (vm, instance) => {
const propertyFilterFlags = __TINY__.SKIP_PREFIX_UNDERSCORE | __TINY__.SKIP_PREFIX_DOLLAR | __TINY__.SKIP_CONSTRUCTOR
__TINY__.createDelegate(instance, vm, propertyFilterFlags)
}
Comment on lines +198 to +201
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for the delegate creation.

The harmonyDefineProperties function calls __TINY__.createDelegate without error handling. Consider adding try-catch to gracefully fall back to the original implementation if delegation fails.

 const harmonyDefineProperties = (vm, instance) => {
   const propertyFilterFlags = __TINY__.SKIP_PREFIX_UNDERSCORE | __TINY__.SKIP_PREFIX_DOLLAR | __TINY__.SKIP_CONSTRUCTOR
-  __TINY__.createDelegate(instance, vm, propertyFilterFlags)
+  try {
+    __TINY__.createDelegate(instance, vm, propertyFilterFlags)
+  } catch (error) {
+    console.warn('Failed to create delegate, falling back to original implementation:', error)
+    return originalDefineProperties(vm, instance, filter)
+  }
+  return vm
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/vue-common/src/adapter/vue2/index.ts around lines 198 to 201, the
harmonyDefineProperties function calls __TINY__.createDelegate without error
handling. Wrap the call to __TINY__.createDelegate in a try-catch block, and in
the catch block, implement a fallback to the original property definition method
to ensure graceful degradation if delegation fails.


const defineProperties = __TINY__ ? harmonyDefineProperties : originalDefineProperties
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider runtime validation of TINY capabilities.

The conditional assignment only checks for the existence of __TINY__ but doesn't validate if it has the required methods. Consider checking for __TINY__.createDelegate specifically.

-const defineProperties = __TINY__ ? harmonyDefineProperties : originalDefineProperties
+const defineProperties = (__TINY__ && typeof __TINY__.createDelegate === 'function') ? harmonyDefineProperties : originalDefineProperties
📝 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 defineProperties = __TINY__ ? harmonyDefineProperties : originalDefineProperties
-const defineProperties = __TINY__ ? harmonyDefineProperties : originalDefineProperties
+const defineProperties = (__TINY__ && typeof __TINY__.createDelegate === 'function')
+ ? harmonyDefineProperties
+ : originalDefineProperties
🤖 Prompt for AI Agents
In packages/vue-common/src/adapter/vue2/index.ts at line 203, the assignment to
defineProperties only checks if __TINY__ exists but does not verify if it has
the necessary method createDelegate. Update the condition to check that __TINY__
is truthy and that __TINY__.createDelegate is a function before assigning
harmonyDefineProperties; otherwise, fallback to originalDefineProperties.


const filter = (name) => name.indexOf('$') === 0 || name.indexOf('_') === 0 || name === 'constructor'

const createVm = (vm, instance, context = undefined) => {
Expand Down
14 changes: 11 additions & 3 deletions packages/vue-common/src/adapter/vue3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as hooks from 'vue'

import { camelize, capitalize, hyphenate } from '@opentiny/utils'
import { bindFilter, emitter, getElementCssClass, getElementStatusClass } from '../utils'
import { __TINY__ } from '../__longque__'

const Teleport = hooks.Teleport

Expand Down Expand Up @@ -233,7 +234,7 @@ const generateChildren = (subTree) => {
return children
}

const defineProperties = (vm, instance, property, filter) => {
const originalDefineProperties = (vm, instance, property, filter) => {
for (const name in instance[property]) {
if (typeof filter === 'function' && filter(name)) continue

Expand All @@ -248,11 +249,18 @@ const defineProperties = (vm, instance, property, filter) => {
return vm
}

const harmonyDefineProperties = (vm, instance, property) => {
const propertyFilterFlags = __TINY__.SKIP_PREFIX_UNDERSCORE
__TINY__.createDelegate(instance[property], vm, propertyFilterFlags)
}

const defineProperties = __TINY__ ? harmonyDefineProperties : originalDefineProperties

const filter = (name) => name.indexOf('_') === 0

const defineInstanceVm = (vm, instance) => {
defineProperties(vm, instance, 'setupState', null)
defineProperties(vm, instance, 'props', filter)
originalDefineProperties(vm, instance, 'setupState', null)
originalDefineProperties(vm, instance, 'props', filter)
defineProperties(vm, instance, 'ctx', filter)

return vm
Expand Down
49 changes: 13 additions & 36 deletions tsconfig.vue2.7.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,16 @@
"noImplicitAny": false,
"baseUrl": ".",
"paths": {
"@opentiny/vue-huicharts-amap": [
"packages/vue/src/chart/autonavi-map"
],
"@opentiny/vue-huicharts-bmap": [
"packages/vue/src/chart/baidu-map"
],
"@opentiny/vue-huicharts-*": [
"packages/vue/src/chart/chart-*"
],
"@opentiny/vue-*": [
"packages/vue-*",
"packages/vue/src/*"
],
"@opentiny/vue-renderless/types*": [
"packages/renderless/types*"
],
"@opentiny/vue-renderless*": [
"packages/renderless/src*"
],
"virtual:common/adapter/vue": [
"packages/vue-common/src/adapter/vue2.7/index.ts"
],
"virtual:locale/vue": [
"packages/vue-locale/src/vue2.7/index.ts"
]
"@opentiny/vue-huicharts-amap": ["packages/vue/src/chart/autonavi-map"],
"@opentiny/vue-huicharts-bmap": ["packages/vue/src/chart/baidu-map"],
"@opentiny/vue-huicharts-*": ["packages/vue/src/chart/chart-*"],
"@opentiny/vue-*": ["packages/vue-*", "packages/vue/src/*"],
"@opentiny/vue-renderless/types*": ["packages/renderless/types*"],
"@opentiny/vue-renderless*": ["packages/renderless/src*"],
"virtual:common/adapter/vue": ["packages/vue-common/src/adapter/vue2.7/index.ts"],
"virtual:locale/vue": ["packages/vue-locale/src/vue2.7/index.ts"]
},
"types": [
"node",
"vite/client"
]
"types": ["node", "vite/client"]
},
"vueCompilerOptions": {
"target": 2.7
Expand All @@ -44,11 +24,8 @@
"packages/**/*.tsx",
"packages/**/*.vue",
"examples/vue2.7/shims-app.d.ts",
"examples/vue2.7/shims-vue.d.ts"
"examples/vue2.7/shims-vue.d.ts",
"packages/vue-common/src/__longque__.d.ts"
],
"exclude": [
"**/node_modules",
"**/dist*",
"**/*.md"
]
}
"exclude": ["**/node_modules", "**/dist*", "**/*.md"]
}
49 changes: 13 additions & 36 deletions tsconfig.vue2.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,16 @@
"noImplicitAny": false,
"baseUrl": ".",
"paths": {
"@opentiny/vue-huicharts-amap": [
"packages/vue/src/chart/autonavi-map"
],
"@opentiny/vue-huicharts-bmap": [
"packages/vue/src/chart/baidu-map"
],
"@opentiny/vue-huicharts-*": [
"packages/vue/src/chart/chart-*"
],
"@opentiny/vue-*": [
"packages/vue-*",
"packages/vue/src/*"
],
"@opentiny/vue-renderless/types*": [
"packages/renderless/types*"
],
"@opentiny/vue-renderless*": [
"packages/renderless/src*"
],
"virtual:common/adapter/vue": [
"packages/vue-common/src/adapter/vue2/index.ts"
],
"virtual:locale/vue": [
"packages/vue-locale/src/vue2/index.ts"
]
"@opentiny/vue-huicharts-amap": ["packages/vue/src/chart/autonavi-map"],
"@opentiny/vue-huicharts-bmap": ["packages/vue/src/chart/baidu-map"],
"@opentiny/vue-huicharts-*": ["packages/vue/src/chart/chart-*"],
"@opentiny/vue-*": ["packages/vue-*", "packages/vue/src/*"],
"@opentiny/vue-renderless/types*": ["packages/renderless/types*"],
"@opentiny/vue-renderless*": ["packages/renderless/src*"],
"virtual:common/adapter/vue": ["packages/vue-common/src/adapter/vue2/index.ts"],
"virtual:locale/vue": ["packages/vue-locale/src/vue2/index.ts"]
},
"types": [
"node",
"vite/client"
]
"types": ["node", "vite/client"]
},
"vueCompilerOptions": {
"target": 2
Expand All @@ -44,11 +24,8 @@
"packages/**/*.tsx",
"packages/**/*.vue",
"examples/vue2/shims-app.d.ts",
"examples/vue2/shims-vue.d.ts"
"examples/vue2/shims-vue.d.ts",
"packages/vue-common/src/__longque__.d.ts"
],
"exclude": [
"**/node_modules",
"**/dist*",
"**/*.md"
]
}
"exclude": ["**/node_modules", "**/dist*", "**/*.md"]
}
47 changes: 12 additions & 35 deletions tsconfig.vue3.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,16 @@
"noImplicitAny": false,
"baseUrl": ".",
"paths": {
"@opentiny/vue-huicharts-amap": [
"packages/vue/src/huicharts/huicharts-amap"
],
"@opentiny/vue-huicharts-bmap": [
"packages/vue/src/huicharts/huicharts-bmap"
],
"@opentiny/vue-huicharts-*": [
"packages/vue/src/huicharts/chart-*"
],
"@opentiny/vue-*": [
"packages/vue-*",
"packages/vue/src/*"
],
"@opentiny/vue-renderless/types*": [
"packages/renderless/types*"
],
"@opentiny/vue-renderless*": [
"packages/renderless/src*"
],
"virtual:common/adapter/vue": [
"packages/vue-common/src/adapter/vue3/index.ts"
],
"virtual:locale/vue": [
"packages/vue-locale/src/vue3/index.ts"
]
"@opentiny/vue-huicharts-amap": ["packages/vue/src/huicharts/huicharts-amap"],
"@opentiny/vue-huicharts-bmap": ["packages/vue/src/huicharts/huicharts-bmap"],
"@opentiny/vue-huicharts-*": ["packages/vue/src/huicharts/chart-*"],
"@opentiny/vue-*": ["packages/vue-*", "packages/vue/src/*"],
"@opentiny/vue-renderless/types*": ["packages/renderless/types*"],
"@opentiny/vue-renderless*": ["packages/renderless/src*"],
"virtual:common/adapter/vue": ["packages/vue-common/src/adapter/vue3/index.ts"],
"virtual:locale/vue": ["packages/vue-locale/src/vue3/index.ts"]
},
"types": [
"node",
"vite/client"
]
"types": ["node", "vite/client"]
},
"vueCompilerOptions": {
"target": 3
Expand All @@ -44,11 +24,8 @@
"packages/**/*.tsx",
"packages/**/*.vue",
"examples/vue3/shims-app.d.ts",
"examples/vue3/shims-vue.d.ts"
"examples/vue3/shims-vue.d.ts",
"packages/vue-common/src/__longque__.d.ts"
],
"exclude": [
"**/node_modules",
"**/dist*",
"**/*.md"
]
"exclude": ["**/node_modules", "**/dist*", "**/*.md"]
}
Loading