fusee-framework 1.5.3 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -13
- package/app/benchmark/benchmark.js +633 -0
- package/app/benchmark/index.html +102 -0
- package/app/benchmark/styles.css +249 -0
- package/app/components/Counter.js +17 -7
- package/app/components/Counter.ts +1 -1
- package/app/components/CounterSection.js +3 -4
- package/app/main.js +29 -62
- package/app/main.ts +72 -63
- package/app/pages/404.js +16 -0
- package/app/pages/[...all].js +35 -0
- package/app/pages/[...all].ts +35 -0
- package/app/pages/_layout.js +26 -0
- package/app/pages/_layout.ts +26 -0
- package/app/pages/about.js +23 -0
- package/app/pages/about.ts +29 -0
- package/app/pages/composables.js +158 -0
- package/app/pages/composables.ts +158 -0
- package/app/pages/dynamic.js +40 -0
- package/app/pages/dynamic.ts +40 -0
- package/app/pages/index.js +117 -0
- package/app/pages/index.ts +78 -0
- package/app/pages/login.ts +21 -0
- package/app/pages/objects/[id].js +56 -0
- package/app/pages/objects/[id].ts +56 -0
- package/app/pages/posts/[category]/[slug].js +56 -0
- package/app/pages/posts/[category]/[slug].ts +56 -0
- package/app/pages/router-example.js +56 -0
- package/app/pages/router-example.ts +56 -0
- package/app/pages/test-for.js +65 -0
- package/app/pages/test-for.ts +80 -0
- package/app/pages/users/[id].js +24 -0
- package/app/pages/users/[id].ts +46 -0
- package/app/pages/users/index.js +22 -0
- package/app/pages/users/index.ts +29 -0
- package/app/pages/users.js +43 -0
- package/app/pages/users.ts +78 -0
- package/app/routes/About.js +1 -1
- package/app/routes/About.ts +1 -1
- package/app/routes/AuthRoutes.ts +41 -0
- package/app/routes/Home.js +9 -0
- package/app/routes/NotFound.js +16 -0
- package/app/routes/NotFound.ts +16 -0
- package/app/routes/RouterExample.js +56 -0
- package/app/routes/RouterExample.ts +56 -0
- package/app/routes/WildcardDemo.js +35 -0
- package/app/routes/WildcardDemo.ts +35 -0
- package/auto-imports.d.ts +1 -0
- package/bin/create-fusee-linux +0 -0
- package/bin/create-fusee-mac-arm64 +0 -0
- package/bin/create-fusee-mac-intel +0 -0
- package/bin/create-fusee-win.exe +0 -0
- package/bin/create-fusee.exe +0 -0
- package/bin/index.js +38 -0
- package/create-fusee-go/cmd/generate.go +72 -0
- package/create-fusee-go/cmd/init.go +38 -0
- package/create-fusee-go/cmd/root.go +121 -0
- package/create-fusee-go/go.mod +10 -0
- package/create-fusee-go/go.sum +10 -0
- package/create-fusee-go/internal/assets/assets.go +78 -0
- package/create-fusee-go/internal/assets/embed/framework/auto-import-preset.js +9 -0
- package/create-fusee-go/internal/assets/embed/framework/core/compiler.js +253 -0
- package/create-fusee-go/internal/assets/embed/framework/core/component.js +266 -0
- package/create-fusee-go/internal/assets/embed/framework/core/composable.js +27 -0
- package/create-fusee-go/internal/assets/embed/framework/core/directives.js +875 -0
- package/create-fusee-go/internal/assets/embed/framework/core/evaluator.js +153 -0
- package/create-fusee-go/internal/assets/embed/framework/core/event-delegation.js +191 -0
- package/create-fusee-go/internal/assets/embed/framework/core/signal.js +412 -0
- package/create-fusee-go/internal/assets/embed/framework/core/store.js +81 -0
- package/create-fusee-go/internal/assets/embed/framework/index.d.ts +3 -0
- package/create-fusee-go/internal/assets/embed/framework/index.js +10 -0
- package/create-fusee-go/internal/assets/embed/framework/router/file-router.js +177 -0
- package/create-fusee-go/internal/assets/embed/framework/router/router.js +462 -0
- package/create-fusee-go/internal/assets/embed/framework/types/compiler.d.ts +15 -0
- package/create-fusee-go/internal/assets/embed/framework/types/component.d.ts +88 -0
- package/create-fusee-go/internal/assets/embed/framework/types/composable.d.ts +14 -0
- package/create-fusee-go/internal/assets/embed/framework/types/directives.d.ts +55 -0
- package/create-fusee-go/internal/assets/embed/framework/types/evaluator.d.ts +13 -0
- package/create-fusee-go/internal/assets/embed/framework/types/event-delegation.d.ts +32 -0
- package/create-fusee-go/internal/assets/embed/framework/types/index.d.ts +22 -0
- package/create-fusee-go/internal/assets/embed/framework/types/router.d.ts +32 -0
- package/create-fusee-go/internal/assets/embed/framework/types/signal.d.ts +79 -0
- package/create-fusee-go/internal/assets/embed/framework/types/store.d.ts +8 -0
- package/create-fusee-go/internal/assets/templates/Counter.tmpl +26 -0
- package/create-fusee-go/internal/assets/templates/component.tmpl +11 -0
- package/create-fusee-go/internal/assets/templates/components/Loading.tmpl +24 -0
- package/create-fusee-go/internal/assets/templates/index.html.tmpl +15 -0
- package/create-fusee-go/internal/assets/templates/main.tmpl +14 -0
- package/create-fusee-go/internal/assets/templates/package.json.tmpl +14 -0
- package/create-fusee-go/internal/assets/templates/page.tmpl +12 -0
- package/create-fusee-go/internal/assets/templates/pages/about.tmpl +20 -0
- package/create-fusee-go/internal/assets/templates/pages/index.tmpl +22 -0
- package/create-fusee-go/internal/assets/templates/pages/layout.tmpl +18 -0
- package/create-fusee-go/internal/assets/templates/tsconfig.json.tmpl +14 -0
- package/create-fusee-go/internal/assets/templates/vite.config.js.tmpl +18 -0
- package/create-fusee-go/main.go +7 -0
- package/framework/auto-import-preset.js +1 -1
- package/framework/core/compiler.js +252 -249
- package/framework/core/component.js +265 -260
- package/framework/core/directives.js +875 -632
- package/framework/core/evaluator.js +153 -70
- package/framework/core/event-delegation.js +191 -0
- package/framework/core/signal.js +412 -404
- package/framework/index.js +10 -11
- package/framework/router/file-router.js +177 -0
- package/framework/router/router.js +462 -80
- package/framework/types/component.d.ts +0 -4
- package/framework/types/event-delegation.d.ts +32 -0
- package/framework/types/index.d.ts +3 -0
- package/framework/types/router.d.ts +32 -15
- package/framework/types/signal.d.ts +1 -0
- package/index.html +638 -563
- package/package.json +5 -3
- package/tsconfig.json +1 -0
- /package/{framework → create-fusee-go/internal/assets/embed/framework}/bin/create-fusee.js +0 -0
|
@@ -1,70 +1,153 @@
|
|
|
1
|
-
export const MUSTACHE_RE = /\{\{\s*(.+?)\s*\}\}/
|
|
2
|
-
|
|
3
|
-
const SENSITIVE_ATTRS = ['href', 'src', 'srcset', 'formaction', 'xlink:href', 'data']
|
|
4
|
-
const DANGEROUS_SCHEMES = /^(javascript|data|vbscript|file):/i
|
|
5
|
-
|
|
6
|
-
export function evaluateExpression(expr, context, extraContext = {}, unwrapSignals = true) {
|
|
7
|
-
const keys = []
|
|
8
|
-
const values = []
|
|
9
|
-
|
|
10
|
-
const exprWithoutStrings = expr.replace(/'[^']*'|"[^"]*"/g, ' ')
|
|
11
|
-
const identifiers = new Set(exprWithoutStrings.match(/[a-zA-Z_$][a-zA-Z0-9_$]*/g) || [])
|
|
12
|
-
|
|
13
|
-
for (const k in context) {
|
|
14
|
-
if (identifiers.has(k)) {
|
|
15
|
-
keys.push(k)
|
|
16
|
-
const val = context[k]
|
|
17
|
-
values.push(
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
for (const k in extraContext) {
|
|
22
|
-
if (!keys.includes(k)) {
|
|
23
|
-
keys.push(k)
|
|
24
|
-
values.push(extraContext[k])
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const isMultiStatement = expr.includes(';') || expr.includes('console.')
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
1
|
+
export const MUSTACHE_RE = /\{\{\s*(.+?)\s*\}\}/
|
|
2
|
+
|
|
3
|
+
const SENSITIVE_ATTRS = ['href', 'src', 'srcset', 'formaction', 'xlink:href', 'data']
|
|
4
|
+
const DANGEROUS_SCHEMES = /^(javascript|data|vbscript|file):/i
|
|
5
|
+
|
|
6
|
+
export function evaluateExpression(expr, context, extraContext = {}, unwrapSignals = true) {
|
|
7
|
+
const keys = []
|
|
8
|
+
const values = []
|
|
9
|
+
|
|
10
|
+
const exprWithoutStrings = expr.replace(/'[^']*'|"[^"]*"/g, ' ')
|
|
11
|
+
const identifiers = new Set(exprWithoutStrings.match(/[a-zA-Z_$][a-zA-Z0-9_$]*/g) || [])
|
|
12
|
+
|
|
13
|
+
for (const k in context) {
|
|
14
|
+
if (identifiers.has(k)) {
|
|
15
|
+
keys.push(k)
|
|
16
|
+
const val = context[k]
|
|
17
|
+
values.push(val)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (const k in extraContext) {
|
|
22
|
+
if (!keys.includes(k)) {
|
|
23
|
+
keys.push(k)
|
|
24
|
+
values.push(extraContext[k])
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const isMultiStatement = expr.includes(';') || expr.includes('console.')
|
|
30
|
+
let body
|
|
31
|
+
if (isMultiStatement) {
|
|
32
|
+
body = expr
|
|
33
|
+
} else {
|
|
34
|
+
const keysToUnwrap = unwrapSignals ? keys : []
|
|
35
|
+
const unwrapStatements = keysToUnwrap.map(id =>
|
|
36
|
+
`const __${id} = typeof ${id} === 'function' && ${id}.isSignal ? ${id}() : ${id};`
|
|
37
|
+
).join('\n')
|
|
38
|
+
let wrappedExpr = expr
|
|
39
|
+
for (const id of keysToUnwrap) {
|
|
40
|
+
wrappedExpr = wrappedExpr.replace(new RegExp('\\b' + id + '\\b', 'g'), '__' + id)
|
|
41
|
+
}
|
|
42
|
+
body = (unwrapStatements ? unwrapStatements + '\n' : '') + `return ${wrappedExpr}`
|
|
43
|
+
}
|
|
44
|
+
const fn = new Function(...keys, body)
|
|
45
|
+
return fn(...values)
|
|
46
|
+
} catch (e) {
|
|
47
|
+
console.warn(`[framework] Error evaluating "${expr}":`, e)
|
|
48
|
+
return ''
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function parseInterpolation(str) {
|
|
53
|
+
const parts = []
|
|
54
|
+
let i = 0
|
|
55
|
+
let lastIndex = 0
|
|
56
|
+
|
|
57
|
+
while (i < str.length) {
|
|
58
|
+
if (str[i] === '{' && str[i+1] === '{') {
|
|
59
|
+
if (i > 0 && str[i-1] === '\\') {
|
|
60
|
+
if (i - 1 > lastIndex) {
|
|
61
|
+
parts.push({ type: 'static', value: str.slice(lastIndex, i - 1) })
|
|
62
|
+
}
|
|
63
|
+
parts.push({ type: 'static', value: '{{' })
|
|
64
|
+
i += 2
|
|
65
|
+
lastIndex = i
|
|
66
|
+
continue
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (i > lastIndex) {
|
|
70
|
+
parts.push({ type: 'static', value: str.slice(lastIndex, i) })
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let start = i + 2
|
|
74
|
+
let j = start
|
|
75
|
+
let braceLevel = 0
|
|
76
|
+
let inString = false
|
|
77
|
+
let stringChar = null
|
|
78
|
+
|
|
79
|
+
while (j < str.length) {
|
|
80
|
+
const char = str[j]
|
|
81
|
+
|
|
82
|
+
if (inString) {
|
|
83
|
+
if (char === '\\') {
|
|
84
|
+
j += 2
|
|
85
|
+
continue
|
|
86
|
+
}
|
|
87
|
+
if (char === stringChar) {
|
|
88
|
+
inString = false
|
|
89
|
+
}
|
|
90
|
+
j++
|
|
91
|
+
continue
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (char === "'" || char === '"' || char === '`') {
|
|
95
|
+
inString = true
|
|
96
|
+
stringChar = char
|
|
97
|
+
j++
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (char === '{') {
|
|
102
|
+
braceLevel++
|
|
103
|
+
j++
|
|
104
|
+
continue
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (char === '}') {
|
|
108
|
+
if (braceLevel > 0) {
|
|
109
|
+
braceLevel--
|
|
110
|
+
j++
|
|
111
|
+
continue
|
|
112
|
+
} else if (j + 1 < str.length && str[j+1] === '}') {
|
|
113
|
+
const key = str.slice(start, j).trim()
|
|
114
|
+
parts.push({ type: 'dynamic', key })
|
|
115
|
+
i = j + 2
|
|
116
|
+
lastIndex = i
|
|
117
|
+
break
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
j++
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (j >= str.length) {
|
|
125
|
+
parts.push({ type: 'static', value: '{{' })
|
|
126
|
+
i += 2
|
|
127
|
+
lastIndex = i
|
|
128
|
+
continue
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
} else {
|
|
132
|
+
i++
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (lastIndex < str.length) {
|
|
137
|
+
parts.push({ type: 'static', value: str.slice(lastIndex) })
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return parts
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function sanitizeAttr(name, value) {
|
|
144
|
+
const attrName = name.toLowerCase()
|
|
145
|
+
if (SENSITIVE_ATTRS.includes(attrName)) {
|
|
146
|
+
const trimmed = value.trim()
|
|
147
|
+
if (DANGEROUS_SCHEMES.test(trimmed)) {
|
|
148
|
+
console.warn(`[framework] Blocked potential XSS on ${name}: "${value}"`)
|
|
149
|
+
return 'about:blank'
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return value
|
|
153
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { batch } from './signal.js'
|
|
2
|
+
import { evaluateExpression } from './evaluator.js'
|
|
3
|
+
|
|
4
|
+
export const DELEGATED_EVENTS = new Set([
|
|
5
|
+
'beforeinput',
|
|
6
|
+
'click',
|
|
7
|
+
'dblclick',
|
|
8
|
+
'contextmenu',
|
|
9
|
+
'focusin',
|
|
10
|
+
'focusout',
|
|
11
|
+
'input',
|
|
12
|
+
'keydown',
|
|
13
|
+
'keyup',
|
|
14
|
+
'mousedown',
|
|
15
|
+
'mousemove',
|
|
16
|
+
'mouseout',
|
|
17
|
+
'mouseover',
|
|
18
|
+
'mouseup',
|
|
19
|
+
'pointerdown',
|
|
20
|
+
'pointermove',
|
|
21
|
+
'pointerout',
|
|
22
|
+
'pointerover',
|
|
23
|
+
'pointerup',
|
|
24
|
+
'touchend',
|
|
25
|
+
'touchmove',
|
|
26
|
+
'touchstart'
|
|
27
|
+
])
|
|
28
|
+
|
|
29
|
+
const delegatedListeners = new Map()
|
|
30
|
+
const documentListeners = new Map()
|
|
31
|
+
|
|
32
|
+
export function isDelegatedEvent(eventName) {
|
|
33
|
+
return DELEGATED_EVENTS.has(eventName.toLowerCase())
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function ensureDocumentListener(eventType) {
|
|
37
|
+
if (documentListeners.has(eventType)) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const handler = (e) => {
|
|
42
|
+
const listeners = delegatedListeners.get(eventType)
|
|
43
|
+
if (!listeners || listeners.size === 0) return
|
|
44
|
+
|
|
45
|
+
let target = e.target
|
|
46
|
+
while (target && target !== document.body && target !== document.documentElement) {
|
|
47
|
+
for (const entry of listeners) {
|
|
48
|
+
if (entry.element === target) {
|
|
49
|
+
entry.handler(e)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
target = target.parentNode
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
document.addEventListener(eventType, handler, true)
|
|
57
|
+
documentListeners.set(eventType, handler)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function registerDelegatedEvent(element, eventType, handler, options = {}) {
|
|
61
|
+
const { modifiers = [], context, expr, handlerState } = options
|
|
62
|
+
const normalizedEvent = eventType.toLowerCase()
|
|
63
|
+
|
|
64
|
+
ensureDocumentListener(normalizedEvent)
|
|
65
|
+
|
|
66
|
+
if (!delegatedListeners.has(normalizedEvent))
|
|
67
|
+
delegatedListeners.set(normalizedEvent, new Set())
|
|
68
|
+
|
|
69
|
+
const entry = {
|
|
70
|
+
element,
|
|
71
|
+
handler,
|
|
72
|
+
modifiers,
|
|
73
|
+
context,
|
|
74
|
+
expr,
|
|
75
|
+
cleanup: null,
|
|
76
|
+
handlerState: handlerState || { timeoutId: null, throttleTimeoutId: null, lastRun: 0 }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
delegatedListeners.get(normalizedEvent).add(entry)
|
|
80
|
+
|
|
81
|
+
return function cleanup() {
|
|
82
|
+
const state = entry.handlerState
|
|
83
|
+
if (state.timeoutId) {
|
|
84
|
+
clearTimeout(state.timeoutId)
|
|
85
|
+
state.timeoutId = null
|
|
86
|
+
}
|
|
87
|
+
if (state.throttleTimeoutId) {
|
|
88
|
+
clearTimeout(state.throttleTimeoutId)
|
|
89
|
+
state.throttleTimeoutId = null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const listeners = delegatedListeners.get(normalizedEvent)
|
|
93
|
+
if (listeners) {
|
|
94
|
+
listeners.delete(entry)
|
|
95
|
+
if (listeners.size === 0) {
|
|
96
|
+
const docHandler = documentListeners.get(normalizedEvent)
|
|
97
|
+
if (docHandler) {
|
|
98
|
+
document.removeEventListener(normalizedEvent, docHandler, true)
|
|
99
|
+
documentListeners.delete(normalizedEvent)
|
|
100
|
+
}
|
|
101
|
+
delegatedListeners.delete(normalizedEvent)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function createEventHandler(handler, modifiers, context, expr, state = null) {
|
|
108
|
+
const timeoutId = { value: null }
|
|
109
|
+
const throttleTimeoutId = { value: null }
|
|
110
|
+
const lastRun = { value: 0 }
|
|
111
|
+
|
|
112
|
+
let debounceMs = 0
|
|
113
|
+
let throttleMs = 0
|
|
114
|
+
|
|
115
|
+
const parseDuration = (idx) => {
|
|
116
|
+
const next = modifiers[idx + 1]
|
|
117
|
+
if (next && /^\d/.test(next)) {
|
|
118
|
+
if (next.endsWith('ms')) return parseInt(next) || 250
|
|
119
|
+
if (next.endsWith('s')) return (parseFloat(next) || 0.25) * 1000
|
|
120
|
+
}
|
|
121
|
+
return 250
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const debounceIdx = modifiers.indexOf('debounce')
|
|
125
|
+
if (debounceIdx > -1) debounceMs = parseDuration(debounceIdx)
|
|
126
|
+
|
|
127
|
+
const throttleIdx = modifiers.indexOf('throttle')
|
|
128
|
+
if (throttleIdx > -1) throttleMs = parseDuration(throttleIdx)
|
|
129
|
+
|
|
130
|
+
const executeLogic = (e) => {
|
|
131
|
+
batch(() => {
|
|
132
|
+
if (typeof handler === 'function') {
|
|
133
|
+
handler(e)
|
|
134
|
+
} else {
|
|
135
|
+
evaluateExpression(expr, context, { $event: e }, false)
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return (e) => {
|
|
141
|
+
if (modifiers.includes('prevent')) e.preventDefault()
|
|
142
|
+
if (modifiers.includes('stop')) e.stopPropagation()
|
|
143
|
+
if (modifiers.includes('self') && e.target !== e.currentTarget) return
|
|
144
|
+
|
|
145
|
+
if (e instanceof KeyboardEvent) {
|
|
146
|
+
const key = e.key.toLowerCase()
|
|
147
|
+
const keyModifiers = modifiers.filter(m => ['enter', 'escape', 'tab', 'space', 'arrowup', 'arrowdown', 'arrowleft', 'arrowright'].includes(m))
|
|
148
|
+
if (keyModifiers.length > 0) {
|
|
149
|
+
const match = keyModifiers.some(m => {
|
|
150
|
+
if (m === 'escape') return key === 'escape' || key === 'esc'
|
|
151
|
+
if (m === 'space') return key === ' ' || key === 'spacebar'
|
|
152
|
+
return key === m
|
|
153
|
+
})
|
|
154
|
+
if (!match) return
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (throttleMs > 0) {
|
|
159
|
+
const now = Date.now()
|
|
160
|
+
const remaining = throttleMs - (now - lastRun.value)
|
|
161
|
+
|
|
162
|
+
if (remaining <= 0) {
|
|
163
|
+
if (state && state.throttleTimeoutId) clearTimeout(state.throttleTimeoutId)
|
|
164
|
+
else clearTimeout(throttleTimeoutId.value)
|
|
165
|
+
lastRun.value = now
|
|
166
|
+
executeLogic(e)
|
|
167
|
+
} else {
|
|
168
|
+
if (state && state.throttleTimeoutId) clearTimeout(state.throttleTimeoutId)
|
|
169
|
+
else clearTimeout(throttleTimeoutId.value)
|
|
170
|
+
const newTimeoutId = setTimeout(() => {
|
|
171
|
+
lastRun.value = Date.now()
|
|
172
|
+
executeLogic(e)
|
|
173
|
+
}, remaining)
|
|
174
|
+
if (state) state.throttleTimeoutId = newTimeoutId
|
|
175
|
+
else throttleTimeoutId.value = newTimeoutId
|
|
176
|
+
}
|
|
177
|
+
if (state) state.lastRun = lastRun.value
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (debounceMs > 0) {
|
|
182
|
+
if (state && state.timeoutId) clearTimeout(state.timeoutId)
|
|
183
|
+
else clearTimeout(timeoutId.value)
|
|
184
|
+
const newTimeoutId = setTimeout(() => executeLogic(e), debounceMs)
|
|
185
|
+
if (state) state.timeoutId = newTimeoutId
|
|
186
|
+
else timeoutId.value = newTimeoutId
|
|
187
|
+
} else {
|
|
188
|
+
executeLogic(e)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|