DrSensor / DrSensor/nusa

Infer value

Open
#3 1 comment 0 reactions 0 assignees View on GitHub
data binding decorator enhancement
Dominant language
JavaScript
Stars
4
Forks
0
PR merge metrics
No merged PRs in 30d

Description

> **Warning**: beware of #45

## Infer from html

Infer the value only when:
* the value is defined in the html file in form of an attribute, and
* ~~property is specified but undefined~~ accessor is defined without initial value, or
* it override accessor initial value if:
* bound using `infer:` attribute, or
* marked with `@infer` decorator, or
* use `@infer(Class)` with `{ force: true }`

```ts
/// script.ts -> script.js
export default class Global {
// static count: number
// count: number
static accessor count: number
accessor count = 0
increment() {
Global.count++
this.count++
}
}
```
```html





```
```js
import { page } from "test:page.html"

const scope = page.$$('render-scope')
, [ increment_button1
, increment_button2 ] = scope.map(it => it.$("button"))
, [ static_input1
, input1 ] = scope[0].$$('input[type="button"]')
, [ static_input2
, input2 ] = scope[1].$$('input[type="button"]')

assert(static_input1.value === "1")
assert(input1.value === "1")

assert(static_input2.value === "4")
assert(input2.value === "4")

increment_button1.click()

assert(static_input1.value === "2")
assert(input1.value === "2")

assert(static_input2.value === "2")
assert(input2.value === "4") // no change

page.reload() ////////////////////////

assert(static_input1.value === "1")
assert(input1.value === "1")

assert(static_input2.value === "4")
assert(input2.value === "4")

increment_button2.click()

assert(static_input1.value === "5")
assert(input1.value === "1") // no change

assert(static_input2.value === "5")
assert(input2.value === "5")
```

### attribute value from literal value

Parse bind attribute value as literal value if surrounded by backtick then set real attribute value from that literal value when module ready.

```html


click

```

## Infer on set
```d.ts
function infer(
$1: Container,
$2?: (
this?: Container,
value: assignment,
) => typeof this extends undefined ? assignment : void,
);
```
> 🔀 **Behaviour**
> 1. if second argument is defined then call that argument on every assignment
> 2. if that argument is arrow function then either instantiate or call the Container while passing the return value of that arrow function to the Container arguments (use following last logic on how to treat the return value)
> ---
> 1. if `"constructor" in @infer(Container)` then instantiate the Container on every assignment (assume it as a class)
> 2. else just call the Container on every assignment (assume it as arrow function)
> ---
> 1. if `Symbol.toPrimitive in assignedValue` then treat the return value of Symbol.toPrimitive() as assignedValue before being used as Container arguments (recursive check)
> 2. else if `Symbol.iterable in assignedValue` then spread the assignedValue as Container arguments

```ts
export default class {
@infer(Vector3) accessor position: Vector3 | [x: number, y: number, z: number]

@infer(Date) accessor tick: Date | number

move(e: MouseEvent) {
this.tick = -performance.now()

const [x, y, z] = raycast(e)
this.position = [-x, -y, z] // or
// this.position = new Vector3(-x, -y, z)
this.position.normalize()

this.tick += performance.now()
console.debug(this.tick.getSeconds())
}
}
```

> **Note** `@infer` decorator can also be used to infer value from html as non-primitive value.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.