@lightningjs/blits 2.0.0-beta.1 → 2.0.0-beta.2

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.
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Copyright 2024 Comcast Cable Communications Management, LLC
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ *
15
+ * SPDX-License-Identifier: Apache-2.0
16
+ */
17
+
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
+ }
25
+
26
+ export interface LanguagePluginOptions {
27
+ file?: string
28
+ language?: string
29
+ }
30
+
31
+ declare const language: {
32
+ readonly name: 'language'
33
+ plugin: (options?: LanguagePluginOptions) => LanguagePlugin
34
+ }
35
+
36
+ export default language
37
+
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright 2024 Comcast Cable Communications Management, LLC
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ *
15
+ * SPDX-License-Identifier: Apache-2.0
16
+ */
17
+
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
+ }
24
+
25
+ declare const storage: {
26
+ readonly name: 'storage'
27
+ plugin: () => StoragePlugin
28
+ }
29
+
30
+ export default storage
31
+
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Copyright 2024 Comcast Cable Communications Management, LLC
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ *
15
+ * SPDX-License-Identifier: Apache-2.0
16
+ */
17
+
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
+ }
29
+
30
+ export interface ThemePluginConfig {
31
+ themes?: Record<string, Record<string, unknown>>
32
+ current?: string
33
+ base?: string
34
+ variant?: string
35
+ }
36
+
37
+ declare const theme: {
38
+ readonly name: 'theme'
39
+ plugin: (config?: ThemePluginConfig | Record<string, unknown>) => ThemePlugin
40
+ }
41
+
42
+ export default theme
43
+
@@ -20,13 +20,17 @@ import { reactive } from '../lib/reactivity/reactive.js'
20
20
 
21
21
  import Settings from '../settings.js'
22
22
 
