Skip to content

Commit

Permalink
Merge pull request #179 from lightning-js/dev
Browse files Browse the repository at this point in the history
Release 1.5.1
  • Loading branch information
michielvandergeest authored Oct 7, 2024
2 parents 4bb3093 + e26bc14 commit 598a069
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 42 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog


## v1.5.1

_7 oct 2024_

- Added export of symbols
- Various small performance improvements related to component creation

## v1.5.0

_1 oct 2024_
Expand Down
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.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"name": "@lightningjs/blits",
"version": "1.5.0",
"version": "1.5.1",
"description": "Blits: The Lightning 3 App Development Framework",
"bin": "bin/index.js",
"exports": {
".": "./index.js",
"./vite": "./vite/index.js",
"./transitions": "./src/router/transitions/index.js",
"./precompiler": "./src/lib/precompiler/precompiler.js",
"./plugins": "./src/plugins/index.js"
"./plugins": "./src/plugins/index.js",
"./symbols": "./src/lib/symbols.js"
},
"scripts": {
"test": "c8 npm run test:run",
Expand Down
47 changes: 20 additions & 27 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const required = (name) => {
*
*/
const Component = (name = required('name'), config = required('config')) => {
let base
let base = undefined

const component = function (opts, parentEl, parentComponent, rootComponent) {
// generate a human readable ID for the component instance (i.e. Blits::ComponentName1)
Expand Down Expand Up @@ -89,11 +89,10 @@ const Component = (name = required('name'), config = required('config')) => {

// apply the state function (passing in the this reference to utilize configured props)
// and store a reference to this original state
// hasFocus key is sprinkled in
this[symbols.originalState] = {
...((config.state && typeof config.state === 'function' && config.state.apply(this)) || {}),
...{ hasFocus: false },
}
this[symbols.originalState] =
(config.state && typeof config.state === 'function' && config.state.apply(this)) || {}
// add hasFocus key in
this[symbols.originalState]['hasFocus'] = false

// generate a reactive state (using the result of previously execute state function)
// and store it
Expand Down Expand Up @@ -162,20 +161,21 @@ 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++) {
// console.log(config.code.effects[i].toString())
effect(() => {
effects[i](this, this[symbols.children], config, globalComponents, rootComponent, effect)
})
}

// setup watchers if the components has watchers specified
if (this[symbols.watchers]) {
Object.keys(this[symbols.watchers]).forEach((watchKey) => {
const watcherkeys = Object.keys(this[symbols.watchers])
const watcherkeysLength = watcherkeys.length
for (let i = 0; i < watcherkeysLength; i++) {
let target = this
let key = watchKey
let key = watcherkeys[i]
// when dot notation used, find the nested target
if (watchKey.indexOf('.') > -1) {
const keys = watchKey.split('.')
if (key.indexOf('.') > -1) {
const keys = key.split('.')
key = keys.pop()
for (let i = 0; i < keys.length; i++) {
target = target[keys[i]]
Expand All @@ -187,23 +187,13 @@ const Component = (name = required('name'), config = required('config')) => {
effect((force = false) => {
const newValue = target[key]
if (old !== newValue || force === true) {
this[symbols.watchers][watchKey].apply(this, [newValue, old])
this[symbols.watchers][key].apply(this, [newValue, old])
old = newValue
}
})
})
}
}

// set all symbol based properties to non-enumerable and non-configurable
Object.getOwnPropertySymbols(this).forEach((property) => {
Object.defineProperties(this, {
[property]: {
enumerable: false,
configurable: false,
},
})
})

// finaly set the lifecycle state to ready (in the next tick)
setTimeout(() => (this.lifecycle.state = 'ready'))

Expand All @@ -214,7 +204,10 @@ const Component = (name = required('name'), config = required('config')) => {
const factory = (options = {}, parentEl, parentComponent, rootComponent) => {
if (Base[symbols['launched']] === false) {
// Register user defined plugins once on the Base object (after launch)
Object.keys(plugins).forEach((pluginName) => {
const pluginKeys = Object.keys(plugins)
const pluginKeysLength = pluginKeys.length
for (let i = 0; i < pluginKeysLength; i++) {
const pluginName = pluginKeys[i]
const prefixedPluginName = `$${pluginName}`
if (prefixedPluginName in Base) {
Log.warn(
Expand All @@ -231,7 +224,7 @@ const Component = (name = required('name'), config = required('config')) => {
enumerable: true,
configurable: false,
})
})
}

// register global components once
globalComponents = components()
Expand All @@ -241,13 +234,13 @@ const Component = (name = required('name'), config = required('config')) => {
}

// setup the component once per component type, using Base as the prototype
if (!base) {
if (base === undefined) {
Log.debug(`Setting up ${name} component`)
base = setupComponent(Object.create(Base), config)
}

// one time code generation (only if precompilation is turned off)
if (!config.code) {
if (config.code === undefined) {
Log.debug(`Generating code for ${name} component`)
config.code = codegenerator.call(config, parser(config.template, name))
}
Expand Down
13 changes: 8 additions & 5 deletions src/component/setup/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,23 @@ export default (component, props = []) => {
props.push('ref')
}
component[symbols.propKeys] = []
props.forEach((prop) => {
prop = { ...baseProp, ...(typeof prop === 'object' ? prop : { key: prop }) }

const propsLength = props.length

for (let i = 0; i < propsLength; i++) {
const prop = { ...baseProp, ...(typeof props[i] === 'object' ? props[i] : { key: props[i] }) }
component[symbols.propKeys].push(prop.key)
Object.defineProperty(component, prop.key, {
get() {
const value = prop.cast(
this[symbols.props] && prop.key in this[symbols.props]
this[symbols.props] !== undefined && prop.key in this[symbols.props]
? this[symbols.props][prop.key]
: 'default' in prop
? prop.default
: undefined
)

if (prop.required && value === undefined) {
if (prop.required === true && value === undefined) {
Log.warn(`${prop.key} is required`)
}

Expand All @@ -53,5 +56,5 @@ export default (component, props = []) => {
this[symbols.props][prop.key] = v
},
})
})
}
}
21 changes: 15 additions & 6 deletions src/component/setup/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,23 @@ export default (component, state = () => {}) => {
writable: false,
})

const stateKeys = Object.keys(state.apply(component) || {}).concat(['hasFocus'])
const stateKeys = Object.keys(state.apply(component) || {})
// add built-in hasFocus key
stateKeys.push(['hasFocus'])
const stateKeysLength = stateKeys.length

stateKeys.forEach((key) => {
if (component[symbols.propKeys] && component[symbols.propKeys].indexOf(key) > -1) {
for (let i = 0; i < stateKeysLength; i++) {
const key = stateKeys[i]
if (
component[symbols.propKeys] !== undefined &&
component[symbols.propKeys].indexOf(key) > -1
) {
Log.error(`State ${key} already exists as a prop`)
}
if (component[symbols.methodKeys] && component[symbols.methodKeys].indexOf(key) > -1) {
if (
component[symbols.methodKeys] !== undefined &&
component[symbols.methodKeys].indexOf(key) > -1
) {
Log.error(`State ${key} already exists as a method`)
}
component[symbols.stateKeys].push(key)
Expand All @@ -44,7 +54,6 @@ export default (component, state = () => {}) => {
set(v) {
this[symbols.state][key] = v
},
// enumerable: true,
})
})
}
}

0 comments on commit 598a069

Please sign in to comment.