UNPKG

@evolv/mutate

Version:

A library of standard DOM mutations by Evolv AI.

149 lines (107 loc) 4.35 kB
# Mutate Mutate is a library of helpers to maintain persistent modifications to the rendered DOM of a web page for implementation of temporary, experimental changes and features for rapid experimentation. It is intended to be framework independent and equally effective for SPAs and traditionally rendered webpages. ## Getting Set Up ### Installation ```shell $ npm install @evolv/mutate ``` ### Building From Source Clone the repository and run the following commands. ```shell $ npm install $ npm run build ``` ### Run Demo Website There is a demo site included. *Content warning: flashing lights* ```shell $ npm run demo ``` ## Getting Started The API for Mutate is similar in a lot of ways to the API of jQuery with a significant difference, that is selectors (`Collectors`) refer to all current and future matching `Element`s, and the functions to modify the DOM (`Mutations`) are persistent. This means that you don't need to worry about timing, or dynamic areas of the rendered page. Mutate also provides the ability to "project" `Element`s of the DOM into other `Element`s of the DOM, binding all interactions with the "projection" back to the original `Element`s. As everyone building variants have learned the hard way, most `Element`s are dependent on their location in the DOM for both style and functionality. Projection allows the implementer to "move" and restyle `Element`s without losing the position dependent functionality of the original `Element`s. ### Importing ```javascript import {collect, mutate} from '@evolv/mutate'; ``` ### Basic Usage The basic flow when using Mutate is to first define a Collector. ```javascript collect('<selector>', '<collector name>'); ``` Then to define a Mutator for the Collector. ```javascript mutate('<collector name>').hide(); ``` Mutators allow for Mutations to be chained together, similar to jQuery which will be evaluated in order of invocation. ```javascript mutate('<collector name>').text('<new text value>').classes({'<new class>': true}); ``` ### Loop Guard (Infinite Loop Protection) Mutate can detect runaway collectors (e.g. when a mutation keeps creating elements that re-trigger its own collector) and automatically pause the affected mutators. Enable and configure the loop guard at bootstrap time: ```javascript import { bootstrap } from '@evolv/mutate'; bootstrap({ loopGuard: { enabled: true, windowMs: 1000, // size of the observation window threshold: 10, // max collector events allowed within the window cooldownMs: 5000, // time to wait before the same collector can trigger again onDetect: (event) => { console.warn('Loop detected', event); }, }, }); ``` You can also toggle or reconfigure it at runtime through `collect.loopGuard`, either via the module export or the global `evolv.collect.loopGuard` once bootstrapped: ```javascript import { collect } from '@evolv/mutate'; collect.loopGuard.enable({ threshold: 3, windowMs: 500 }); // To disable again: evolv.collect.loopGuard.disable(); ``` Every detection dispatches a `evolv:mutate-loop-detected` `CustomEvent` so host applications can listen globally: ```javascript document.addEventListener('evolv:mutate-loop-detected', (event) => { console.log('Loop guard tripped', event.detail); }); ``` When the guard trips, the relevant collector is paused, and the active mutators are paused & reverted so the page remains responsive. > **Notes** > - The guard is disabled by default; enable it explicitly and tune `threshold`, `windowMs`, and `cooldownMs` (default `5000ms`) for your scenario. Starting with a higher threshold (default `10` events within `1000ms`) avoids flagging legitimate quick mutations such as `text()` + `styles()`. > - Built-in effects automatically revert, but custom mutations must provide a `revert` handler if you expect the guard to undo their DOM changes. #### How to test your changes 1. Run npm start 2. Create a simple website or use codesandbox 3. Add a snippet to head `<script src="http://localhost:8080/index.js"></script>` (make sure that your local is running on 8080, otherwise update src) 4. Apply changes to the website in the console ```javascript evolv.collect('h1', 'heading') evolv.mutate('heading').html('Test'); ``` ## Documentation [Mutate Documentation](https://evolv-ai.github.io/mutate)