Skip to content

Releases: hstd-dev/hstd

0.1.40 - Task

12 Aug 07:37

Choose a tag to compare

📝 Task

Self-resolvable Promise provides phase handling which triggered by user.

import { $, h as html, io, Task } from "hstd";


const Iterated = async function*() {

    const
        user = $(''),
        next = Task() // returns self-resolvable Promise.
    ;

    yield html`
        <label>Show user <input ${{ [io.value]: user }}/></label>
        <button ${{ [on.click]: () => next(user.$) }}>submit</button>
    `;

    const finalUser = await next();

    yield html`
        <label>Loading...</label>
    `;
    
    const { name, age, link } = await fetch(`/api/user/${finalUser}`).then(res => res.json());

    yield html`
        <div>
            <label>${name}</label>
            <label>${age}</label>
            <label>${link}</label>
        </div>
    `;

}

0.1.37 - Exposing Cores

03 Aug 20:18

Choose a tag to compare

⚙ Exposing Core Features

in 0.1.37, we added exports which contains some parts of hstd's core:

Pointer()

Module Pointer is the unwrapped edition of $.

import { $, Pointer } from "hstd";

const count = Pointer(0);
++count.$; // "1"

This module does not support some few features, such as producing pointer from template:

$`count is ${count}`; // "count is 1"
Pointer`count is ${count}`; // TypeError

and processing global property:

$.console.log(count); // show log from "count" changes
Pointer.console.log(count); // TypeError

...which is slightly faster than wrapped $.

Memo()

Module Memo uses Map or WeakMap to eliminate additional, unnecessary computation like React's useMemo().
this is used in various scene, from TemplateStringsArray validation layer to Pointer's binding strategy.

import { Memo } from "hstd";

const sum = Memo((input) => {
    console.log("computing...");
    return input + 1
});

sum(1); // returns "2"
// console: "computing..."
sum(1); // returns "2"
// nothing appears at console, which shows the callback was not executed.

the second arguments of Memo defines which method should be use between WeakMap or Map:

const resolveTemplate = Memo((template) => {

    console.log(`analyzing template... ${template.join("[value]")}`)
    const processedTemplate = // analyzing process continues...

    return (values) => processedTemplate(values);

}, true); // put "true" here when you want to use WeakMap for caching keys instead of Map.

const temp = (a, ...b) => resolveTemplate(a)(b);

const factory = () => temp`Hello world at ${performance.now()}`;

factory(); // returns: Hello world at 1187.437022
// console: "analyzing template... Hello world at [value]"

factory(); // returns: Hello world at 1196.921623
// nothing appears at console, which shows the first callback was not executed.

Prop()

Module Prop generates proxied stackable prop, which used in our on and css:

import { h as html, Prop } from "hstd";

const myStackable = Prop(
    (key) => (value, ref) => ref[key] = value;
);

document.body.append(...html`
    <video ${{ [myStackableProp.src]: "cat.webp" }}></video>
    <audio ${{
        [myStackableProp]: {
            src: "cat.opus"
        }
    }}></audio>
`)

0.1.31 - from()

27 Jul 11:10

Choose a tag to compare

import { $ } from 'hstd';

const $innerWidth = $(innerWidth).from(resolve => {
    addEventListener("resize", () => resolve(innerWidth), { passive: true })
});

$innerWidth.watch($ => console.log($)); // shows current innerWidth!

0.1.28 - Async Iterator Support

25 Jul 07:27

Choose a tag to compare

💫 Async Iterator Support

For customized complex fallbacks:

import { $, h as html } from "hstd";

async function* UserProfile(userId: string): AsyncGenerator<HSTDFragment> {

    const
        loadingDots: $<number> = $(0, $ => $ % 3),
        loadingDotsInterval: string = setInterval(() => loadingDots.$++, 700)
    ;

    yield html`
        <span>Loading${$`.`.repeat(loadingDots.into($ => $ + 1))}</span>
    `;
    
    const { name, age, link } = await fetch(`/api/user/${userId}`).then(res => res.json());

    clearInterval(loadingDotsInterval);

    yield html`
        <div>
            <label>${name}</label>
            <label>${age}</label>
            <label>${link}</label>
        </div>
    `;

}

document.body.append(...html`${UserProfile("ihasq")}`);

or write your own Suspense:

async function* Suspense({ fallback }, main) {
    yield* fallback;
    yield* await main;
}

document.body.append(...html`
    ${Suspense({ fallback: html`<label>Loading...</label>` },
        User({ id: "ihasq" })
    )}
`)

0.1.22

10 Jul 17:22

Choose a tag to compare

Added:

🦖 Asyncified - HyperStandard now supports Promise

async function WithFetch() {

    const { name, age, gender } = await fetch("/api/user/ihasq").then(res => res.json());
    return html`
        <h1>${name}</h1>
        <h2>Age: ${age}</h2>
        <h2>Gender: ${gender}</h2>
    `
}

document.body.append(...html`${WithFetch()}`) // without "await" !!

0.1.21

20 Jun 10:34

Choose a tag to compare

Changed:

  • Faster Style Declaration: Changed static style declaration method from CSSStyleDeclaration to <style>.