@lightningjs/blits 1.47.0 → 1.49.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/CHANGELOG.md +24 -0
- package/index.d.ts +13 -10
- package/package.json +2 -2
- package/scripts/prepublishOnly.js +2 -2
- package/scripts/prepush.js +21 -1
- package/src/component.js +39 -9
- package/src/engines/L3/element.js +33 -6
- package/src/lib/codegenerator/generator.js +22 -11
- package/src/lib/lifecycle.js +2 -2
- package/src/lib/reactivity/effect.js +3 -2
- package/src/lib/reactivityguard/computedprops.js +1 -1
- package/src/router/router.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
## v1.49.0
|
|
5
|
+
|
|
6
|
+
_20 feb 2026_
|
|
7
|
+
|
|
8
|
+
- Added `data-blits-renderstate` inspector attribute
|
|
9
|
+
- Fixed `data-blits-hasfocus` inspector attribute to always be available
|
|
10
|
+
- Added boolean attribute to `idle` lifecycle hook to indicate `idle` or `active` state
|
|
11
|
+
- Fixed type definitions for
|
|
12
|
+
- Fixed double processiong of reactivity guard
|
|
13
|
+
|
|
14
|
+
## v1.48.0
|
|
15
|
+
|
|
16
|
+
_10 feb 2026_
|
|
17
|
+
|
|
18
|
+
- Improved cleanup of for-loop effects
|
|
19
|
+
- Fixed router issue with params not being reset
|
|
20
|
+
- Added next tick debouncing for transitions on multiple props
|
|
21
|
+
- Bumped renderer to 2.21.0
|
|
22
|
+
- Added support for using function-notation in `@loaded`, `@error` and `@updated` callbacks
|
|
23
|
+
- Added displaying of correct component type in inspector data when using `is`-attribute
|
|
24
|
+
- Replaced `$`-prefix for automatic inspector data with `blits-` prefix (fixes fatal error in Safari)
|
|
25
|
+
|
|
26
|
+
|
|
3
27
|
## v1.47.0
|
|
4
28
|
|
|
5
29
|
_26 jan 2026_
|
package/index.d.ts
CHANGED
|
@@ -201,11 +201,14 @@ declare module '@lightningjs/blits' {
|
|
|
201
201
|
*/
|
|
202
202
|
exit?: () => void;
|
|
203
203
|
/**
|
|
204
|
-
* Fires when the renderer is done rendering and enters an idle state
|
|
204
|
+
* Fires when the renderer is done rendering and enters an idle state (idle = true)
|
|
205
|
+
* and when the renderer starts rendering again and leaves the idle state (idle = false)
|
|
206
|
+
*
|
|
207
|
+
* @param idle - boolean to indicate whether the renderer is in idle state or not
|
|
205
208
|
*
|
|
206
209
|
* Note: This event can fire multiple times
|
|
207
210
|
*/
|
|
208
|
-
idle?: () => void;
|
|
211
|
+
idle?: (idle: boolean) => void;
|
|
209
212
|
/**
|
|
210
213
|
* Fires at a predefined interval and reports the current FPS value
|
|
211
214
|
*
|
|
@@ -666,9 +669,9 @@ declare module '@lightningjs/blits' {
|
|
|
666
669
|
|
|
667
670
|
export interface RouterHooks {
|
|
668
671
|
init?: () => Promise<void> | void;
|
|
669
|
-
beforeEach?: (to: Route, from: Route) => string | Route | Promise<string | Route
|
|
670
|
-
afterEach?: (to: Route, from: Route) => string | Route | Promise<string | Route
|
|
671
|
-
error?: (err: string) => string | Route | Promise<string | Route
|
|
672
|
+
beforeEach?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
673
|
+
afterEach?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
674
|
+
error?: (err: string) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
672
675
|
}
|
|
673
676
|
|
|
674
677
|
export interface RouterConfig<P extends Props, S, M, C> {
|
|
@@ -694,13 +697,13 @@ declare module '@lightningjs/blits' {
|
|
|
694
697
|
|
|
695
698
|
/**
|
|
696
699
|
* Enable or disable RouterView history navigation on Back input
|
|
697
|
-
*
|
|
700
|
+
*
|
|
698
701
|
* @default true
|
|
699
|
-
*
|
|
702
|
+
*
|
|
700
703
|
* @remarks
|
|
701
704
|
* This is an app-wide setting that affects all RouterView instances in your application.
|
|
702
705
|
* The router state is global and shared across all router instances.
|
|
703
|
-
*
|
|
706
|
+
*
|
|
704
707
|
* @example
|
|
705
708
|
* ```js
|
|
706
709
|
* router: {
|
|
@@ -809,8 +812,8 @@ declare module '@lightningjs/blits' {
|
|
|
809
812
|
}[keyof T]
|
|
810
813
|
|
|
811
814
|
export interface RouteHooks {
|
|
812
|
-
before?: (to: Route, from: Route) => string | Route | Promise<string | Route>;
|
|
813
|
-
after?: (to: Route, from: Route) => string | Route | Promise<string | Route>;
|
|
815
|
+
before?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
816
|
+
after?: (to: Route, from: Route) => string | Route | void | boolean | Promise<string | Route | void | boolean>;
|
|
814
817
|
}
|
|
815
818
|
|
|
816
819
|
export type Route = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.49.0",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"@lightningjs/msdf-generator": "^1.2.0",
|
|
77
|
-
"@lightningjs/renderer": "^2.
|
|
77
|
+
"@lightningjs/renderer": "^2.23.0",
|
|
78
78
|
"magic-string": "^0.30.21"
|
|
79
79
|
},
|
|
80
80
|
"repository": {
|
|
@@ -19,7 +19,7 @@ import fs from 'fs'
|
|
|
19
19
|
import path from 'path'
|
|
20
20
|
import { fileURLToPath } from 'url'
|
|
21
21
|
import compiler from '../src/lib/precompiler/precompiler.js'
|
|
22
|
-
import
|
|
22
|
+
import childProcess from 'child_process'
|
|
23
23
|
|
|
24
24
|
const currentDir = process.cwd()
|
|
25
25
|
const componentDirs = ['src/components']
|
|
@@ -71,7 +71,7 @@ function processFile(filePath) {
|
|
|
71
71
|
function formatFileWithESLint(filePath) {
|
|
72
72
|
const command = `eslint "${filePath}" --fix`
|
|
73
73
|
|
|
74
|
-
exec(command, (error, stdout, stderr) => {
|
|
74
|
+
childProcess.exec(command, (error, stdout, stderr) => {
|
|
75
75
|
if (error) {
|
|
76
76
|
console.error(`Execution Error: ${error.message}`)
|
|
77
77
|
console.error(`Exit Code: ${error.code}`)
|
package/scripts/prepush.js
CHANGED
|
@@ -69,7 +69,6 @@ try {
|
|
|
69
69
|
// Run ESLint on the changed files
|
|
70
70
|
execSync(`npx eslint ${fileList.join(' ')}`, { stdio: 'inherit' })
|
|
71
71
|
console.log('Linting passed successfully!\n')
|
|
72
|
-
process.exit(0)
|
|
73
72
|
} catch (error) {
|
|
74
73
|
console.log('\n==========================================================================')
|
|
75
74
|
console.log('ESLint found issues in your code. Please fix them before pushing.')
|
|
@@ -79,3 +78,24 @@ try {
|
|
|
79
78
|
console.log('==========================================================================\n')
|
|
80
79
|
process.exit(1)
|
|
81
80
|
}
|
|
81
|
+
|
|
82
|
+
// By default, always run tests unless RUN_TEST=skip
|
|
83
|
+
const runTestsFlag = process.env.RUN_TEST || ''
|
|
84
|
+
|
|
85
|
+
if (runTestsFlag.toLowerCase() === 'skip') {
|
|
86
|
+
console.log('Skipping tests due to RUN_TEST=skip. Proceeding with push.')
|
|
87
|
+
process.exit(0)
|
|
88
|
+
} else {
|
|
89
|
+
// For any other value (including empty or unknown), run tests
|
|
90
|
+
try {
|
|
91
|
+
console.log('Running tests...\n')
|
|
92
|
+
execSync('npm run test', { stdio: 'inherit' })
|
|
93
|
+
console.log('Tests passed successfully!\n')
|
|
94
|
+
process.exit(0)
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.log('\n==========================================================================')
|
|
97
|
+
console.log('Some tests failed. Please fix them before pushing.')
|
|
98
|
+
console.log('==========================================================================\n')
|
|
99
|
+
process.exit(1)
|
|
100
|
+
}
|
|
101
|
+
}
|
package/src/component.js
CHANGED
|
@@ -267,33 +267,60 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
267
267
|
this[symbols.slots] = this[symbols.children].filter((child) => child[symbols.isSlot])
|
|
268
268
|
|
|
269
269
|
this[symbols.rendererEventListeners] = []
|
|
270
|
+
|
|
271
|
+
if (this[symbols.holder] !== undefined && Settings.get('inspector', false)) {
|
|
272
|
+
this[symbols.holder].setInspectorMetadata({ 'blits-hasFocus': false })
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// setup inspector data for render state
|
|
276
|
+
if (name === 'App' && Settings.get('inspector', false)) {
|
|
277
|
+
this.$setTimeout(() => {
|
|
278
|
+
const wrapperEl = this[symbols.wrapper]
|
|
279
|
+
const idleCb = () => {
|
|
280
|
+
wrapperEl.setInspectorMetadata({ 'blits-renderState': 'idle' })
|
|
281
|
+
}
|
|
282
|
+
const activeCb = () => {
|
|
283
|
+
wrapperEl.setInspectorMetadata({ 'blits-renderState': 'active' })
|
|
284
|
+
}
|
|
285
|
+
renderer.on('idle', idleCb)
|
|
286
|
+
renderer.on('active', activeCb)
|
|
287
|
+
this[symbols.rendererEventListeners].push({ event: 'idle', cb: idleCb })
|
|
288
|
+
this[symbols.rendererEventListeners].push({ event: 'active', cb: activeCb })
|
|
289
|
+
})
|
|
290
|
+
}
|
|
291
|
+
|
|
270
292
|
// register hooks if component has hooks specified
|
|
271
293
|
if (config.hooks) {
|
|
272
294
|
// push to next tick to ensure
|
|
273
|
-
setTimeout(() => {
|
|
295
|
+
this.$setTimeout(() => {
|
|
274
296
|
// frame tick event
|
|
275
297
|
if (config.hooks.frameTick) {
|
|
276
|
-
const cb = (
|
|
277
|
-
this[symbols.rendererEventListeners].push({ event: 'frameTick', cb })
|
|
298
|
+
const cb = (_r, data) => emit('frameTick', this[symbols.identifier], this, [data])
|
|
278
299
|
renderer.on('frameTick', cb)
|
|
300
|
+
this[symbols.rendererEventListeners].push({ event: 'frameTick', cb })
|
|
279
301
|
}
|
|
280
302
|
|
|
281
303
|
// idle event
|
|
282
304
|
if (config.hooks.idle) {
|
|
283
|
-
const
|
|
284
|
-
emit('idle', this[symbols.identifier], this)
|
|
305
|
+
const idleCb = () => {
|
|
306
|
+
emit('idle', this[symbols.identifier], this, [true])
|
|
307
|
+
}
|
|
308
|
+
const activeCb = () => {
|
|
309
|
+
emit('idle', this[symbols.identifier], this, [false])
|
|
285
310
|
}
|
|
286
|
-
|
|
287
|
-
renderer.on('
|
|
311
|
+
renderer.on('idle', idleCb)
|
|
312
|
+
renderer.on('active', activeCb)
|
|
313
|
+
this[symbols.rendererEventListeners].push({ event: 'idle', cb: idleCb })
|
|
314
|
+
this[symbols.rendererEventListeners].push({ event: 'active', cb: activeCb })
|
|
288
315
|
}
|
|
289
316
|
|
|
290
317
|
// fpsUpdate event
|
|
291
318
|
if (config.hooks.fpsUpdate) {
|
|
292
|
-
const cb = (
|
|
319
|
+
const cb = (_r, data) => {
|
|
293
320
|
emit('fpsUpdate', this[symbols.identifier], this, [data.fps])
|
|
294
321
|
}
|
|
295
|
-
this[symbols.rendererEventListeners].push({ event: 'fpsUpdate', cb })
|
|
296
322
|
renderer.on('fpsUpdate', cb)
|
|
323
|
+
this[symbols.rendererEventListeners].push({ event: 'fpsUpdate', cb })
|
|
297
324
|
}
|
|
298
325
|
})
|
|
299
326
|
|
|
@@ -450,6 +477,9 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
450
477
|
// during the code generation step
|
|
451
478
|
factory[Symbol.for('config')] = config
|
|
452
479
|
|
|
480
|
+
// Display name for inspector
|
|
481
|
+
factory[Symbol.for('componentType')] = name
|
|
482
|
+
|
|
453
483
|
// To determine whether dynamic component is actual Blits component or not
|
|
454
484
|
factory[symbols.isComponent] = true
|
|
455
485
|
|
|
@@ -602,7 +602,7 @@ const Element = {
|
|
|
602
602
|
this.props.props['data'] = {}
|
|
603
603
|
}
|
|
604
604
|
|
|
605
|
-
// Merge framework data (
|
|
605
|
+
// Merge framework data (blits-* keys data attributes)
|
|
606
606
|
Object.assign(this.props['data'], data)
|
|
607
607
|
Object.assign(this.props.props['data'], data)
|
|
608
608
|
|
|
@@ -656,13 +656,31 @@ const Element = {
|
|
|
656
656
|
}
|
|
657
657
|
},
|
|
658
658
|
animate(prop, value, transition) {
|
|
659
|
+
// Clear any existing debounce timeout for this property
|
|
660
|
+
if (this.debounceTimeouts[prop] !== undefined) {
|
|
661
|
+
clearTimeout(this.debounceTimeouts[prop])
|
|
662
|
+
Log.debug(`Cleared debounce timeout for property "${prop}"`)
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
// Debounce the animation execution
|
|
666
|
+
this.debounceTimeouts[prop] = setTimeout(() => {
|
|
667
|
+
delete this.debounceTimeouts[prop]
|
|
668
|
+
this._executeAnimation(prop, value, transition)
|
|
669
|
+
}, 0)
|
|
670
|
+
},
|
|
671
|
+
_executeAnimation(prop, value, transition) {
|
|
659
672
|
// check if a transition is already scheduled to run on the same prop
|
|
660
673
|
// and cancels it if it does
|
|
674
|
+
const stateOfAnimation =
|
|
675
|
+
this.scheduledTransitions[prop] !== undefined
|
|
676
|
+
? this.scheduledTransitions[prop].f.state
|
|
677
|
+
: undefined
|
|
678
|
+
|
|
661
679
|
if (
|
|
662
|
-
|
|
663
|
-
|
|
680
|
+
stateOfAnimation !== undefined &&
|
|
681
|
+
(stateOfAnimation === 'scheduled' || stateOfAnimation === 'running')
|
|
664
682
|
) {
|
|
665
|
-
this.scheduledTransitions[prop].f.stop()
|
|
683
|
+
this.scheduledTransitions[prop].f.stop(stateOfAnimation === 'running' ? false : true)
|
|
666
684
|
}
|
|
667
685
|
|
|
668
686
|
// if current value is the same as the value to animate to, instantly resolve
|
|
@@ -700,7 +718,7 @@ const Element = {
|
|
|
700
718
|
|
|
701
719
|
// Update inspector metadata when transition starts
|
|
702
720
|
if (inspectorEnabled === true) {
|
|
703
|
-
this.setInspectorMetadata({
|
|
721
|
+
this.setInspectorMetadata({ 'blits-isTransitioning': true })
|
|
704
722
|
}
|
|
705
723
|
|
|
706
724
|
if (transition.start !== undefined && typeof transition.start === 'function') {
|
|
@@ -740,7 +758,7 @@ const Element = {
|
|
|
740
758
|
// Update inspector metadata when transition ends
|
|
741
759
|
if (inspectorEnabled === true) {
|
|
742
760
|
this.setInspectorMetadata({
|
|
743
|
-
|
|
761
|
+
'blits-isTransitioning': Object.keys(this.scheduledTransitions).length > 0,
|
|
744
762
|
})
|
|
745
763
|
}
|
|
746
764
|
})
|
|
@@ -752,6 +770,14 @@ const Element = {
|
|
|
752
770
|
if (this.node === null) return
|
|
753
771
|
|
|
754
772
|
Log.debug('Deleting Node', this.nodeId)
|
|
773
|
+
|
|
774
|
+
// Clear all pending debounce timeouts
|
|
775
|
+
const debounceProps = Object.keys(this.debounceTimeouts)
|
|
776
|
+
for (let i = 0; i < debounceProps.length; i++) {
|
|
777
|
+
clearTimeout(this.debounceTimeouts[debounceProps[i]])
|
|
778
|
+
}
|
|
779
|
+
this.debounceTimeouts = null
|
|
780
|
+
|
|
755
781
|
// Clearing transition end callback functions
|
|
756
782
|
const transitionProps = Object.keys(this.scheduledTransitions)
|
|
757
783
|
for (let i = 0; i < transitionProps.length; i++) {
|
|
@@ -834,6 +860,7 @@ export default (config, component) => {
|
|
|
834
860
|
return Object.assign(Object.create(Element), {
|
|
835
861
|
props: Object.assign(Object.create(propsTransformer), { props: {} }),
|
|
836
862
|
scheduledTransitions: {},
|
|
863
|
+
debounceTimeouts: {},
|
|
837
864
|
config,
|
|
838
865
|
component,
|
|
839
866
|
})
|
|
@@ -360,17 +360,17 @@ const generateComponentCode = function (
|
|
|
360
360
|
}
|
|
361
361
|
`)
|
|
362
362
|
|
|
363
|
-
// For forloops, this code runs per instance, setting metadata for each component instance
|
|
364
363
|
if (isDev === true) {
|
|
365
|
-
const
|
|
364
|
+
const templateTagName = templateObject[Symbol.for('componentType')]
|
|
366
365
|
const holderElm = options.key
|
|
367
366
|
? `elms[${holderCounter}][${options.key}]`
|
|
368
367
|
: `elms[${holderCounter}]`
|
|
368
|
+
const componentDisplayName = `typeof componentType === 'string'
|
|
369
|
+
? componentType
|
|
370
|
+
: (componentType?.[Symbol.for('componentType')] || '${templateTagName}')`
|
|
369
371
|
renderCode.push(`
|
|
370
372
|
if (${holderElm} !== undefined && typeof ${holderElm}.setInspectorMetadata === 'function') {
|
|
371
|
-
${holderElm}.setInspectorMetadata({
|
|
372
|
-
$componentType: '${componentType}'
|
|
373
|
-
})
|
|
373
|
+
${holderElm}.setInspectorMetadata({ 'blits-componentType': ${componentDisplayName} })
|
|
374
374
|
}
|
|
375
375
|
`)
|
|
376
376
|
}
|
|
@@ -503,10 +503,16 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
503
503
|
|
|
504
504
|
component !== null && component[Symbol.for('removeGlobalEffects')](effects[${forStartCounter}])
|
|
505
505
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
const
|
|
509
|
-
|
|
506
|
+
const effectsToRemove = new Set(effects[${forStartCounter}].slice(0))
|
|
507
|
+
if (effectsToRemove.size > 0) {
|
|
508
|
+
const componentEffects = component?.[Symbol.for('effects')] || []
|
|
509
|
+
let writeIndex = 0
|
|
510
|
+
for (let readIndex = 0; readIndex < componentEffects.length; readIndex++) {
|
|
511
|
+
if (!effectsToRemove.has(componentEffects[readIndex])) {
|
|
512
|
+
componentEffects[writeIndex++] = componentEffects[readIndex]
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
componentEffects.length = writeIndex
|
|
510
516
|
}
|
|
511
517
|
|
|
512
518
|
effects[${forStartCounter}].length = 0
|
|
@@ -804,8 +810,13 @@ const cast = (val = '', key = false, component = 'component.') => {
|
|
|
804
810
|
}
|
|
805
811
|
// @-listener
|
|
806
812
|
else if (key.startsWith('@') && val) {
|
|
807
|
-
const
|
|
808
|
-
|
|
813
|
+
const trimmed = val.trim()
|
|
814
|
+
if (/^\$?\w+$/.test(trimmed)) {
|
|
815
|
+
const c = component.slice(0, -1)
|
|
816
|
+
castedValue = `${c}['${trimmed.replace('$', '')}'] && ${c}['${trimmed.replace('$', '')}'].bind(${c})`
|
|
817
|
+
} else {
|
|
818
|
+
castedValue = interpolate(trimmed, component)
|
|
819
|
+
}
|
|
809
820
|
}
|
|
810
821
|
// dynamic value
|
|
811
822
|
else if (val.startsWith('$')) {
|
package/src/lib/lifecycle.js
CHANGED
|
@@ -97,7 +97,7 @@ export default {
|
|
|
97
97
|
this.component[symbols.holder] &&
|
|
98
98
|
typeof this.component[symbols.holder].setInspectorMetadata === 'function'
|
|
99
99
|
) {
|
|
100
|
-
this.component[symbols.holder].setInspectorMetadata({
|
|
100
|
+
this.component[symbols.holder].setInspectorMetadata({ 'blits-hasFocus': true })
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
if (v === 'unfocus') {
|
|
@@ -107,7 +107,7 @@ export default {
|
|
|
107
107
|
this.component[symbols.holder] &&
|
|
108
108
|
typeof this.component[symbols.holder].setInspectorMetadata === 'function'
|
|
109
109
|
) {
|
|
110
|
-
this.component[symbols.holder].setInspectorMetadata({
|
|
110
|
+
this.component[symbols.holder].setInspectorMetadata({ 'blits-hasFocus': false })
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
}
|
|
@@ -32,9 +32,10 @@ const objectMap = new WeakMap()
|
|
|
32
32
|
const globalEffectsMap = new Map()
|
|
33
33
|
|
|
34
34
|
export const removeGlobalEffects = (effectsToRemove) => {
|
|
35
|
-
if (globalEffectsMap.size === 0) return
|
|
35
|
+
if (globalEffectsMap.size === 0 || effectsToRemove.length === 0) return
|
|
36
|
+
const effectsToRemoveSet = new Set(effectsToRemove)
|
|
36
37
|
for (const [effect, target] of globalEffectsMap) {
|
|
37
|
-
if (
|
|
38
|
+
if (!effectsToRemoveSet.has(effect)) continue
|
|
38
39
|
const effectsSet = objectMap.get(target)
|
|
39
40
|
if (effectsSet === undefined) continue
|
|
40
41
|
for (const set of effectsSet.values()) {
|
|
@@ -195,7 +195,7 @@ export default (code) => {
|
|
|
195
195
|
if (thisRefs.size > 0) {
|
|
196
196
|
// Skip if already modified
|
|
197
197
|
if (
|
|
198
|
-
prop.body.includes(commentText) ||
|
|
198
|
+
prop.body.includes(commentText.trim()) ||
|
|
199
199
|
Array.from(thisRefs).some((ref) => prop.body.startsWith(ref))
|
|
200
200
|
) {
|
|
201
201
|
continue
|
package/src/router/router.js
CHANGED
|
@@ -403,7 +403,7 @@ export const navigate = async function () {
|
|
|
403
403
|
// Update router state after announcements and final route resolution,
|
|
404
404
|
// right before initializing or restoring the view
|
|
405
405
|
state.path = route.path
|
|
406
|
-
state.params = route.params
|
|
406
|
+
state.params = Object.keys(route.params).length === 0 ? null : route.params
|
|
407
407
|
state.hash = route.hash
|
|
408
408
|
state.data = null
|
|
409
409
|
state.data = route.data || {}
|