release: WRNexusJS 0.2.49

This commit is contained in:
2026-07-19 12:03:49 +05:30
parent 9ca1cc6b0f
commit 1cda2a01b3
2 changed files with 50 additions and 62 deletions
+10 -8
View File
@@ -881,7 +881,7 @@ component Accordion {
expect(output).not.toContain('${(isOpen(index)) ? " open" : ""}'); expect(output).not.toContain('${(isOpen(index)) ? " open" : ""}');
}); });
test("server-rendered each locals work in reactive handlers", () => { test("server-rendered each locals work in reactive handlers", async () => {
const firstLocals = Buffer.from( const firstLocals = Buffer.from(
JSON.stringify({ JSON.stringify({
item: { item: {
@@ -903,13 +903,12 @@ test("server-rendered each locals work in reactive handlers", () => {
).toString("base64"); ).toString("base64");
const dom = mountHtml(` const dom = mountHtml(`
<div <div data-scope="openIndex: -1">
data-scope="openIndex: -1"
>
<article <article
data-wrn-loop-locals="${firstLocals}" data-wrn-loop-locals="${firstLocals}"
> >
<button <button
type="button"
data-on-click="openIndex = index" data-on-click="openIndex = index"
> >
First First
@@ -924,6 +923,7 @@ test("server-rendered each locals work in reactive handlers", () => {
data-wrn-loop-locals="${secondLocals}" data-wrn-loop-locals="${secondLocals}"
> >
<button <button
type="button"
data-on-click="openIndex = index" data-on-click="openIndex = index"
> >
Second Second
@@ -936,13 +936,15 @@ test("server-rendered each locals work in reactive handlers", () => {
</div> </div>
`); `);
const buttons: any = dom.querySelectorAll("button"); const buttons = dom.querySelectorAll("button") as HTMLButtonElement[];
buttons[1].click(); buttons[1]!.click();
await Promise.resolve();
const articles = dom.querySelectorAll("article"); const articles = dom.querySelectorAll("article");
expect(articles[0].querySelector("span")?.classList.contains("open")).toBe(false); expect(articles[0]!.querySelector("span")?.classList.contains("open")).toBe(false);
expect(articles[1].querySelector("span")?.classList.contains("open")).toBe(true); expect(articles[1]!.querySelector("span")?.classList.contains("open")).toBe(true);
}); });
+40 -54
View File
@@ -214,59 +214,6 @@ export const REACTIVE_RUNTIME = String.raw`
var value = initial; var value = initial;
var subscribers = new Set(); var subscribers = new Set();
var notifying = false; var notifying = false;
var pendingNotification = false;
var pendingPrevious;
function notify(previous) {
if (notifying) {
pendingNotification = true;
if (pendingPrevious === undefined) {
pendingPrevious = previous;
}
return;
}
notifying = true;
try {
/*
* Iterate a snapshot. Reactive renderers may subscribe again while
* running, but that must not mutate the collection currently being
* iterated.
*/
var snapshot =
Array.from(subscribers);
snapshot.forEach(function (
subscriber,
) {
if (
subscribers.has(
subscriber,
)
) {
subscriber(
value,
previous,
);
}
});
} finally {
notifying = false;
}
if (pendingNotification) {
var nextPrevious =
pendingPrevious;
pendingNotification = false;
pendingPrevious = undefined;
notify(nextPrevious);
}
}
return { return {
get: function () { get: function () {
@@ -286,7 +233,46 @@ export const REACTIVE_RUNTIME = String.raw`
var previous = value; var previous = value;
value = nextValue; value = nextValue;
notify(previous); /*
* Prevent nested synchronous notification of the
* same signal.
*/
if (notifying) {
return;
}
notifying = true;
try {
/*
* Always iterate a snapshot. A renderer can read
* this signal and subscribe again while it runs.
*/
var snapshot =
Array.from(subscribers);
for (
var index = 0;
index < snapshot.length;
index++
) {
var subscriber =
snapshot[index];
if (
subscribers.has(
subscriber,
)
) {
subscriber(
value,
previous,
);
}
}
} finally {
notifying = false;
}
}, },
subscribe: function ( subscribe: function (