Skip to content

Commit

Permalink
Merge pull request #186 from lightning-js/dev
Browse files Browse the repository at this point in the history
Release 1.7.0
  • Loading branch information
michielvandergeest authored Oct 14, 2024
2 parents 533dec3 + 1903c68 commit 981b8ce
Show file tree
Hide file tree
Showing 22 changed files with 191 additions and 33 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v1.7.0

_14 oct 2024_

- Added cleanup upon component destroy of effects generated by global reactivity

## v1.6.0 / v1.6.1

_9 oct 2024_
Expand Down
Empty file modified bin/index.js
100644 → 100755
Empty file.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lightningjs/blits",
"version": "1.6.1",
"version": "1.7.0",
"description": "Blits: The Lightning 3 App Development Framework",
"bin": "bin/index.js",
"exports": {
Expand Down
8 changes: 8 additions & 0 deletions packages/create-blits/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## v1.0.1

_11 Oct 2024_

- Updated boilerplate with more advanced screen
- Added readme to boilerplate


## v1.0.0

_08 Oct 2024_
Expand Down
Empty file modified packages/create-blits/bin/index.js
100644 → 100755
Empty file.
49 changes: 49 additions & 0 deletions packages/create-blits/boilerplate/common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# {$appName}

### {$appPackage}


Welcome to the _{$appName}_ Lightning 3 Blits App!

### Getting started

Follow the steps below to get your Lightning 3 Blits App up and running in no time.

#### IDE setup

It is highly recommended to install the Blits [VS-code extension](https://marketplace.visualstudio.com/items?itemName=LightningJS.lightning-blits) which will give you template highlighting and improved autocompletion.

#### Project setup

Run the following command to install the dependencies of your App:

```sh
npm install
```

#### Build and run in development mode

Run your App in development mode:

```sh
npm run dev
```

This command uses Vite to fire up a local server, with Hot Reloading support. Visit the provided link in your web browser to see the App in action.

#### Build the App for production

Create an optimized and minified version of your App:

```sh
npm run build
```

This will create a production version of the app in the `dist` folder.


### Resources

- [Blits documentation](https://lightningjs.io/v3-docs/blits/getting_started/intro.html) - official documentation
- [Blits Example App](https://blits-demo.lightningjs.io/?source=true) - a great reference to learn by example
- [Blits Components](https://lightningjs.io/blits-components.html) - off-the-shelf, basic and performant reference components
2 changes: 1 addition & 1 deletion packages/create-blits/boilerplate/js/default/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export default Blits.Application({
<Element>
<RouterView />
</Element>
`,
`,
routes: [{ path: '/', component: Home }],
})
62 changes: 60 additions & 2 deletions packages/create-blits/boilerplate/js/default/src/pages/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,66 @@ export default Blits.Component('Home', {
},
template: `
<Element w="1920" h="1080" color="#1e293b">
<Element src="assets/logo.png" w="200" h="200" x="860" y="320" :effects="[$shader('radius', {radius: 12})]" />
<Loader x="880" y="600" />
<Element :y.transition="$y">
<Element
src="assets/logo.png"
w="200"
h="200"
:scale.transition="{value: $scale, duration: 500}"
:rotation.transition="{value: $rotation, duration: 800}"
:x.transition="{value: $x, delay: 200, duration: 1200, easing: 'cubic-bezier(1,-0.64,.39,1.44)'}"
mount="{x: 0.5}"
y="320"
:effects="[$shader('radius', {radius: 8})]"
/>
<Loader :x="1920 / 2" mount="{x: 0.5}" y="600" w="160" :alpha.transition="$loaderAlpha" />
<Element y="600" :alpha.transition="$textAlpha">
<Text size="80" align="center" wordwrap="1920">Hello!</Text>
<Text
size="50"
align="center"
y="120"
:x="1920/2"
wordwrap="500"
lineheight="64"
mount="{x: 0.5}"
color="#ffffffaa"
content="Let's get started with Lightning 3 & Blits"
/>
</Element>
</Element>
</Element>
`,
state() {
return {
y: 0,
x: -1000,
rotation: 0,
scale: 1,
loaderAlpha: 0,
textAlpha: 0.00001,
}
},
hooks: {
ready() {
this.loaderAlpha = 1
this.x = 1920 / 2

this.$setTimeout(() => {
this.rotation = 720
this.scale = 1.5
}, 3000)

this.$setTimeout(() => {
this.scale = 1
}, 3000 + 300)

this.$setTimeout(() => {
this.y = -60
this.loaderAlpha = 0
this.scale = 1
this.textAlpha = 1
}, 3800)
},
},
})
4 changes: 2 additions & 2 deletions packages/create-blits/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/create-blits/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lightningjs/create-blits",
"version": "1.0.0",
"version": "1.1.0",
"description": "Create a new Lightning 3 Blits App",
"bin": "bin/index.js",
"scripts": {
Expand Down
20 changes: 13 additions & 7 deletions packages/create-blits/src/helpers/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ export const copyLightningFixtures = (config) => {
recursive: true,
})

// Copy readme
fs.copyFileSync(
path.join(config.fixturesBase, 'common/README.md'),
path.join(targetDir, 'README.md')
)

// Copy IDE stuff from fixture base
fs.cpSync(path.join(config.fixturesBase, 'common/ide'), path.join(targetDir), {
recursive: true,
})

resolve(targetDir)
})
}
Expand Down Expand Up @@ -55,11 +66,6 @@ export const addESlint = (config) => {
path.join(config.targetDir, 'eslint.config.cjs')
)

// Copy IDE stuff from fixture base
fs.cpSync(path.join(config.fixturesBase, 'common/ide'), path.join(config.targetDir), {
recursive: true,
})

// Copy and merge fixture specific package.json
const origPackageJson = JSON.parse(fs.readFileSync(path.join(config.targetDir, 'package.json')))
const eslintPackageJson = JSON.parse(
Expand All @@ -77,8 +83,8 @@ export const addESlint = (config) => {
},
scripts: {
...(origPackageJson.scripts || {}),
...(eslintPackageJson.scripts || {})
}
...(eslintPackageJson.scripts || {}),
},
},
null,
2
Expand Down
7 changes: 5 additions & 2 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,12 @@ const Component = (name = required('name'), config = required('config')) => {
// reactive bindings define in the template
const effects = config.code.effects
for (let i = 0; i < effects.length; i++) {
effect(() => {
const eff = () => {
effects[i](this, this[symbols.children], config, globalComponents, rootComponent, effect)
})
}
// store reference to the effect
this[symbols.effects].push(eff)
effect(eff)
}

// setup watchers if the components has watchers specified
Expand Down
2 changes: 2 additions & 0 deletions src/component/base/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Focus from '../../focus.js'
import eventListeners from '../../lib/eventListeners.js'
import { trigger } from '../../lib/reactivity/effect.js'
import { Log } from '../../lib/log.js'
import { removeGlobalEffects } from '../../lib/reactivity/effect.js'

export default {
focus: {
Expand Down Expand Up @@ -56,6 +57,7 @@ export default {
this.$clearIntervals()
eventListeners.removeListeners(this)
deleteChildren(this[symbols.children])
removeGlobalEffects(this[symbols.effects])
Log.debug(`Destroyed component ${this.componentId}`)
},
writable: false,
Expand Down
2 changes: 2 additions & 0 deletions src/component/setup/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ let counter = 0
export default function (component, config) {
component[symbols.identifier] = ++counter

component[symbols.effects] = []

// setup hooks
registerHooks(config.hooks, component[symbols.identifier])

Expand Down
8 changes: 5 additions & 3 deletions src/lib/codegenerator/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,15 @@ const generateForLoopCode = function (templateObject, parent) {
}

// inner scope variables are part of the main forloop
innerScopeEffects.forEach((effect) => {
innerScopeEffects.forEach((effect, index) => {
const key = effect.indexOf(`scope.${index}`) > -1 ? `'${interpolate(result[2], '')}'` : null
if (effect.indexOf("Symbol.for('props')") === -1) {
ctx.renderCode.push(`
effect(() => {
let eff${index} = () => {
${effect}
}, ${key})
}
effect(eff${index}, ${key})
component[Symbol.for('effects')].push(eff${index})
`)
} else {
// props shouldn't be wrapped in an effect, but simply passed on
Expand Down
18 changes: 17 additions & 1 deletion src/lib/reactivity/effect.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,22 @@ export const resumeTracking = () => {
}

const objectMap = new WeakMap()
const globalEffectsMap = new Map()

export const track = (target, key) => {
export const removeGlobalEffects = (effectsToRemove) => {
if (globalEffectsMap.size === 0) return
for (const [effect, target] of globalEffectsMap) {
if (effectsToRemove.indexOf(effect) === -1) continue
const effectsSet = objectMap.get(target)
if (effectsSet === undefined) continue
for (const set of effectsSet.values()) {
set.delete(effect)
globalEffectsMap.delete(effect)
}
}
}

export const track = (target, key, global = false) => {
if (currentEffect) {
if (paused) {
return
Expand All @@ -49,6 +63,8 @@ export const track = (target, key) => {
effectsMap.set(key, effects)
}
effects.add(currentEffect)

if (global === true) globalEffectsMap.set(currentEffect, target)
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/lib/reactivity/reactive.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const getRaw = (value) => {
return raw ? getRaw(raw) : value
}

const reactiveProxy = (original, _parent = null, _key) => {
const reactiveProxy = (original, _parent = null, _key, global) => {
// don't create a proxy when a Blits component or an Image Texture
// is assigned to a state variable
if (typeof original === 'object') {
Expand All @@ -53,7 +53,7 @@ const reactiveProxy = (original, _parent = null, _key) => {
if (Array.isArray(target)) {
if (typeof target[key] === 'object' && target[key] !== null) {
if (Array.isArray(target[key])) {
track(target, key)
track(target, key, global)
}
// create a new reactive proxy
return reactiveProxy(getRaw(target[key]), target, key)
Expand Down Expand Up @@ -81,15 +81,15 @@ const reactiveProxy = (original, _parent = null, _key) => {
// handling objects (but not null values, which have object type in JS)
if (typeof target[key] === 'object' && target[key] !== null) {
if (Array.isArray(target[key])) {
track(target, key)
track(target, key, global)
}
// create a new reactive proxy
return reactiveProxy(getRaw(target[key]), target, key)
}

// handling all other types
// track the key on the target
track(target, key)
track(target, key, global)
// return the reflected value
return Reflect.get(target, key, receiver)
},
Expand Down Expand Up @@ -119,7 +119,7 @@ const reactiveProxy = (original, _parent = null, _key) => {
return proxy
}

const reactiveDefineProperty = (target) => {
const reactiveDefineProperty = (target, global) => {
Object.keys(target).forEach((key) => {
let internalValue = target[key]

Expand All @@ -140,7 +140,7 @@ const reactiveDefineProperty = (target) => {
enumerable: true,
configurable: true,
get() {
track(target, key)
track(target, key, global)
return internalValue
},
set(newValue) {
Expand All @@ -157,8 +157,10 @@ const reactiveDefineProperty = (target) => {
return target
}

export const reactive = (target, mode = 'Proxy') => {
return mode === 'defineProperty' ? reactiveDefineProperty(target) : reactiveProxy(target)
export const reactive = (target, mode = 'Proxy', global = false) => {
return mode === 'defineProperty'
? reactiveDefineProperty(target, global)
: reactiveProxy(target, undefined, undefined, global)
}

export const memo = (raw) => {
Expand Down
Loading

0 comments on commit 981b8ce

Please sign in to comment.