@lightningjs/blits 1.45.2 → 1.47.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 +21 -1
- package/index.d.ts +55 -25
- package/package.json +2 -2
- package/scripts/prepublishOnly.js +7 -1
- package/src/announcer/announcer.js +50 -4
- package/src/announcer/speechSynthesis.js +156 -37
- package/src/component/base/methods.js +4 -0
- package/src/component/base/router.js +6 -0
- package/src/component/base/timeouts_intervals.js +56 -0
- package/src/component/setup/routes.js +5 -0
- package/src/component.js +3 -0
- package/src/components/Circle.js +1 -0
- package/src/components/FPScounter.js +1 -0
- package/src/components/RouterView.js +88 -78
- package/src/components/Sprite.js +1 -0
- package/src/engines/L3/element.js +60 -2
- package/src/lib/codegenerator/generator.js +22 -1
- package/src/lib/lifecycle.js +28 -2
- package/src/lib/reactivityguard/computedprops.js +79 -13
- package/src/lib/symbols.js +2 -0
- package/src/plugins/appstate.d.ts +1 -4
- package/src/plugins/index.d.ts +4 -5
- package/src/plugins/language.d.ts +7 -4
- package/src/plugins/storage/storage.d.ts +6 -4
- package/src/plugins/theme.d.ts +12 -4
- package/src/plugins/theme.js +30 -3
- package/src/router/router.js +35 -2
package/src/components/Circle.js
CHANGED
|
@@ -16,96 +16,106 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import Component from '../component.js'
|
|
19
|
-
import Router from '../router/router.js'
|
|
19
|
+
import Router, { state as routerState } from '../router/router.js'
|
|
20
20
|
import symbols from '../lib/symbols.js'
|
|
21
21
|
import Focus from '../focus.js'
|
|
22
22
|
|
|
23
23
|
let hashchangeHandler = null
|
|
24
24
|
|
|
25
|
+
/** @typedef {{ $input?: (event: any) => boolean, $focus?: (event: any) => void }} RouterViewParent */
|
|
26
|
+
|
|
25
27
|
export default () =>
|
|
26
|
-
Component(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
28
|
+
Component(
|
|
29
|
+
'RouterView',
|
|
30
|
+
/** @type {any} */ ({
|
|
31
|
+
/* eslint-disable no-unused-vars */
|
|
32
|
+
code: {
|
|
33
|
+
render: function anonymous(parent, component, context, components, effect, getRaw, Log) {
|
|
34
|
+
const elms = []
|
|
35
|
+
const elementConfigs = []
|
|
36
|
+
const forloops = []
|
|
37
|
+
const props = []
|
|
38
|
+
const created = []
|
|
39
|
+
const effects = {}
|
|
40
|
+
const skips = []
|
|
41
|
+
let componentType
|
|
42
|
+
let rootComponent = component
|
|
43
|
+
let propData
|
|
44
|
+
let slotComponent
|
|
45
|
+
let inSlot = false
|
|
46
|
+
let slotChildCounter = 0
|
|
47
|
+
let cmps = []
|
|
48
|
+
elementConfigs[0] = {}
|
|
49
|
+
elementConfigs[0]['___wrapper'] = true
|
|
45
50
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
elms[0] = this.element(
|
|
52
|
+
{ parent: parent || 'root' },
|
|
53
|
+
inSlot === true ? slotComponent : component
|
|
54
|
+
)
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
elementConfigs[0]['w'] = parent.node.width * (100 / 100)
|
|
57
|
+
elementConfigs[0]['height'] = parent.node.height * (100 / 100)
|
|
58
|
+
elms[0].populate(elementConfigs[0])
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
if (inSlot === true) {
|
|
61
|
+
slotChildCounter -= 1
|
|
62
|
+
}
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
64
|
+
return {
|
|
65
|
+
elms,
|
|
66
|
+
cleanup: () => {
|
|
67
|
+
rootComponent = null
|
|
68
|
+
propData = null
|
|
69
|
+
slotComponent = null
|
|
70
|
+
parent = null
|
|
71
|
+
component = null
|
|
72
|
+
cmps.length = 0
|
|
73
|
+
elms.length = 0
|
|
74
|
+
components.length = 0
|
|
75
|
+
elementConfigs.length = 0
|
|
76
|
+
forloops.length = 0
|
|
77
|
+
props.length = 0
|
|
78
|
+
skips.length = 0
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
effects: [],
|
|
83
|
+
context: {},
|
|
76
84
|
},
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
state() {
|
|
81
|
-
return {
|
|
82
|
-
activeView: null,
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
hooks: {
|
|
86
|
-
async ready() {
|
|
87
|
-
if (this.parent[symbols.routerHooks] && this.parent[symbols.routerHooks].init) {
|
|
88
|
-
await this.parent[symbols.routerHooks].init.apply(this.parent)
|
|
85
|
+
state() {
|
|
86
|
+
return {
|
|
87
|
+
activeView: null,
|
|
89
88
|
}
|
|
90
|
-
hashchangeHandler = () => Router.navigate.apply(this)
|
|
91
|
-
Router.navigate.apply(this)
|
|
92
|
-
window.addEventListener('hashchange', hashchangeHandler)
|
|
93
|
-
},
|
|
94
|
-
destroy() {
|
|
95
|
-
window.removeEventListener('hashchange', hashchangeHandler, false)
|
|
96
89
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.
|
|
100
|
-
|
|
90
|
+
hooks: {
|
|
91
|
+
async ready() {
|
|
92
|
+
if (this.parent[symbols.routerHooks] && this.parent[symbols.routerHooks].init) {
|
|
93
|
+
await this.parent[symbols.routerHooks].init.apply(this.parent)
|
|
94
|
+
}
|
|
95
|
+
hashchangeHandler = () => Router.navigate.apply(this)
|
|
96
|
+
Router.navigate.apply(this)
|
|
97
|
+
window.addEventListener('hashchange', hashchangeHandler)
|
|
98
|
+
},
|
|
99
|
+
destroy() {
|
|
100
|
+
window.removeEventListener('hashchange', hashchangeHandler, false)
|
|
101
|
+
},
|
|
102
|
+
focus() {
|
|
103
|
+
if (this.activeView && Focus.get() === this) {
|
|
104
|
+
this.activeView.$focus()
|
|
105
|
+
}
|
|
106
|
+
},
|
|
101
107
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
input: {
|
|
109
|
+
back(e) {
|
|
110
|
+
if (routerState.backNavigation === false) {
|
|
111
|
+
this.parent.$input(e)
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
const navigating = Router.back.call(this)
|
|
115
|
+
if (navigating === false) {
|
|
116
|
+
this.parent.$focus(e)
|
|
117
|
+
}
|
|
118
|
+
},
|
|
109
119
|
},
|
|
110
|
-
}
|
|
111
|
-
|
|
120
|
+
})
|
|
121
|
+
)
|
package/src/components/Sprite.js
CHANGED
|
@@ -243,15 +243,29 @@ const propsTransformer = {
|
|
|
243
243
|
},
|
|
244
244
|
set w(v) {
|
|
245
245
|
this.props['width'] = parsePercentage.call(this, v, 'width')
|
|
246
|
+
if (
|
|
247
|
+
this.___wrapper === true &&
|
|
248
|
+
this.element.component.eol !== true &&
|
|
249
|
+
this.element.component[symbols.holder] !== undefined
|
|
250
|
+
) {
|
|
251
|
+
this.element.component[symbols.holder].set('w', this.props['width'])
|
|
252
|
+
}
|
|
246
253
|
},
|
|
247
254
|
set width(v) {
|
|
248
|
-
this.
|
|
255
|
+
this.w = v
|
|
249
256
|
},
|
|
250
257
|
set h(v) {
|
|
251
258
|
this.props['height'] = parsePercentage.call(this, v, 'height')
|
|
259
|
+
if (
|
|
260
|
+
this.___wrapper === true &&
|
|
261
|
+
this.element.component.eol !== true &&
|
|
262
|
+
this.element.component[symbols.holder] !== undefined
|
|
263
|
+
) {
|
|
264
|
+
this.element.component[symbols.holder].set('h', this.props['height'])
|
|
265
|
+
}
|
|
252
266
|
},
|
|
253
267
|
set height(v) {
|
|
254
|
-
this.
|
|
268
|
+
this.h = v
|
|
255
269
|
},
|
|
256
270
|
set x(v) {
|
|
257
271
|
this.props['x'] = parsePercentage.call(this, v, 'width')
|
|
@@ -564,6 +578,39 @@ const Element = {
|
|
|
564
578
|
})
|
|
565
579
|
}
|
|
566
580
|
},
|
|
581
|
+
/**
|
|
582
|
+
* Sets framework-provided inspector metadata
|
|
583
|
+
* Only sets if inspector is enabled and in dev mode
|
|
584
|
+
* @param {Object} data - Framework inspector metadata to merge
|
|
585
|
+
*/
|
|
586
|
+
setInspectorMetadata(data) {
|
|
587
|
+
// Early return if inspector not enabled (performance optimization)
|
|
588
|
+
if (inspectorEnabled !== true) {
|
|
589
|
+
return
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Early return if element is destroyed (props.props is null)
|
|
593
|
+
if (this.props.props === undefined || this.props.props === null) {
|
|
594
|
+
return
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// Initialize data object if it doesn't exist
|
|
598
|
+
if (this.props['data'] === undefined) {
|
|
599
|
+
this.props['data'] = {}
|
|
600
|
+
}
|
|
601
|
+
if (this.props.props['data'] === undefined) {
|
|
602
|
+
this.props.props['data'] = {}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Merge framework data (with $ prefix to prevent collisions)
|
|
606
|
+
Object.assign(this.props['data'], data)
|
|
607
|
+
Object.assign(this.props.props['data'], data)
|
|
608
|
+
|
|
609
|
+
// Sync to renderer node so inspector can see it
|
|
610
|
+
if (this.node !== undefined && this.node !== null) {
|
|
611
|
+
this.node.data = { ...this.props.props['data'] }
|
|
612
|
+
}
|
|
613
|
+
},
|
|
567
614
|
/**
|
|
568
615
|
* Set an individual property on the node
|
|
569
616
|
*
|
|
@@ -651,6 +698,11 @@ const Element = {
|
|
|
651
698
|
f,
|
|
652
699
|
}
|
|
653
700
|
|
|
701
|
+
// Update inspector metadata when transition starts
|
|
702
|
+
if (inspectorEnabled === true) {
|
|
703
|
+
this.setInspectorMetadata({ $isTransitioning: true })
|
|
704
|
+
}
|
|
705
|
+
|
|
654
706
|
if (transition.start !== undefined && typeof transition.start === 'function') {
|
|
655
707
|
// fire transition start callback when animation really starts (depending on specified delay)
|
|
656
708
|
f.once('animating', () => {
|
|
@@ -685,6 +737,12 @@ const Element = {
|
|
|
685
737
|
}
|
|
686
738
|
// remove the prop from scheduled transitions
|
|
687
739
|
delete this.scheduledTransitions[prop]
|
|
740
|
+
// Update inspector metadata when transition ends
|
|
741
|
+
if (inspectorEnabled === true) {
|
|
742
|
+
this.setInspectorMetadata({
|
|
743
|
+
$isTransitioning: Object.keys(this.scheduledTransitions).length > 0,
|
|
744
|
+
})
|
|
745
|
+
}
|
|
688
746
|
})
|
|
689
747
|
|
|
690
748
|
// start animation
|
|
@@ -151,6 +151,10 @@ const generateElementCode = function (
|
|
|
151
151
|
|
|
152
152
|
renderCode.push(`elementConfigs[${counter}] = {}`)
|
|
153
153
|
|
|
154
|
+
if (counter === 0) {
|
|
155
|
+
renderCode.push(`elementConfigs[${counter}]['___wrapper'] = true `)
|
|
156
|
+
}
|
|
157
|
+
|
|
154
158
|
if (options.forloop) {
|
|
155
159
|
renderCode.push(`if(${elm} === undefined) {`)
|
|
156
160
|
}
|
|
@@ -283,9 +287,11 @@ const generateComponentCode = function (
|
|
|
283
287
|
|
|
284
288
|
const children = templateObject.children
|
|
285
289
|
delete templateObject.children
|
|
290
|
+
// Capture holder counter before generating element code (which may process children and increment counter)
|
|
291
|
+
const holderCounter = counter
|
|
286
292
|
generateElementCode.call(this, templateObject, parent, { ...options, ...{ holder: true } })
|
|
287
293
|
|
|
288
|
-
parent = options.key ? `elms[${
|
|
294
|
+
parent = options.key ? `elms[${holderCounter}][${options.key}]` : `elms[${holderCounter}]`
|
|
289
295
|
|
|
290
296
|
counter++
|
|
291
297
|
|
|
@@ -354,6 +360,21 @@ const generateComponentCode = function (
|
|
|
354
360
|
}
|
|
355
361
|
`)
|
|
356
362
|
|
|
363
|
+
// For forloops, this code runs per instance, setting metadata for each component instance
|
|
364
|
+
if (isDev === true) {
|
|
365
|
+
const componentType = templateObject[Symbol.for('componentType')]
|
|
366
|
+
const holderElm = options.key
|
|
367
|
+
? `elms[${holderCounter}][${options.key}]`
|
|
368
|
+
: `elms[${holderCounter}]`
|
|
369
|
+
renderCode.push(`
|
|
370
|
+
if (${holderElm} !== undefined && typeof ${holderElm}.setInspectorMetadata === 'function') {
|
|
371
|
+
${holderElm}.setInspectorMetadata({
|
|
372
|
+
$componentType: '${componentType}'
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
`)
|
|
376
|
+
}
|
|
377
|
+
|
|
357
378
|
this.cleanupCode.push(`components[${counter}] = null`)
|
|
358
379
|
|
|
359
380
|
if (options.forloop) {
|
package/src/lib/lifecycle.js
CHANGED
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
import { Log } from './log.js'
|
|
19
19
|
import { emit, privateEmit } from './hooks.js'
|
|
20
20
|
import symbols from './symbols.js'
|
|
21
|
+
import Settings from '../settings.js'
|
|
22
|
+
|
|
23
|
+
let inspectorEnabled = null
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* List of valid lifecycle states for a component.
|
|
@@ -82,8 +85,31 @@ export default {
|
|
|
82
85
|
// emit 'public' hook
|
|
83
86
|
emit(v, this.component[symbols.identifier], this.component)
|
|
84
87
|
// update the built-in hasFocus state variable
|
|
85
|
-
if (v === 'focus'
|
|
86
|
-
|
|
88
|
+
if (v === 'focus' || v === 'unfocus') {
|
|
89
|
+
if (inspectorEnabled === null) {
|
|
90
|
+
inspectorEnabled = Settings.get('inspector', false)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (v === 'focus') {
|
|
94
|
+
this.component[symbols.state].hasFocus = true
|
|
95
|
+
if (
|
|
96
|
+
inspectorEnabled === true &&
|
|
97
|
+
this.component[symbols.holder] &&
|
|
98
|
+
typeof this.component[symbols.holder].setInspectorMetadata === 'function'
|
|
99
|
+
) {
|
|
100
|
+
this.component[symbols.holder].setInspectorMetadata({ $hasFocus: true })
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (v === 'unfocus') {
|
|
104
|
+
this.component[symbols.state].hasFocus = false
|
|
105
|
+
if (
|
|
106
|
+
inspectorEnabled === true &&
|
|
107
|
+
this.component[symbols.holder] &&
|
|
108
|
+
typeof this.component[symbols.holder].setInspectorMetadata === 'function'
|
|
109
|
+
) {
|
|
110
|
+
this.component[symbols.holder].setInspectorMetadata({ $hasFocus: false })
|
|
111
|
+
}
|
|
112
|
+
}
|
|
87
113
|
}
|
|
88
114
|
},
|
|
89
115
|
}
|
|
@@ -35,10 +35,12 @@ const findMatchingBrace = (text, startPos) => {
|
|
|
35
35
|
// Skip comments when not in strings
|
|
36
36
|
else if (!inString && char === '/' && text[position + 1] === '/') {
|
|
37
37
|
// Skip line comment
|
|
38
|
-
|
|
38
|
+
const nextNewline = text.indexOf('\n', position + 2)
|
|
39
|
+
position = nextNewline === -1 ? text.length - 1 : nextNewline
|
|
39
40
|
} else if (!inString && char === '/' && text[position + 1] === '*') {
|
|
40
41
|
// Skip block comment
|
|
41
|
-
|
|
42
|
+
const end = text.indexOf('*/', position + 2)
|
|
43
|
+
position = end === -1 ? text.length - 1 : end + 1
|
|
42
44
|
}
|
|
43
45
|
// Count braces only outside strings and comments
|
|
44
46
|
else if (!inString) {
|
|
@@ -60,6 +62,44 @@ const findComputedFunctionEnd = (computedObj, openingBracePos) => {
|
|
|
60
62
|
return findMatchingBrace(computedObj, openingBracePos)
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
// Skip whitespace + commas + comments (line and block) starting from `pos`, return next code position.
|
|
66
|
+
const skipNonCode = (text, pos) => {
|
|
67
|
+
let p = pos
|
|
68
|
+
while (p < text.length) {
|
|
69
|
+
const c = text[p]
|
|
70
|
+
|
|
71
|
+
// whitespace
|
|
72
|
+
if (c === ' ' || c === '\t' || c === '\n' || c === '\r') {
|
|
73
|
+
p++
|
|
74
|
+
continue
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// separators between object members
|
|
78
|
+
if (c === ',') {
|
|
79
|
+
p++
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// line comment
|
|
84
|
+
if (c === '/' && text[p + 1] === '/') {
|
|
85
|
+
const nextNewline = text.indexOf('\n', p + 2)
|
|
86
|
+
p = nextNewline === -1 ? text.length : nextNewline + 1
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// block comment
|
|
91
|
+
if (c === '/' && text[p + 1] === '*') {
|
|
92
|
+
const end = text.indexOf('*/', p + 2)
|
|
93
|
+
p = end === -1 ? text.length : end + 2
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return p
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return p
|
|
101
|
+
}
|
|
102
|
+
|
|
63
103
|
export default (code) => {
|
|
64
104
|
// Find component declarations
|
|
65
105
|
const componentRegex =
|
|
@@ -83,6 +123,8 @@ export default (code) => {
|
|
|
83
123
|
|
|
84
124
|
if (computedEnd !== -1) {
|
|
85
125
|
const computedObj = configObject.substring(computedStart, computedEnd)
|
|
126
|
+
const computedBlockStart = computedKeywordMatch.index
|
|
127
|
+
const computedBlockEnd = computedEnd
|
|
86
128
|
|
|
87
129
|
// Process each computed property
|
|
88
130
|
const computedProps = []
|
|
@@ -93,15 +135,20 @@ export default (code) => {
|
|
|
93
135
|
// using cursor-based parsing gives better accuracy
|
|
94
136
|
while (currentPos < computedObj.length - 1) {
|
|
95
137
|
// -1 to exclude the closing brace
|
|
96
|
-
//
|
|
97
|
-
|
|
138
|
+
// Skip whitespace/comments so we don't match commented-out computed functions
|
|
139
|
+
currentPos = skipNonCode(computedObj, currentPos)
|
|
140
|
+
if (currentPos >= computedObj.length - 1) break
|
|
141
|
+
|
|
142
|
+
// Find the next function name (computed properties are `name() { ... }`)
|
|
143
|
+
const functionNameMatch = /^(\w+)\s*\(\)\s*/.exec(computedObj.substring(currentPos))
|
|
98
144
|
if (!functionNameMatch) break
|
|
99
145
|
|
|
100
146
|
const funcName = functionNameMatch[1]
|
|
101
|
-
const funcNamePos = currentPos
|
|
147
|
+
const funcNamePos = currentPos
|
|
102
148
|
|
|
103
149
|
// Find opening brace for this function
|
|
104
|
-
const
|
|
150
|
+
const afterSignaturePos = funcNamePos + functionNameMatch[0].length
|
|
151
|
+
const openingBracePos = computedObj.indexOf('{', afterSignaturePos)
|
|
105
152
|
if (openingBracePos === -1) break
|
|
106
153
|
|
|
107
154
|
// Find closing brace for individual computed function
|
|
@@ -133,14 +180,15 @@ export default (code) => {
|
|
|
133
180
|
}
|
|
134
181
|
|
|
135
182
|
// Store the original computed object for later replacement
|
|
136
|
-
const originalComputedObj = configObject.substring(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
)
|
|
183
|
+
const originalComputedObj = configObject.substring(computedBlockStart, computedBlockEnd)
|
|
184
|
+
const computedObjOffsetInOriginal = computedStart - computedBlockStart
|
|
185
|
+
const computedObjEndInOriginal = computedObjOffsetInOriginal + computedObj.length
|
|
140
186
|
|
|
141
187
|
let modifiedComputedObj = originalComputedObj
|
|
142
188
|
let hasChanges = false
|
|
143
189
|
|
|
190
|
+
const replacements = []
|
|
191
|
+
|
|
144
192
|
for (const prop of computedProps) {
|
|
145
193
|
const thisRefs = extractThisReferences(prop.body)
|
|
146
194
|
|
|
@@ -181,13 +229,31 @@ export default (code) => {
|
|
|
181
229
|
prop.fullText.substring(0, openBraceIndex).match(/^(\s*)/)[0] +
|
|
182
230
|
'}'
|
|
183
231
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
232
|
+
replacements.push({
|
|
233
|
+
start: prop.startPos,
|
|
234
|
+
end: prop.endPos,
|
|
235
|
+
text: modifiedPropText,
|
|
236
|
+
})
|
|
187
237
|
}
|
|
188
238
|
}
|
|
189
239
|
}
|
|
190
240
|
|
|
241
|
+
if (replacements.length > 0) {
|
|
242
|
+
let modifiedComputedInner = computedObj
|
|
243
|
+
|
|
244
|
+
replacements.sort((a, b) => b.start - a.start)
|
|
245
|
+
for (const r of replacements) {
|
|
246
|
+
modifiedComputedInner =
|
|
247
|
+
modifiedComputedInner.slice(0, r.start) + r.text + modifiedComputedInner.slice(r.end)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
modifiedComputedObj =
|
|
251
|
+
originalComputedObj.slice(0, computedObjOffsetInOriginal) +
|
|
252
|
+
modifiedComputedInner +
|
|
253
|
+
originalComputedObj.slice(computedObjEndInOriginal)
|
|
254
|
+
hasChanges = true
|
|
255
|
+
}
|
|
256
|
+
|
|
191
257
|
if (hasChanges) {
|
|
192
258
|
// Store the modification of the entire computed object
|
|
193
259
|
modifications.push({
|
package/src/lib/symbols.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* @property {symbol} inputEvents
|
|
18
18
|
* @property {symbol} internalEvent
|
|
19
19
|
* @property {symbol} intervals
|
|
20
|
+
* @property {symbol} debounces
|
|
20
21
|
* @property {symbol} isProxy
|
|
21
22
|
* @property {symbol} launched
|
|
22
23
|
* @property {symbol} level
|
|
@@ -70,6 +71,7 @@ export default {
|
|
|
70
71
|
inputEvents: Symbol('inputEvents'),
|
|
71
72
|
internalEvent: Symbol('internalEvent'),
|
|
72
73
|
intervals: Symbol('intervals'),
|
|
74
|
+
debounces: Symbol('debounces'),
|
|
73
75
|
isProxy: Symbol('isProxy'),
|
|
74
76
|
launched: Symbol('launched'),
|
|
75
77
|
level: Symbol('level'),
|
|
@@ -15,10 +15,7 @@
|
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// Re-export AppStatePlugin for direct imports
|
|
21
|
-
export type { AppStatePlugin }
|
|
18
|
+
export type AppStatePlugin<TState extends Record<string, unknown> = Record<string, unknown>> = TState
|
|
22
19
|
|
|
23
20
|
declare const appState: {
|
|
24
21
|
readonly name: 'appState'
|
package/src/plugins/index.d.ts
CHANGED
|
@@ -21,9 +21,8 @@ export { default as appState } from './appstate.js'
|
|
|
21
21
|
export { default as storage } from './storage/storage.js'
|
|
22
22
|
|
|
23
23
|
// Re-export plugin interfaces for convenience
|
|
24
|
-
export type { LanguagePlugin,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export type {
|
|
28
|
-
export type { ThemePluginConfig } from './theme.js'
|
|
24
|
+
export type { LanguagePlugin, LanguagePluginOptions } from './language.js'
|
|
25
|
+
export type { ThemePlugin, ThemePluginConfig } from './theme.js'
|
|
26
|
+
export type { StoragePlugin } from './storage/storage.js'
|
|
27
|
+
export type { AppStatePlugin } from './appstate.js'
|
|
29
28
|
|
|
@@ -15,16 +15,19 @@
|
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
export interface LanguagePlugin {
|
|
19
|
+
translate(key: string, ...replacements: any[]): string
|
|
20
|
+
readonly language: string
|
|
21
|
+
set(language: string): void
|
|
22
|
+
translations(translationsObject: Record<string, unknown>): void
|
|
23
|
+
load(file: string): Promise<void>
|
|
24
|
+
}
|
|
19
25
|
|
|
20
26
|
export interface LanguagePluginOptions {
|
|
21
27
|
file?: string
|
|
22
28
|
language?: string
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
// Re-export LanguagePlugin for direct imports
|
|
26
|
-
export type { LanguagePlugin }
|
|
27
|
-
|
|
28
31
|
declare const language: {
|
|
29
32
|
readonly name: 'language'
|
|
30
33
|
plugin: (options?: LanguagePluginOptions) => LanguagePlugin
|
|
@@ -15,10 +15,12 @@
|
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
export interface StoragePlugin {
|
|
19
|
+
get<T = unknown>(key: string): T | null
|
|
20
|
+
set(key: string, value: unknown): boolean
|
|
21
|
+
remove(key: string): void
|
|
22
|
+
clear(): void
|
|
23
|
+
}
|
|
22
24
|
|
|
23
25
|
declare const storage: {
|
|
24
26
|
readonly name: 'storage'
|
package/src/plugins/theme.d.ts
CHANGED
|
@@ -15,17 +15,25 @@
|
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
export interface ThemePlugin {
|
|
19
|
+
get<T = unknown>(key: string): T | undefined
|
|
20
|
+
get<T>(key: string, fallback: T): T
|
|
21
|
+
/**
|
|
22
|
+
* @deprecated
|
|
23
|
+
* Deprecated: use `$theme.current()` instead
|
|
24
|
+
*/
|
|
25
|
+
set(theme: string): void
|
|
26
|
+
current(theme: string): void
|
|
27
|
+
variant(theme: string): void
|
|
28
|
+
}
|
|
19
29
|
|
|
20
30
|
export interface ThemePluginConfig {
|
|
21
31
|
themes?: Record<string, Record<string, unknown>>
|
|
22
32
|
current?: string
|
|
23
33
|
base?: string
|
|
34
|
+
variant?: string
|
|
24
35
|
}
|
|
25
36
|
|
|
26
|
-
// Re-export ThemePlugin for direct imports
|
|
27
|
-
export type { ThemePlugin }
|
|
28
|
-
|
|
29
37
|
declare const theme: {
|
|
30
38
|
readonly name: 'theme'
|
|
31
39
|
plugin: (config?: ThemePluginConfig | Record<string, unknown>) => ThemePlugin
|