Skip to content

Commit

Permalink
Fixing aspect of reactivity and added optional computed tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianFun123 committed Sep 24, 2024
1 parent 0424228 commit 7781d5f
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 12 deletions.
26 changes: 25 additions & 1 deletion examples/jdom-template/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
import { $, state, computed, html } from '../../index.js';
import { $, $r, state, computed, html, JDOMComponent } from '../../index.js';

class Test2 extends JDOMComponent {
test = state('Test2')

constructor() {
super()
}
render() {
console.log(this.test)
return html`a: ${this.test}`
}
}
$r('test-app', Test2)

class Test {
image = state('Test1')
create(){
html`<${Test2} test=${this.image} /> <button @click=${() => this.image.value = 'OOO'}>OO</button>`.appendTo(document.body);
}
}

new Test().create()




const tasks = state([]);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jdomjs",
"version": "3.1.11",
"version": "3.1.12",
"description": "A wrapper for query selector and html elements",
"main": "./index.js",
"types": "./types/index.d.ts",
Expand Down
39 changes: 37 additions & 2 deletions src/Hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export default class Hook {
#destroyed = false
#alreadyProxied = false

static TRACKING = []
static IS_TRACKING = false


/**
* @param {T} value
*/
Expand Down Expand Up @@ -94,6 +98,7 @@ export default class Hook {
* @return {T}
*/
get value() {
Hook.track(this)
return this._value
}

Expand All @@ -104,8 +109,10 @@ export default class Hook {

dispatchListener(oldVal) {
for (let listener of this.listeners) {
if (listener.call(this, this._value, oldVal) === true)
break
try {
if (listener.call(this, this._value, oldVal) === true)
break
} catch (e) {}
}
}

Expand All @@ -128,4 +135,32 @@ export default class Hook {
toString() {
return `${this.value}`
}

/**
* @param {Hook} hook
*/
static track(hook) {
if (Hook.IS_TRACKING) {
Hook.TRACKING.push(hook)
}
}

static enableTracking() {
Hook.IS_TRACKING = true
}
static disableTracking() {
Hook.IS_TRACKING = false
Hook.clearTracked()
}

/**
* @return {Hook[]}
*/
static getTracked() {
return Hook.TRACKING
}

static clearTracked() {
Hook.TRACKING = []
}
}
2 changes: 1 addition & 1 deletion src/decorators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function State() {
}
}

export function Computed(dependencies: string[] | ((target: any) => Hook<any>[])) {
export function Computed(dependencies: string[] | ((target: any) => Hook[])) {
return function(target: any, key: string) {
const func = target[key];

Expand Down
26 changes: 20 additions & 6 deletions src/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,32 @@ export function state(initialValue) {
}

/**
* If dependencies is not given, the dependencies will be automatically seletected
*
* @template T
* @param {function(): T} callable
* @param {Hook[]} dependencies
* @param {Hook[]|undefined} dependencies
* @return {Hook<T>}
*/
export function computed(callable, dependencies = []) {
export function computed(callable, dependencies = undefined) {
const hook = new Hook(callable())

for (let dependency of dependencies) {
dependency.listeners.push(() => {
hook.value = callable()
})
if (dependencies === undefined) {
Hook.enableTracking()
callable()

for (const trackedElement of Hook.getTracked()) {
trackedElement.addListener(() => {
hook.value = callable()
})
}
Hook.disableTracking()
} else {
for (let dependency of dependencies) {
dependency.listeners.push(() => {
hook.value = callable()
})
}
}

return hook
Expand Down
8 changes: 7 additions & 1 deletion src/template/TemplateDOMAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,14 @@ export default class TemplateDOMAdapter {
if (usingJDOMComponent) {
if (key.endsWith('.attr')) {
elem.setAttribute(key.replace('.attr', ''), value)
} else if (key.endsWith('.unhook')) {
elem[key] = value
} else if (elem[key] instanceof Hook) {
elem[key].value = value
} else {
elem[key] = value
}
elem[key] = value

return
}
elem.setAttribute(key, value)
Expand Down

0 comments on commit 7781d5f

Please sign in to comment.