Skip to main content
Glama
index.js3.05 kB
import { options } from 'preact'; /** * Setup a rerender function that will drain the queue of pending renders * @returns {() => void} */ export function setupRerender() { options.__test__previousDebounce = options.debounceRendering; options.debounceRendering = cb => (options.__test__drainQueue = cb); return () => options.__test__drainQueue && options.__test__drainQueue(); } const isThenable = value => value != null && typeof value.then == 'function'; /** Depth of nested calls to `act`. */ let actDepth = 0; /** * Run a test function, and flush all effects and rerenders after invoking it. * * Returns a Promise which resolves "immediately" if the callback is * synchronous or when the callback's result resolves if it is asynchronous. * * @param {() => void|Promise<void>} cb The function under test. This may be sync or async. * @return {Promise<void>} */ export function act(cb) { if (++actDepth > 1) { // If calls to `act` are nested, a flush happens only when the // outermost call returns. In the inner call, we just execute the // callback and return since the infrastructure for flushing has already // been set up. // // If an exception occurs, the outermost `act` will handle cleanup. try { const result = cb(); if (isThenable(result)) { return result.then( () => { --actDepth; }, e => { --actDepth; throw e; } ); } } catch (e) { --actDepth; throw e; } --actDepth; return Promise.resolve(); } const previousRequestAnimationFrame = options.requestAnimationFrame; const rerender = setupRerender(); /** @type {() => void} */ let flushes = [], toFlush; // Override requestAnimationFrame so we can flush pending hooks. options.requestAnimationFrame = fc => flushes.push(fc); const finish = () => { try { rerender(); while (flushes.length) { toFlush = flushes; flushes = []; toFlush.forEach(x => x()); rerender(); } } catch (e) { if (!err) { err = e; } } finally { teardown(); } options.requestAnimationFrame = previousRequestAnimationFrame; --actDepth; }; let err; let result; try { result = cb(); } catch (e) { err = e; } if (isThenable(result)) { return result.then(finish, err => { finish(); throw err; }); } // nb. If the callback is synchronous, effects must be flushed before // `act` returns, so that the caller does not have to await the result, // even though React recommends this. finish(); if (err) { throw err; } return Promise.resolve(); } /** * Teardown test environment and reset preact's internal state */ export function teardown() { if (options.__test__drainQueue) { // Flush any pending updates leftover by test options.__test__drainQueue(); delete options.__test__drainQueue; } if (typeof options.__test__previousDebounce != 'undefined') { options.debounceRendering = options.__test__previousDebounce; delete options.__test__previousDebounce; } else { options.debounceRendering = undefined; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sadiuysal/mem0-mcp-server-ts'

If you have feedback or need assistance with the MCP directory API, please join our Discord server