Releases: Claviz/drayman
v3.0.0
- Modified
forceUpdateto perform a deep equality check between the previously sent view and the new view. View updates are now only transmitted to the browser if actual changes are detected. - Added support for
heapLimit(by default 512 MB),externalLimit(by default 512 MB), andheartbeatLimitMs(by default 3000 ms). These parameters allow controlling resource consumption of component instances. - Introduced a heartbeat mechanism where component instances periodically report their status. The system now tracks the
lastHeartbeattimestamp and automatically terminates instances that become unresponsive (frozen) and fail to report within theheartbeatLimitMswindow. - Implemented continuous monitoring of V8 heap statistics (
used_heap_sizeandexternal_memory) via the heartbeat payload. Components exceeding their configuredheapLimitorexternalLimitare now terminated to prevent memory leaks from affecting the host system. - Created a global garbage collection system for
connectionsandcomponentInstances. This system tracks disconnected clients and destroyed instances, ensuring their resources (workers, event listeners) are properly released. - Enhanced graceful termination:
- Attempts to invoke
handleDestroyComponentInstanceon the worker thread to allow for custom cleanup logic. - If a worker is unresponsive, it is forcibly terminated after a timeout.
- All pending event requests are cancelled, and event listeners are unsubscribed.
- Emitting a
componentInstanceDestroyedevent to notify the client and other parts of the system.
- Attempts to invoke
- Improved error propagation within the event loop. Added try-catch blocks around event processing to prevent unhandled exceptions in component instances from crashing the main process.
- Optimized the
updatePropsfunction in the Virtual DOM patching process in@drayman/element. It now utilizes a customdeepEqualutility to compare new property values with existing ones. DOM updates are skipped if the properties are deeply equivalent, preventing unnecessary re-renders and DOM mutations. - Added a built-in visual overlay that displays "Component connection lost" when the WebSocket connection is closed or the component instance is destroyed.
- Updated
drayman.config.jsprocessing to accept and pass throughheapLimit,externalLimit, andheartbeatLimitMs. These settings are now propagated from the framework configuration down to the core component initialization logic.
v2.9.0
v2.8.0
v2.6.0
- You can now use any custom rule for
styleattribute, for example:
<div style={{ '--dynamic-bg-image': `url('')` }}></div>- Added
debounceforemitinbrowserCommands:
This option is useful, for example, when viewport of the browser was resized and you need to execute callback only after user has stopped resizing it:
public/index.html
...
<script>
initializeDraymanFramework({
browserCommands: (emit) => ({
events: async ({ onViewportChanged }) => {
window.onresize = () => {
emit(
onViewportChanged,
{
width: window.innerWidth,
height: window.innerHeight,
},
{
debounce: 500,
}
);
};
},
}),
});
</script>
...src/components/home.tsx
export const component: DraymanComponent<any> = async ({
Browser,
forceUpdate,
}) => {
let dimensions = ``;
Browser.events({
onViewportChanged: async (data) => {
dimensions = `${data.width}x${data.height}`;
await forceUpdate();
},
});
return () => {
return <div>{dimensions}</div>;
};
};In the example above, onViewportChanged callback will be executed and text of window dimensions will be updated only after user has stopped resizing browser window for 500ms.
- Server object can now be used to listen to events from EventHub or emit events to EventHub. This can be used when you want to communicate from server to all or specific components at once. You can read more about EventHub object here.
src/index.ts
export const Server: DraymanServer = async ({ EventHub }) => {
EventHub.on("my-event", (data) => {
console.log(data);
});
return {
sendEvent: async () => {
EventHub.emit("my-event", { hello: "world" });
},
};
};v2.5.0
Added Event Guards. This feature prevents unnecessary server requests when listening for specific events, such as keyboard shortcuts.
For example, you can now easily create a keyboard shortcut that only triggers a server-side action when a specific key combination is pressed. Check out the example in our docs to see how to implement an Event Guard for a keyboard event here.
v.2.4.0
It is now possible to pass an event to <drayman-element /> from client-side and it will be executed as expected.
Client HTML:
<body>
<drayman-element component="home"></drayman-element>
<script>
initializeDraymanFramework();
const draymanElement = document.getElementsByTagName('drayman-element')[0];
// Passing `onRootEvent` as an `option`:
draymanElement.options = {
onRootEvent: async ({ text }) => {
let el = document.createElement('div');
el.innerText = text;
document.body.appendChild(el);
}
};
</script>
</body>Server-side home.tsx component:
export const component: DraymanComponent<{ onRootEvent: any; }> = async ({ props }) => {
return () => {
return (
<button
onclick={async () => {
await props.onRootEvent({ text: `Nice!` });
}}
>Click!</button>
)
}
}v.2.3.0
- Added defaultProps.
v.2.1.0
v.2.0.0
- Error boundaries implementation - previously a parent component couldn't be rendered if some of the components in a component tree failed to initialise or render. Now a parent is rendered with problematic parts highlighted and descriptive error is shown.
- Console events (log, error, etc.) are now pretty-printed.
- Components are now transpiled with source maps. This allows to see exact line of the error inside a source code.
v.1.8.0
- It is possible now to create a middleware for requests via Server object.