release: WRNexusJS 0.6.0

This commit is contained in:
2026-08-01 01:09:58 +05:30
parent 3e565e8d03
commit 687d345882
502 changed files with 33038 additions and 11358 deletions
+147 -2
View File
@@ -24,6 +24,7 @@ export const REACTIVE_RUNTIME = String.raw`
var pendingUpdateHooks = new Map();
var updateHooksScheduled = false;
var behaviorObserver;
var clientModuleCache = new Map();
function reportDiagnostic(code, message, element, detail) {
var payload = {
@@ -478,6 +479,21 @@ export const REACTIVE_RUNTIME = String.raw`
}
}
function loadClientModule(element) {
var url = element.getAttribute("data-wrn-client-module");
if (!url) return Promise.resolve(null);
var promise = clientModuleCache.get(url);
if (!promise) {
promise = import(url).catch(function (error) {
clientModuleCache.delete(url);
reportDiagnostic("WRN-CLIENT-MODULE", "Failed to load browser function module '" + url + "'.", element, error);
return null;
});
clientModuleCache.set(url, promise);
}
return promise;
}
function setupScope(el) {
if (el.__wrnexusScope) return;
@@ -677,13 +693,39 @@ export const REACTIVE_RUNTIME = String.raw`
}
var behaviorFunctions = {};
var componentEventTarget = el.querySelector("[data-wrn-events]") || el;
var moduleBindings = {};
var componentEventTarget = el.hasAttribute("data-wrn-events")
? el
: el.querySelector("[data-wrn-events]") || el;
var declaredEvents = new Set(
String(componentEventTarget.getAttribute("data-wrn-events") || "")
.split(",")
.map(function (name) { return name.trim(); })
.filter(Boolean),
);
var outputHandlers = componentEventTarget.__wrnexusOutputHandlers || (componentEventTarget.__wrnexusOutputHandlers = {});
var outputProxy = new Proxy({}, {
get: function (_target, property) {
return function (payload) {
return invokeComponentOutput(componentEventTarget, String(property), payload);
};
},
});
var componentRpcName = componentEventTarget.getAttribute("data-wrn-component") || componentEventTarget.getAttribute("data-wrn-hydration") || "component";
var serverProxy = new Proxy({}, {
get: function (_target, property) {
return function () {
return callServerFunction(componentRpcName, String(property), Array.prototype.slice.call(arguments));
};
},
});
var propsProxy = new Proxy({}, {
get: function (_target, property) { return peekScope(String(property)); },
set: function () { throw new TypeError("WRN-PROP-READONLY: props are readonly"); },
});
var refsProxy = new Proxy({}, {
get: function (_target, property) { return el.querySelector('[data-ref="' + String(property).replace(/"/g, '\"') + '"]'); },
});
var stateWatchers = {};
var anyStateListeners = new Set();
var cleanupCallbacks = [];
@@ -695,6 +737,11 @@ export const REACTIVE_RUNTIME = String.raw`
return dispatchComponentEvent(componentEventTarget, name, detail);
};
}
if (name === "output") return outputProxy;
if (name === "server") return serverProxy;
if (name === "props") return propsProxy;
if (name === "refs") return refsProxy;
if (Object.prototype.hasOwnProperty.call(moduleBindings, name)) return moduleBindings[name];
if (name === "$emit") {
return function (eventName, detail) {
return dispatchComponentEvent(componentEventTarget, eventName, detail);
@@ -919,6 +966,42 @@ export const REACTIVE_RUNTIME = String.raw`
});
}
function installClientModule(module) {
if (!module) return;
var stateProxy = new Proxy({}, {
get: function (_target, property) { return readScope(String(property)); },
set: function (_target, property, value) { writeScope(String(property), value); return true; },
ownKeys: function () { return Object.keys(signals); },
getOwnPropertyDescriptor: function () { return { enumerable: true, configurable: true }; },
});
var context = {
state: stateProxy,
output: outputProxy,
server: serverProxy,
props: propsProxy,
refs: refsProxy,
};
var importedBindings = module.__wrnexusImportedBindings;
if (importedBindings && typeof importedBindings === "object") {
Object.keys(importedBindings).forEach(function (name) {
var binding = importedBindings[name];
moduleBindings[name] = binding;
if (binding && typeof binding.subscribe === "function") {
cleanupCallbacks.push(binding.subscribe(function () { renderAll(); }));
}
});
}
var functions = typeof module.bindClientScope === "function"
? module.bindClientScope(context)
: module.__wrnexusClientFunctions;
if (!functions || typeof functions !== "object") return;
Object.keys(functions).forEach(function (name) {
if (typeof functions[name] === "function") behaviorFunctions[name] = functions[name];
});
}
installClientModule(el.__wrnexusClientModule);
// A binding belongs to THIS scope only when el is the node's nearest
// [data-scope] ancestor. Otherwise a nested scope owns it and we skip it,
// so an outer scope never clobbers an inner one's values.
@@ -1233,6 +1316,7 @@ export const REACTIVE_RUNTIME = String.raw`
eventLocals.event = event;
eventLocals.$event = event;
eventLocals.payload = event && Object.prototype.hasOwnProperty.call(event, "detail") ? event.detail : undefined;
try {
runStmt(
@@ -1773,6 +1857,7 @@ export const REACTIVE_RUNTIME = String.raw`
locals.event = event;
locals.$event = event;
locals.payload = event && Object.prototype.hasOwnProperty.call(event, "detail") ? event.detail : undefined;
try {
runStmt(
@@ -1794,6 +1879,19 @@ export const REACTIVE_RUNTIME = String.raw`
? { passive: true }
: undefined;
if (target === componentEventTarget && declaredEvents.has(evt)) {
var directHandler = function (payload) {
var locals = decodeLoopLocals(node);
locals.payload = payload;
locals.event = undefined;
locals.$event = undefined;
return runStmt(stmt, locals);
};
(outputHandlers[evt] || (outputHandlers[evt] = new Set())).add(directHandler);
cleanupCallbacks.push(function () {
if (outputHandlers[evt]) outputHandlers[evt].delete(directHandler);
});
}
target.addEventListener(evt, listener, options);
cleanupCallbacks.push(function () {
target.removeEventListener(evt, listener, options);
@@ -1932,7 +2030,16 @@ export const REACTIVE_RUNTIME = String.raw`
function hydrate() {
if (element.__wrnexusScope || !element.isConnected) return;
setupScope(element);
var moduleUrl = element.getAttribute("data-wrn-client-module");
if (!moduleUrl || moduleUrl === "__WRNEXUS_CLIENT_MODULE__") {
setupScope(element);
return;
}
loadClientModule(element).then(function (module) {
if (element.__wrnexusScope || !element.isConnected) return;
element.__wrnexusClientModule = module;
setupScope(element);
});
}
if (strategy === "load") {
@@ -2616,6 +2723,43 @@ export const REACTIVE_RUNTIME = String.raw`
}
}
function invokeComponentOutput(root, name, payload) {
if (!root || !name) return undefined;
var registry = root.__wrnexusOutputHandlers;
var handlers = registry && registry[name];
if (handlers && handlers.size) {
var values = [];
handlers.forEach(function (handler) { values.push(handler(payload)); });
return values.some(function (value) { return value && typeof value.then === "function"; })
? Promise.all(values)
: values[values.length - 1];
}
return dispatchComponentEvent(root, name, payload);
}
function callServerFunction(component, functionName, args) {
var csrf = document.querySelector('meta[name="wrnexus-csrf"]');
return fetch("/__wrnexus/rpc", {
method: "POST",
credentials: "same-origin",
headers: {
"content-type": "application/json",
"x-wrnexus-csrf": csrf ? csrf.getAttribute("content") || "" : "",
},
body: JSON.stringify({ component: component, function: functionName, args: args || [] }),
}).then(function (response) {
return response.json().catch(function () { return null; }).then(function (payload) {
if (!response.ok || !payload || !payload.ok) {
var error = new Error(payload && payload.error && payload.error.message || "Server function call failed");
error.code = payload && payload.error && payload.error.code || "WRN-RPC-FAILED";
error.status = response.status;
throw error;
}
return payload.value;
});
});
}
function dispatchComponentEvent(root, name, detail) {
if (!root || !name) return null;
var EventConstructor =
@@ -3789,6 +3933,7 @@ export const REACTIVE_RUNTIME = String.raw`
}
window.__wrnexusHydrateScopes = hydrateScopes;
window.__wrnexusInvalidateClientModule = function (url) { clientModuleCache.delete(url); };
window.__wrnexusHydrateCsrFetches = hydrateCsrFetches;
window.__wrnexusDisposeBehaviors = disposeBehaviors;
if (document.readyState === "loading") {