@lightningjs/blits 1.5.1 → 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/CHANGELOG.md +14 -0
- package/bin/index.js +6 -138
- package/docs/getting_started/getting_started.md +1 -1
- package/docs/plugins/language.md +1 -1
- package/package.json +2 -8
- package/src/component/base/methods.js +2 -0
- package/src/component/setup/index.js +2 -0
- package/src/component.js +5 -2
- package/src/lib/codegenerator/generator.js +13 -5
- package/src/lib/reactivity/effect.js +17 -1
- package/src/lib/reactivity/reactive.js +10 -8
- package/src/lib/symbols.js +2 -0
- package/src/plugin.js +1 -1
- package/src/plugins/appstate.js +1 -1
- package/src/plugins/language.js +2 -1
- package/src/plugins/log.js +1 -1
- package/src/plugins/theme.js +3 -2
- package/bin/helpers.js +0 -220
- package/boilerplate/common/eslint/.editorconfig +0 -7
- package/boilerplate/common/eslint/.eslintignore +0 -3
- package/boilerplate/common/eslint/.eslintrc.cjs +0 -38
- package/boilerplate/common/eslint/husky/pre-commit +0 -2
- package/boilerplate/common/eslint/package.json +0 -20
- package/boilerplate/common/git/gitignore +0 -8
- package/boilerplate/common/ide/.vscode/extensions.json +0 -8
- package/boilerplate/common/ide/.vscode/launch.json +0 -12
- package/boilerplate/common/ide/.vscode/settings.json +0 -10
- package/boilerplate/common/public/assets/logo.png +0 -0
- package/boilerplate/common/public/fonts/Lato-Regular.ttf +0 -0
- package/boilerplate/common/public/fonts/OpenSans-Medium.ttf +0 -0
- package/boilerplate/common/public/fonts/Raleway-ExtraBold.ttf +0 -0
- package/boilerplate/js/default/.env.example +0 -4
- package/boilerplate/js/default/.gitattributes +0 -3
- package/boilerplate/js/default/index.html +0 -11
- package/boilerplate/js/default/package.json +0 -36
- package/boilerplate/js/default/src/App.js +0 -12
- package/boilerplate/js/default/src/components/Loader.js +0 -23
- package/boilerplate/js/default/src/index.js +0 -27
- package/boilerplate/js/default/src/pages/Home.js +0 -15
- package/boilerplate/js/default/vite.config.js +0 -26
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.7.0
|
|
4
|
+
|
|
5
|
+
_14 oct 2024_
|
|
6
|
+
|
|
7
|
+
- Added cleanup upon component destroy of effects generated by global reactivity
|
|
8
|
+
|
|
9
|
+
## v1.6.0 / v1.6.1
|
|
10
|
+
|
|
11
|
+
_9 oct 2024_
|
|
12
|
+
|
|
13
|
+
- Abstracted app create functionality to separate package
|
|
14
|
+
- Cleaned up dependencies
|
|
15
|
+
- Fixed issue with item reference in for loop
|
|
16
|
+
- Fixed issue with looping directly over `<Text>` components
|
|
3
17
|
|
|
4
18
|
## v1.5.1
|
|
5
19
|
|
package/bin/index.js
CHANGED
|
@@ -1,141 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import process from 'process'
|
|
4
|
-
import { dirname } from 'path'
|
|
5
|
-
import prompts from 'prompts'
|
|
6
|
-
import { fileURLToPath } from 'url'
|
|
7
|
-
import fs from 'fs'
|
|
8
|
-
import { red, bold } from 'kolorist'
|
|
9
|
-
import sequence from '../src/helpers/sequence.js'
|
|
10
|
-
import validatePackage from 'validate-npm-package-name'
|
|
11
|
-
import {
|
|
12
|
-
addESlint,
|
|
13
|
-
copyLightningFixtures,
|
|
14
|
-
setAppData,
|
|
15
|
-
setBlitsVersion,
|
|
16
|
-
gitInit,
|
|
17
|
-
done, spinnerMsg
|
|
18
|
-
} from './helpers.js'
|
|
2
|
+
import { execSync } from 'child_process'
|
|
19
3
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Answer the questions below to set up a new Lightning 3 Blits App
|
|
26
|
-
`
|
|
27
|
-
|
|
28
|
-
console.log(defaultBanner)
|
|
29
|
-
|
|
30
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
31
|
-
const __dirname = dirname(__filename)
|
|
32
|
-
|
|
33
|
-
const fixturesBase = path.join(
|
|
34
|
-
__dirname,
|
|
35
|
-
'../boilerplate')
|
|
36
|
-
|
|
37
|
-
const questions = [
|
|
38
|
-
{
|
|
39
|
-
type: 'text',
|
|
40
|
-
name: 'appName',
|
|
41
|
-
message: 'What is the name of your App?',
|
|
42
|
-
format: val => {
|
|
43
|
-
// Check if the provided application name is empty
|
|
44
|
-
if (!val.trim()) {
|
|
45
|
-
spinnerMsg.fail(red(bold("Please provide a name for the App")))
|
|
46
|
-
return process.exit(1)
|
|
47
|
-
} else {
|
|
48
|
-
return val
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
initial: 'My Blits App', // Default value for the application name
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
type: 'text',
|
|
55
|
-
name: 'appPackage',
|
|
56
|
-
message: 'What is the package name of your App?',
|
|
57
|
-
format: val => {
|
|
58
|
-
// Validate the package name using validate-npm-package-name
|
|
59
|
-
if (!validatePackage(val).validForNewPackages) {
|
|
60
|
-
spinnerMsg.fail(red(bold("Please provide a valid package name")))
|
|
61
|
-
return process.exit(1)
|
|
62
|
-
} else {
|
|
63
|
-
return val
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
initial: prev => `${prev.replace(/[\sA-Z]/g, str => str === ' ' ? '-' : str.toLowerCase())}`,
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
type: 'text',
|
|
70
|
-
name: 'appFolder',
|
|
71
|
-
message: 'In what folder (relative to the current location) should the App be generated?',
|
|
72
|
-
format: (val, prev) => {
|
|
73
|
-
// Regular expression to validate whether the path is Unix/Windows-based
|
|
74
|
-
const pathRegex = /([A-Za-z]:)?([\\/]+\w+)+/
|
|
75
|
-
// Check if the provided path matches the defined regex
|
|
76
|
-
if (pathRegex.test(val)) {
|
|
77
|
-
try {
|
|
78
|
-
// Check if the path exists
|
|
79
|
-
if (fs.statSync(val)) {
|
|
80
|
-
// Return the resolved file path using path.join
|
|
81
|
-
return `${path.join(val, prev.appPackage)}`
|
|
82
|
-
}
|
|
83
|
-
} catch (e) {
|
|
84
|
-
// Handle case where an error occurred during file system interaction
|
|
85
|
-
if (e.code === 'ENOENT') {
|
|
86
|
-
spinnerMsg.fail(red(bold("Entered directory path is invalid, please enter a valid directory!")))
|
|
87
|
-
process.exit()
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
} else if (val === prev.appPackage) {
|
|
91
|
-
return path.join(process.cwd(), prev.appPackage)
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
initial: (prev, val) => val.appPackage,
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
type: 'toggle',
|
|
98
|
-
name: 'esLint',
|
|
99
|
-
message: 'Do you want to enable eslint?',
|
|
100
|
-
initial: 'true',
|
|
101
|
-
active: 'Yes',
|
|
102
|
-
inactive: 'No',
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
type: 'toggle',
|
|
106
|
-
name: 'gitInit',
|
|
107
|
-
message: 'Do you want to generate an git repository?',
|
|
108
|
-
initial: 'true',
|
|
109
|
-
active: 'Yes',
|
|
110
|
-
inactive: 'No',
|
|
111
|
-
},
|
|
112
|
-
]
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const createApp = () => {
|
|
116
|
-
return new Promise(resolve => {
|
|
117
|
-
let config
|
|
118
|
-
sequence([
|
|
119
|
-
async () => {
|
|
120
|
-
const onCancel = () => {
|
|
121
|
-
process.exit()
|
|
122
|
-
}
|
|
123
|
-
config = await prompts(questions, { onCancel })
|
|
124
|
-
config.fixturesBase = fixturesBase
|
|
125
|
-
return config
|
|
126
|
-
},
|
|
127
|
-
() => {
|
|
128
|
-
spinnerMsg.start(`Generating new App "${config.appName}" ...`)
|
|
129
|
-
copyLightningFixtures(config).then(targetDir => (config.targetDir = targetDir))
|
|
130
|
-
spinnerMsg.succeed()
|
|
131
|
-
},
|
|
132
|
-
() => setAppData(config),
|
|
133
|
-
() => setBlitsVersion(config),
|
|
134
|
-
() => config.esLint && addESlint(config),
|
|
135
|
-
() => config.gitInit && gitInit(config.targetDir, config.fixturesBase),
|
|
136
|
-
() => done(config)
|
|
137
|
-
])
|
|
138
|
-
})
|
|
4
|
+
try {
|
|
5
|
+
execSync('npx --yes @lightningjs/create-blits@latest', { stdio: 'inherit' })
|
|
6
|
+
} catch (error) {
|
|
7
|
+
console.error('Error while creating new Lightning 3 Blits App', error)
|
|
8
|
+
process.exit(1)
|
|
139
9
|
}
|
|
140
|
-
|
|
141
|
-
createApp()
|
|
@@ -9,7 +9,7 @@ To get started with Blits, follow these simple steps to set up your development
|
|
|
9
9
|
2. Run the following command to start a new Blits Lightning 3 App project:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
|
|
12
|
+
npm create @lightningjs/app
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
You will be guided through a short series of questions to generate a new project with all the boilerplate code you need to start building your own Lightning 3 App.
|
package/docs/plugins/language.md
CHANGED
|
@@ -121,7 +121,7 @@ Blits.Component('MyComponent', {
|
|
|
121
121
|
|
|
122
122
|
## Getting the current language
|
|
123
123
|
|
|
124
|
-
The current language can be retrieved via the `this.$
|
|
124
|
+
The current language can be retrieved via the `this.$language.language` property. It will return the currently set language code.
|
|
125
125
|
|
|
126
126
|
## Translating
|
|
127
127
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -48,13 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@lightningjs/msdf-generator": "^1.0.2",
|
|
51
|
-
"@lightningjs/renderer": "^2.3.
|
|
52
|
-
"execa": "^8.0.1",
|
|
53
|
-
"kolorist": "^1.8.0",
|
|
54
|
-
"ora": "^7.0.1",
|
|
55
|
-
"prompts": "^2.4.2",
|
|
56
|
-
"replace-in-file": "^6.1.0",
|
|
57
|
-
"validate-npm-package-name": "^5.0.0"
|
|
51
|
+
"@lightningjs/renderer": "^2.3.2"
|
|
58
52
|
},
|
|
59
53
|
"repository": {
|
|
60
54
|
"type": "git",
|
|
@@ -20,6 +20,7 @@ import Focus from '../../focus.js'
|
|
|
20
20
|
import eventListeners from '../../lib/eventListeners.js'
|
|
21
21
|
import { trigger } from '../../lib/reactivity/effect.js'
|
|
22
22
|
import { Log } from '../../lib/log.js'
|
|
23
|
+
import { removeGlobalEffects } from '../../lib/reactivity/effect.js'
|
|
23
24
|
|
|
24
25
|
export default {
|
|
25
26
|
focus: {
|
|
@@ -56,6 +57,7 @@ export default {
|
|
|
56
57
|
this.$clearIntervals()
|
|
57
58
|
eventListeners.removeListeners(this)
|
|
58
59
|
deleteChildren(this[symbols.children])
|
|
60
|
+
removeGlobalEffects(this[symbols.effects])
|
|
59
61
|
Log.debug(`Destroyed component ${this.componentId}`)
|
|
60
62
|
},
|
|
61
63
|
writable: false,
|
package/src/component.js
CHANGED
|
@@ -161,9 +161,12 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
161
161
|
// reactive bindings define in the template
|
|
162
162
|
const effects = config.code.effects
|
|
163
163
|
for (let i = 0; i < effects.length; i++) {
|
|
164
|
-
|
|
164
|
+
const eff = () => {
|
|
165
165
|
effects[i](this, this[symbols.children], config, globalComponents, rootComponent, effect)
|
|
166
|
-
}
|
|
166
|
+
}
|
|
167
|
+
// store reference to the effect
|
|
168
|
+
this[symbols.effects].push(eff)
|
|
169
|
+
effect(eff)
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
// setup watchers if the components has watchers specified
|
|
@@ -356,6 +356,9 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
356
356
|
templateObject[Symbol.for('componentType')] === 'Slot' ||
|
|
357
357
|
templateObject[Symbol.for('componentType')] === 'Text'
|
|
358
358
|
) {
|
|
359
|
+
if (templateObject[Symbol.for('componentType')] === 'Text') {
|
|
360
|
+
templateObject.__textnode = 'true'
|
|
361
|
+
}
|
|
359
362
|
generateElementCode.call(ctx, templateObject, parent, {
|
|
360
363
|
key: 'scope.key',
|
|
361
364
|
component: 'scope.',
|
|
@@ -389,13 +392,15 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
389
392
|
}
|
|
390
393
|
|
|
391
394
|
// inner scope variables are part of the main forloop
|
|
392
|
-
innerScopeEffects.forEach((effect) => {
|
|
395
|
+
innerScopeEffects.forEach((effect, index) => {
|
|
393
396
|
const key = effect.indexOf(`scope.${index}`) > -1 ? `'${interpolate(result[2], '')}'` : null
|
|
394
397
|
if (effect.indexOf("Symbol.for('props')") === -1) {
|
|
395
398
|
ctx.renderCode.push(`
|
|
396
|
-
|
|
399
|
+
let eff${index} = () => {
|
|
397
400
|
${effect}
|
|
398
|
-
}
|
|
401
|
+
}
|
|
402
|
+
effect(eff${index}, ${key})
|
|
403
|
+
component[Symbol.for('effects')].push(eff${index})
|
|
399
404
|
`)
|
|
400
405
|
} else {
|
|
401
406
|
// props shouldn't be wrapped in an effect, but simply passed on
|
|
@@ -450,8 +455,11 @@ const generateForLoopCode = function (templateObject, parent) {
|
|
|
450
455
|
const match = matches[l]
|
|
451
456
|
const ref = `component.${match[2]}`
|
|
452
457
|
refs.indexOf(ref) === -1 && refs.push(ref)
|
|
453
|
-
effect
|
|
454
|
-
|
|
458
|
+
// don't update the effect to point to component, if we're referring to a scope item
|
|
459
|
+
if (match[2] !== item) {
|
|
460
|
+
effect =
|
|
461
|
+
effect.substring(0, match.index) + ref + effect.substring(match.index + match[1].length)
|
|
462
|
+
}
|
|
455
463
|
}
|
|
456
464
|
|
|
457
465
|
ctx.renderCode.push(`
|
|
@@ -29,8 +29,22 @@ export const resumeTracking = () => {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
const objectMap = new WeakMap()
|
|
32
|
+
const globalEffectsMap = new Map()
|
|
32
33
|
|
|
33
|
-
export const
|
|
34
|
+
export const removeGlobalEffects = (effectsToRemove) => {
|
|
35
|
+
if (globalEffectsMap.size === 0) return
|
|
36
|
+
for (const [effect, target] of globalEffectsMap) {
|
|
37
|
+
if (effectsToRemove.indexOf(effect) === -1) continue
|
|
38
|
+
const effectsSet = objectMap.get(target)
|
|
39
|
+
if (effectsSet === undefined) continue
|
|
40
|
+
for (const set of effectsSet.values()) {
|
|
41
|
+
set.delete(effect)
|
|
42
|
+
globalEffectsMap.delete(effect)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const track = (target, key, global = false) => {
|
|
34
48
|
if (currentEffect) {
|
|
35
49
|
if (paused) {
|
|
36
50
|
return
|
|
@@ -49,6 +63,8 @@ export const track = (target, key) => {
|
|
|
49
63
|
effectsMap.set(key, effects)
|
|
50
64
|
}
|
|
51
65
|
effects.add(currentEffect)
|
|
66
|
+
|
|
67
|
+
if (global === true) globalEffectsMap.set(currentEffect, target)
|
|
52
68
|
}
|
|
53
69
|
}
|
|
54
70
|
|
|
@@ -28,7 +28,7 @@ export const getRaw = (value) => {
|
|
|
28
28
|
return raw ? getRaw(raw) : value
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const reactiveProxy = (original, _parent = null, _key) => {
|
|
31
|
+
const reactiveProxy = (original, _parent = null, _key, global) => {
|
|
32
32
|
// don't create a proxy when a Blits component or an Image Texture
|
|
33
33
|
// is assigned to a state variable
|
|
34
34
|
if (typeof original === 'object') {
|
|
@@ -53,7 +53,7 @@ const reactiveProxy = (original, _parent = null, _key) => {
|
|
|
53
53
|
if (Array.isArray(target)) {
|
|
54
54
|
if (typeof target[key] === 'object' && target[key] !== null) {
|
|
55
55
|
if (Array.isArray(target[key])) {
|
|
56
|
-
track(target, key)
|
|
56
|
+
track(target, key, global)
|
|
57
57
|
}
|
|
58
58
|
// create a new reactive proxy
|
|
59
59
|
return reactiveProxy(getRaw(target[key]), target, key)
|
|
@@ -81,7 +81,7 @@ const reactiveProxy = (original, _parent = null, _key) => {
|
|
|
81
81
|
// handling objects (but not null values, which have object type in JS)
|
|
82
82
|
if (typeof target[key] === 'object' && target[key] !== null) {
|
|
83
83
|
if (Array.isArray(target[key])) {
|
|
84
|
-
track(target, key)
|
|
84
|
+
track(target, key, global)
|
|
85
85
|
}
|
|
86
86
|
// create a new reactive proxy
|
|
87
87
|
return reactiveProxy(getRaw(target[key]), target, key)
|
|
@@ -89,7 +89,7 @@ const reactiveProxy = (original, _parent = null, _key) => {
|
|
|
89
89
|
|
|
90
90
|
// handling all other types
|
|
91
91
|
// track the key on the target
|
|
92
|
-
track(target, key)
|
|
92
|
+
track(target, key, global)
|
|
93
93
|
// return the reflected value
|
|
94
94
|
return Reflect.get(target, key, receiver)
|
|
95
95
|
},
|
|
@@ -119,7 +119,7 @@ const reactiveProxy = (original, _parent = null, _key) => {
|
|
|
119
119
|
return proxy
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
const reactiveDefineProperty = (target) => {
|
|
122
|
+
const reactiveDefineProperty = (target, global) => {
|
|
123
123
|
Object.keys(target).forEach((key) => {
|
|
124
124
|
let internalValue = target[key]
|
|
125
125
|
|
|
@@ -140,7 +140,7 @@ const reactiveDefineProperty = (target) => {
|
|
|
140
140
|
enumerable: true,
|
|
141
141
|
configurable: true,
|
|
142
142
|
get() {
|
|
143
|
-
track(target, key)
|
|
143
|
+
track(target, key, global)
|
|
144
144
|
return internalValue
|
|
145
145
|
},
|
|
146
146
|
set(newValue) {
|
|
@@ -157,8 +157,10 @@ const reactiveDefineProperty = (target) => {
|
|
|
157
157
|
return target
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
export const reactive = (target, mode = 'Proxy') => {
|
|
161
|
-
return mode === 'defineProperty'
|
|
160
|
+
export const reactive = (target, mode = 'Proxy', global = false) => {
|
|
161
|
+
return mode === 'defineProperty'
|
|
162
|
+
? reactiveDefineProperty(target, global)
|
|
163
|
+
: reactiveProxy(target, undefined, undefined, global)
|
|
162
164
|
}
|
|
163
165
|
|
|
164
166
|
export const memo = (raw) => {
|
package/src/lib/symbols.js
CHANGED
package/src/plugin.js
CHANGED
package/src/plugins/appstate.js
CHANGED
package/src/plugins/language.js
CHANGED
package/src/plugins/log.js
CHANGED
package/src/plugins/theme.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* SPDX-License-Identifier: Apache-2.0
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import { Log } from '../lib/log'
|
|
18
|
+
import { Log } from '../lib/log.js'
|
|
19
19
|
import { reactive } from '../lib/reactivity/reactive.js'
|
|
20
20
|
|
|
21
21
|
import Settings from '../settings.js'
|
|
@@ -52,7 +52,8 @@ export default {
|
|
|
52
52
|
{
|
|
53
53
|
current: 'default',
|
|
54
54
|
},
|
|
55
|
-
Settings.get('reactivityMode')
|
|
55
|
+
Settings.get('reactivityMode'),
|
|
56
|
+
true
|
|
56
57
|
)
|
|
57
58
|
|
|
58
59
|
let themes = {}
|
package/bin/helpers.js
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { green, bold, red } from 'kolorist'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import { execa } from 'execa'
|
|
4
|
-
import fs from 'fs'
|
|
5
|
-
import replaceInFile from 'replace-in-file'
|
|
6
|
-
import ora from 'ora'
|
|
7
|
-
const spinner = ora()
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* This function copies Lightning fixtures to the target directory for creating a L3 application.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
export const copyLightningFixtures = (config) => {
|
|
14
|
-
return new Promise((resolve) => {
|
|
15
|
-
const targetDir = config.appFolder || ''
|
|
16
|
-
if (config.appFolder && fs.existsSync(targetDir)) {
|
|
17
|
-
exit(red(bold('The target directory ' + targetDir + ' already exists')))
|
|
18
|
-
}
|
|
19
|
-
//this will be removed once ts support is added
|
|
20
|
-
fs.cpSync(path.join(path.join(config.fixturesBase, 'js'), 'default'), targetDir, {
|
|
21
|
-
recursive: true,
|
|
22
|
-
})
|
|
23
|
-
fs.cpSync(path.join(config.fixturesBase, 'common/public'), path.join(targetDir, 'public'), {
|
|
24
|
-
recursive: true,
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
resolve(targetDir)
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* This function adds eslint related configuration to the project folder to be created
|
|
33
|
-
* @param config
|
|
34
|
-
* @returns {boolean}
|
|
35
|
-
*/
|
|
36
|
-
export const addESlint = (config) => {
|
|
37
|
-
// Make husky dir
|
|
38
|
-
fs.mkdirSync(path.join(config.targetDir, '.husky'), { recursive: true })
|
|
39
|
-
|
|
40
|
-
// Copy husky hook
|
|
41
|
-
fs.copyFileSync(
|
|
42
|
-
path.join(config.fixturesBase, 'common/eslint/husky/pre-commit'),
|
|
43
|
-
path.join(config.targetDir, '.husky/pre-commit')
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
// Copy editor config from common
|
|
47
|
-
fs.copyFileSync(
|
|
48
|
-
path.join(config.fixturesBase, 'common/eslint/.editorconfig'),
|
|
49
|
-
path.join(config.targetDir, '.editorconfig')
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
// Copy eslintignore from common
|
|
53
|
-
fs.copyFileSync(
|
|
54
|
-
path.join(config.fixturesBase, 'common/eslint/.eslintignore'),
|
|
55
|
-
path.join(config.targetDir, '.eslintignore')
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
// Copy eslintrc.js from fixtured specfic directory
|
|
59
|
-
fs.copyFileSync(
|
|
60
|
-
path.join(config.fixturesBase, 'common/eslint/.eslintrc.cjs'),
|
|
61
|
-
path.join(config.targetDir, '.eslintrc.cjs')
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
// Copy IDE stuff from fixture base
|
|
65
|
-
fs.cpSync(path.join(config.fixturesBase, 'common/ide'), path.join(config.targetDir), {
|
|
66
|
-
recursive: true,
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
// Copy and merge fixture specific package.json
|
|
70
|
-
const origPackageJson = JSON.parse(fs.readFileSync(path.join(config.targetDir, 'package.json')))
|
|
71
|
-
const eslintPackageJson = JSON.parse(
|
|
72
|
-
fs.readFileSync(path.join(config.fixturesBase, 'common/eslint/package.json'))
|
|
73
|
-
)
|
|
74
|
-
fs.writeFileSync(
|
|
75
|
-
path.join(config.targetDir, 'package.json'),
|
|
76
|
-
JSON.stringify(
|
|
77
|
-
{
|
|
78
|
-
...origPackageJson,
|
|
79
|
-
...eslintPackageJson,
|
|
80
|
-
devDependencies: {
|
|
81
|
-
...(origPackageJson.devDependencies || {}),
|
|
82
|
-
...(eslintPackageJson.devDependencies || {}),
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
null,
|
|
86
|
-
2
|
|
87
|
-
)
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
return true
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* This function sets the version by fetching the latest blits version
|
|
95
|
-
* @param config
|
|
96
|
-
* @returns {Promise<unknown>}
|
|
97
|
-
*/
|
|
98
|
-
export const setBlitsVersion = (config) => {
|
|
99
|
-
return new Promise((resolve, reject) => {
|
|
100
|
-
execa('npm', ['view', '@lightningjs/blits', 'version'])
|
|
101
|
-
.then(({ stdout }) => {
|
|
102
|
-
replaceInFile.sync({
|
|
103
|
-
files: config.targetDir + '/*',
|
|
104
|
-
from: /\{\$blitsVersion\}/g,
|
|
105
|
-
to: '^' + stdout,
|
|
106
|
-
})
|
|
107
|
-
resolve()
|
|
108
|
-
})
|
|
109
|
-
.catch((e) => {
|
|
110
|
-
spinnerMsg.fail(`Error occurred while setting blits version\n\n${e}`)
|
|
111
|
-
reject()
|
|
112
|
-
})
|
|
113
|
-
})
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Display a message and start a spinner with the specified message.
|
|
118
|
-
*
|
|
119
|
-
* @param {string} msg - The message to display while starting the spinner.
|
|
120
|
-
*/
|
|
121
|
-
export const spinnerMsg = {
|
|
122
|
-
start(msg) {
|
|
123
|
-
console.log(' ')
|
|
124
|
-
spinner.start(msg)
|
|
125
|
-
},
|
|
126
|
-
stop() {
|
|
127
|
-
spinner.stop()
|
|
128
|
-
},
|
|
129
|
-
succeed(msg) {
|
|
130
|
-
spinner.succeed(msg)
|
|
131
|
-
},
|
|
132
|
-
fail(msg) {
|
|
133
|
-
spinner.fail(msg)
|
|
134
|
-
console.log(' ')
|
|
135
|
-
},
|
|
136
|
-
warn(msg) {
|
|
137
|
-
spinner.warn(msg)
|
|
138
|
-
},
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* This function replaces placeholders like '{$appName}' and '{$appPackage}' in files within the target directory
|
|
143
|
-
* with the actual values from the configuration object.
|
|
144
|
-
*
|
|
145
|
-
* @param {Object} config - The configuration object containing application data.
|
|
146
|
-
*/
|
|
147
|
-
export const setAppData = (config) => {
|
|
148
|
-
replaceInFile.sync({
|
|
149
|
-
files: config.targetDir + '/*',
|
|
150
|
-
from: /\{\$appPackage\}/g,
|
|
151
|
-
to: config.appPackage,
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
replaceInFile.sync({
|
|
155
|
-
files: config.targetDir + '/*',
|
|
156
|
-
from: /\{\$appName\}/g,
|
|
157
|
-
to: config.appName,
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Display an error message and exit the program with an error status.
|
|
163
|
-
*
|
|
164
|
-
* @param {string} msg - The error message to display before exiting the program.
|
|
165
|
-
*/
|
|
166
|
-
export const exit = (msg) => {
|
|
167
|
-
spinnerMsg.fail(msg)
|
|
168
|
-
process.exit()
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Initialize an empty Git repository in the specified directory and copy a .gitignore file.
|
|
173
|
-
*
|
|
174
|
-
* @param {string} cwd - The current working directory where the Git repository will be created.
|
|
175
|
-
* @param {string} fixturesBase - The base directory for fixtures.
|
|
176
|
-
* @returns {Promise} A Promise that resolves when the Git initialization and file copying are completed successfully
|
|
177
|
-
*/
|
|
178
|
-
export const gitInit = (cwd, fixturesBase) => {
|
|
179
|
-
spinnerMsg.start('Initializing empty GIT repository')
|
|
180
|
-
let msg
|
|
181
|
-
return execa('git', ['init'], { cwd })
|
|
182
|
-
.then(({ stdout }) => (msg = stdout))
|
|
183
|
-
.then(() => {
|
|
184
|
-
return fs.copyFileSync(
|
|
185
|
-
path.join(fixturesBase, 'common/git/gitignore'),
|
|
186
|
-
path.join(cwd, '.gitignore')
|
|
187
|
-
)
|
|
188
|
-
})
|
|
189
|
-
.then(() => spinnerMsg.succeed(msg))
|
|
190
|
-
.catch((e) => spinnerMsg.fail(`Error occurred while creating git repository\n\n${e}`))
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Checks whether the give path is valid
|
|
195
|
-
* @param path
|
|
196
|
-
* @returns {boolean}
|
|
197
|
-
*/
|
|
198
|
-
export const isValidPath = (path) => {
|
|
199
|
-
try {
|
|
200
|
-
// Check if the path exists
|
|
201
|
-
fs.accessSync(path, fs.constants.F_OK)
|
|
202
|
-
return true
|
|
203
|
-
} catch (err) {
|
|
204
|
-
// The path does not exist or is not accessible
|
|
205
|
-
return false
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export const done = (config) => {
|
|
210
|
-
console.log('')
|
|
211
|
-
console.log('--------------------------------------------------------------------')
|
|
212
|
-
console.log(' Your new boilerplate Lightning 3 App has been created! ⚡️')
|
|
213
|
-
console.log('--------------------------------------------------------------------')
|
|
214
|
-
console.log('')
|
|
215
|
-
console.log('Follow the steps below to get started:')
|
|
216
|
-
console.log('')
|
|
217
|
-
console.log(` ${green(bold(`cd ${config.appFolder}`))}`)
|
|
218
|
-
console.log(` ${green(bold('npm install'))}`)
|
|
219
|
-
console.log(` ${green(bold('npm run dev'))}`)
|
|
220
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
root: true,
|
|
3
|
-
env: {
|
|
4
|
-
browser: true,
|
|
5
|
-
es6: true,
|
|
6
|
-
node: true,
|
|
7
|
-
},
|
|
8
|
-
plugins: ['prettier'],
|
|
9
|
-
extends: ['eslint:recommended', 'plugin:prettier/recommended', 'prettier'],
|
|
10
|
-
rules: {
|
|
11
|
-
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
|
12
|
-
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
|
13
|
-
quotes: [2, 'single', 'avoid-escape'],
|
|
14
|
-
semi: [2, 'never'],
|
|
15
|
-
'no-extra-boolean-cast': 'off',
|
|
16
|
-
'no-unused-vars': [
|
|
17
|
-
1,
|
|
18
|
-
{
|
|
19
|
-
argsIgnorePattern: 'res|next|^err',
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
'prettier/prettier': [
|
|
23
|
-
'error',
|
|
24
|
-
{
|
|
25
|
-
trailingComma: 'es5',
|
|
26
|
-
singleQuote: true,
|
|
27
|
-
tabWidth: 2,
|
|
28
|
-
semi: false,
|
|
29
|
-
printWidth: 100,
|
|
30
|
-
},
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
parserOptions: {
|
|
34
|
-
parser: 'babel-eslint',
|
|
35
|
-
ecmaVersion: 2020,
|
|
36
|
-
sourceType: 'module',
|
|
37
|
-
},
|
|
38
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"lint-staged": {
|
|
3
|
-
"*.js": [
|
|
4
|
-
"eslint --fix"
|
|
5
|
-
]
|
|
6
|
-
},
|
|
7
|
-
"husky": {
|
|
8
|
-
"hooks": {
|
|
9
|
-
"pre-commit": "lint-staged"
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
"devDependencies": {
|
|
13
|
-
"eslint": "^8.8.0",
|
|
14
|
-
"eslint-config-prettier": "^8.3.0",
|
|
15
|
-
"eslint-plugin-prettier": "^4.0.0",
|
|
16
|
-
"husky": "^7.0.4",
|
|
17
|
-
"lint-staged": "^12.3.3",
|
|
18
|
-
"prettier": "^2.5.1"
|
|
19
|
-
}
|
|
20
|
-
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{$appPackage}",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"description": "{$appName}",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"start": "npm run dev",
|
|
9
|
-
"lint": "eslint '**/*.js'",
|
|
10
|
-
"lint:fix": "eslint '**/*.js' --fix",
|
|
11
|
-
"build": "vite build",
|
|
12
|
-
"dev": "vite dev --host"
|
|
13
|
-
},
|
|
14
|
-
"lint-staged": {
|
|
15
|
-
"*.js": [
|
|
16
|
-
"eslint --fix"
|
|
17
|
-
]
|
|
18
|
-
},
|
|
19
|
-
"husky": {
|
|
20
|
-
"hooks": {
|
|
21
|
-
"pre-commit": "lint-staged"
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"eslint": "^8.8.0",
|
|
26
|
-
"eslint-config-prettier": "^8.3.0",
|
|
27
|
-
"eslint-plugin-prettier": "^4.0.0",
|
|
28
|
-
"husky": "^7.0.4",
|
|
29
|
-
"lint-staged": "^12.3.3",
|
|
30
|
-
"prettier": "^2.5.1",
|
|
31
|
-
"vite": "^4.0.4"
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"@lightningjs/blits": "{$blitsVersion}"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import Blits from '@lightningjs/blits'
|
|
2
|
-
|
|
3
|
-
export default Blits.Component('Loading', {
|
|
4
|
-
template: `
|
|
5
|
-
<Element>
|
|
6
|
-
<Circle size="40" color="#94a3b8" :alpha.transition="{value: $alpha, delay: 200}" />
|
|
7
|
-
<Circle size="40" color="#94a3b8" x="60" :alpha.transition="{value: $alpha, delay: 300}" />
|
|
8
|
-
<Circle size="40" color="#94a3b8" x="120" :alpha.transition="{value: $alpha, delay: 400}" />
|
|
9
|
-
</Element>
|
|
10
|
-
`,
|
|
11
|
-
state() {
|
|
12
|
-
return {
|
|
13
|
-
alpha: 0,
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
hooks: {
|
|
17
|
-
ready() {
|
|
18
|
-
this.$setInterval(() => {
|
|
19
|
-
this.alpha = this.alpha === 1 ? 0 : 1
|
|
20
|
-
}, 800)
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
})
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import Blits from '@lightningjs/blits'
|
|
2
|
-
import App from './App.js'
|
|
3
|
-
|
|
4
|
-
Blits.Launch(App, 'app', {
|
|
5
|
-
w: 1920,
|
|
6
|
-
h: 1080,
|
|
7
|
-
multithreaded: false,
|
|
8
|
-
debugLevel: 1,
|
|
9
|
-
defaultFont: 'lato',
|
|
10
|
-
fonts: [
|
|
11
|
-
{
|
|
12
|
-
family: 'lato',
|
|
13
|
-
type: 'msdf',
|
|
14
|
-
file: 'fonts/Lato-Regular.ttf',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
family: 'raleway',
|
|
18
|
-
type: 'msdf',
|
|
19
|
-
file: 'fonts/Raleway-ExtraBold.ttf',
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
family: 'opensans',
|
|
23
|
-
type: 'web',
|
|
24
|
-
file: 'fonts/OpenSans-Medium.ttf',
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
})
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import Blits from '@lightningjs/blits'
|
|
2
|
-
|
|
3
|
-
import Loader from '../components/Loader.js'
|
|
4
|
-
|
|
5
|
-
export default Blits.Component('Home', {
|
|
6
|
-
components: {
|
|
7
|
-
Loader,
|
|
8
|
-
},
|
|
9
|
-
template: `
|
|
10
|
-
<Element w="1920" h="1080" color="#1e293b">
|
|
11
|
-
<Element src="assets/logo.png" w="200" h="200" x="860" y="320" :effects="[$shader('radius', {radius: 12})]" />
|
|
12
|
-
<Loader x="880" y="600" />
|
|
13
|
-
</Element>
|
|
14
|
-
`,
|
|
15
|
-
})
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
2
|
-
|
|
3
|
-
import { defineConfig } from 'vite'
|
|
4
|
-
import blitsVitePlugins from '@lightningjs/blits/vite'
|
|
5
|
-
|
|
6
|
-
export default defineConfig(({ command, mode, ssrBuild }) => {
|
|
7
|
-
return {
|
|
8
|
-
base: '/', // Set to your base path if you are deploying to a subdirectory (example: /myApp/)
|
|
9
|
-
plugins: [...blitsVitePlugins],
|
|
10
|
-
resolve: {
|
|
11
|
-
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext'],
|
|
12
|
-
},
|
|
13
|
-
server: {
|
|
14
|
-
headers: {
|
|
15
|
-
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
16
|
-
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
17
|
-
},
|
|
18
|
-
fs: {
|
|
19
|
-
allow: ['..'],
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
worker: {
|
|
23
|
-
format: 'es',
|
|
24
|
-
},
|
|
25
|
-
}
|
|
26
|
-
})
|