23
- const getValueByDotNotation = (obj, base, path) => {
23
+ const getValueByDotNotation = (obj, base, variant, path) => {
24
24
  const keys = path.split('.')
25
25
 
26
26
  for (let i = 0; i < keys.length; i++) {
27
27
  const key = keys[i]
28
28
 
29
- if (obj !== null && key in obj === true) {
29
+ if (variant !== null && key in variant === true) {
30
+ obj = variant[key]
31
+ variant = variant !== null && key in variant === true ? variant[key] : null
32
+ base = base !== null && key in base === true ? base[key] : null
33
+ } else if (obj !== null && key in obj === true) {
30
34
  obj = obj[key]
31
35
  base = base !== null && key in base === true ? base[key] : null
32
36
  }
@@ -51,6 +55,7 @@ export default {
51
55
  const state = reactive(
52
56
  {
53
57
  current: 'default',
58
+ variant: null,
54
59
  },
55
60
  Settings.get('reactivityMode'),
56
61
  true
@@ -62,6 +67,7 @@ export default {
62
67
  themes = config.themes
63
68
  state.current = config.current || 'default'
64
69
  base = config.base || 'default'
70
+ state.variant = config.variant || null
65
71
  } else {
66
72
  themes = { default: config }
67
73
  }
@@ -71,8 +77,14 @@ export default {
71
77
  // reference state.current, to trigger reactive effects for
72
78
  // theme get function when current theme is modified
73
79
  state.current
80
+ state.variant
74
81
  if (themeMap[key] !== undefined) return themeMap[key]
75
- const value = getValueByDotNotation(themes[state.current], themes[base] || null, key)
82
+ const value = getValueByDotNotation(
83
+ themes[state.current],
84
+ themes[base] || null,
85
+ themes[state.variant] || null,
86
+ key
87
+ )
76
88
  if (value !== undefined) {
77
89
  // store the value for next time
78
90
  themeMap[key] = value
@@ -82,6 +94,11 @@ export default {
82
94
  },
83
95
 
84
96
  set(theme) {
97
+ Log.warn('$theme.set() is deprecated, use $theme.current() instead')
98
+ this.current(theme)
99
+ },
100
+
101
+ current(theme) {
85
102
  if (theme in themes) {
86
103
  themeMap = {}
87
104
  state.current = theme
@@ -89,6 +106,16 @@ export default {
89
106
  Log.warn(`Theme ${theme} not found`)
90
107
  }
91
108
  },
109
+
110
+ variant(theme) {
111
+ if (theme in themes) {
112
+ themeMap = {}
113
+ state.variant = theme
114
+ console.log('change variant', theme)
115
+ } else {
116
+ Log.warn(`Variant ${theme} not found`)
117
+ }
118
+ },
92
119
  }
93
120
  },
94
121
  }
@@ -30,6 +30,9 @@ import Settings from '../settings.js'
30
30
  * @typedef {import('../component.js').BlitsComponent} BlitsComponent - The element of the route
31
31
  * @typedef {import('../engines/L3/element.js').BlitsElement} BlitsElement - The element of the route
32
32
  *
33
+ * @typedef {BlitsComponent|BlitsComponentFactory} RouteView
34
+ * @typedef {RouteView & { default?: BlitsComponentFactory }} RouteViewWithOptionalDefault
35
+ *
33
36
  * @typedef {Object} Route
34
37
  * @property {string} path - The path of the route
35
38
  * @property {string} hash - The hash of the route
@@ -57,6 +60,7 @@ export const state = reactive(
57
60
  data: null,
58
61
  params: null,
59
62
  hash: '',
63
+ backNavigation: true,
60
64
  },
61
65
  Settings.get('reactivityMode'),
62
66
  true
@@ -335,6 +339,7 @@ export const navigate = async function () {
335
339
  return
336
340
  }
337
341
  }
342
+
338
343
  // add the previous route (technically still the current route at this point)
339
344
  // into the history stack when inHistory is true and we're not navigating back
340
345
  if (
@@ -354,6 +359,7 @@ export const navigate = async function () {
354
359
  /** @type {import('../engines/L3/element.js').BlitsElement} */
355
360
  let holder
356
361
 
362
+ /** @type {RouteViewWithOptionalDefault|undefined|null} */
357
363
  let view
358
364
  let focus
359
365
  // when navigating back let's see if we're navigating back to a route that was kept alive
@@ -397,7 +403,7 @@ export const navigate = async function () {
397
403
  // Update router state after announcements and final route resolution,
398
404
  // right before initializing or restoring the view
399
405
  state.path = route.path
400
- state.params = route.params || {}
406
+ state.params = Object.keys(route.params).length === 0 ? null : route.params
401
407
  state.hash = route.hash
402
408
  state.data = null
403
409
  state.data = route.data || {}
@@ -484,7 +490,7 @@ export const navigate = async function () {
484
490
  shouldAnimate = true
485
491
  const oldView = this[symbols.children].splice(1, 1).pop()
486
492
  if (oldView) {
487
- removeView(previousRoute, oldView, route.transition.out, navigatingBack)
493
+ await removeView(previousRoute, oldView, route.transition.out, navigatingBack)
488
494
  }
489
495
  }
490
496
 
@@ -492,7 +498,7 @@ export const navigate = async function () {
492
498
  if (route.transition.in) {
493
499
  if (Array.isArray(route.transition.in)) {
494
500
  for (let i = 0; i < route.transition.in.length; i++) {
495
- i === route.transition.length - 1
501
+ i === route.transition.in.length - 1
496
502
  ? await setOrAnimate(holder, route.transition.in[i], shouldAnimate)
497
503
  : setOrAnimate(holder, route.transition.in[i], shouldAnimate)
498
504
  }
@@ -500,6 +506,33 @@ export const navigate = async function () {
500
506
  await setOrAnimate(holder, route.transition.in, shouldAnimate)
501
507
  }
502
508
  }
509
+
510
+ if (this[symbols.parent][symbols.routerHooks]) {
511
+ const hooks = this[symbols.parent][symbols.routerHooks]
512
+ if (hooks.afterEach) {
513
+ try {
514
+ await hooks.afterEach.call(
515
+ this.parent,
516
+ route, // to
517
+ previousRoute // from
518
+ )
519
+ } catch (error) {
520
+ Log.error('Error in "AfterEach" Hook', error)
521
+ }
522
+ }
523
+ }
524
+
525
+ if (route.hooks.after) {
526
+ try {
527
+ await route.hooks.after.call(
528
+ this.parent,
529
+ route, // to
530
+ previousRoute // from
531
+ )
532
+ } catch (error) {
533
+ Log.error('Error or Rejected Promise in "After" Hook', error)
534
+ }
535
+ }
503
536
  } else {
504
537
  Log.error(`Route ${route.hash} not found`)
505
538
  const routerHooks = this[symbols.parent][symbols.routerHooks]
Binary file
@@ -32,12 +32,22 @@ export default function () {
32
32
 
33
33
  // we should only precompile .blits, .js and .ts files
34
34
  if (
35
- fileExtension === '.js' ||
36
- fileExtension === '.ts' ||
37
- fileExtension === '.blits' ||
38
- fileExtension === '.mjs'
35
+ filePath.indexOf('node_modules') === -1 &&
36
+ (fileExtension === '.js' ||
37
+ fileExtension === '.ts' ||
38
+ fileExtension === '.blits' ||
39
+ fileExtension === '.mjs')
39
40
  ) {
40
- return compiler(source, filePath, config.mode)
41
+ const result = compiler(source, filePath, config.mode)
42
+
43
+ if (typeof result === 'object') {
44
+ return {
45
+ code: result.code,
46
+ map: result.map,
47
+ }
48
+ }
49
+ // No transformation needed - return null so Vite knows no changes were made
50
+ return null
41
51
  }
42
52
 
43
53
  // vite expects null if there is no modification