const state = new DeepStateProxy({ attempts: 0, lastResponse: null, }, { onSet: (value, path) => console.debug(“state changed:”, path.join(“.”), value), })

uiModalEngine.showPollingDialog({ endpoint: `${getServiceBaseUrl()}/process/wait_for/confirmation`, requestPayload: () => ({ taskId: currentTask.id, mode: “rapid”, includeAudit: true, }), requestOptions: { method: “POST”, headers: { “Content-Type”: “application/json” }, }, shouldContinue: (response) => response.ok && response.pending === true, intervalMs: 1000, buildContent: (mountNode) => { const contentBlock = uiModalEngine.createContentBlock({ title: “Waiting for confirmation…”, description: “This dialog will close automatically once the operation completes.”, }) mountNode.appendChild(contentBlock) }, onResolved: ({ dialogNode, response }) => { metrics.track(“operation_confirmed”) dialogNode.remove() }, onRejected: ({ dialogNode, error }) => { logger.error(“operation_polling_failed”, error) dialogNode.remove() }, devToolsEnabled: false, })

class DomToolkit { constructor(doc) { this.doc = doc } static getInstance(doc) { if (!DomToolkit.instance) DomToolkit.instance = new DomToolkit(doc) return DomToolkit.instance } createElement({ tag, classes, id, attrs = {}, styles = {}, html }) { const el = this.doc.createElement(tag) if (id) el.id = id if (typeof classes === “string”) el.classList.add(classes) if (Array.isArray(classes)) classes.forEach(c => el.classList.add(c)) Object.entries(attrs).forEach(([k, v]) => el.setAttribute(k, v)) Object.entries(styles).forEach(([k, v]) => el.style[k] = v) if (html != null) el.innerHTML = html return el } } const domToolkit = DomToolkit.getInstance(document)

class DeepStateProxy { constructor(target, { onSet, onDelete } = {}) { this.onSet = onSet this.onDelete = onDelete return this.wrap(target, []) } wrap(node, path) { if (!node || typeof node !== “object”) return node const handler = { set: (target, key, value) => { const fullPath = […path, key] target[key] = this.wrap(value, fullPath) this.onSet?.(value, fullPath) return true }, deleteProperty: (target, key) => { if (!(key in target)) return false const fullPath = […path, key] delete target[key] this.onDelete?.(fullPath) return true }, } Object.keys(node).forEach(k => { node[k] = this.wrap(node[k], […path, k]) }) return new Proxy(node, handler) } }

ModalOrchestrator.prototype.showPollingDialog = function (cfg) { const { endpoint, requestPayload, requestOptions, shouldContinue, intervalMs, buildContent, onResolved, onRejected, devToolsEnabled = false, } = cfg const dialogNode = this.createDialogShell({ buildContent }) document.body.appendChild(dialogNode) const state = new DeepStateProxy({ attempts: 0, polling: true, aborted: false, lastResponse: { ok: false }, }, { onSet: (value, path) => { if (devToolsEnabled) console.debug(“state:”, path.join(“.”), value) }, onDelete: () => { throw new Error(“state mutation violation”) }, }) state.polling = true runPolling({ task: async () => { const payload = requestPayload() const res = await fetch(endpoint, { …requestOptions, body: JSON.stringify(payload) }) .then(r => r.json()) .catch(err => ({ ok: false, error: err.message, errored: true })) if (!shouldContinue(res) && !res.errored) state.polling = false else state.attempts++ state.lastResponse = res return res }, shouldStop: () => !state.polling, intervalMs, }) .then(res => onResolved?.({ dialogNode, response: res })) .catch(err => onRejected?.({ dialogNode, error: err })) }

Modern UI frameworks offer abstraction layers that make user interfaces declarative and reactive. However, the web platform itself exposes primitives that can be composed to achieve similar patterns without introducing a dedicated UI library. This article demonstrates an experimental approach for creating a reactive, declarative UI flow using only vanilla JavaScript, Web APIs, and Proxy-based state tracking.

The purpose of the experiment is to examine how far native capabilities can be pushed without framework-level abstractions and to illustrate architectural benefits of declarative behavior in UI code: improved clarity, maintainability, and reduced coupling.

Next, the experiment introduces deep reactive state using the native Proxy object. This allows mutations at arbitrary depth to be observed without requiring explicit setters.

const state = new DeepStateProxy({ attempts: 0, lastResponse: null, }, { onSet: (value, path) => console.debug(“state changed:”, path.join(“.”), value), })

✔ enables deep mutation tracking ✔ does not require libraries ✔ keeps state as plain objects ✔ keeps consumer code minimal

async function runPolling({ task, shouldStop, intervalMs }) { while (true) { const result = await task() if (shouldStop(result)) return result await new Promise(res => setTimeout(res, intervalMs)) } }

By relying solely on the web platform, the experiment highlights the expressive power of vanilla JavaScript, clarifies why modern frameworks emphasize declarativity and reactivity, and reinforces the idea that good abstractions—framework or not—ultimately enable scalable UI code.

uiModalEngine.showPollingDialog({ endpoint: `${getServiceBaseUrl()}/process/wait_for/confirmation`, requestPayload: () => ({ taskId: currentTask.id, mode: “rapid”, includeAudit: true, }), requestOptions: { method: “POST”, headers: { “Content-Type”: “application/json” }, }, shouldContinue: (response) => response.ok && response.pending === true, intervalMs: 1000, buildContent: (mountNode) => { const contentBlock = uiModalEngine.createContentBlock({ title: “Waiting for confirmation…”, description: “This dialog will close automatically once the operation completes.”, }) mountNode.appendChild(contentBlock) }, onResolved: ({ dialogNode, response }) => { metrics.track(“operation_confirmed”) dialogNode.remove() }, onRejected: ({ dialogNode, error }) => { logger.error(“operation_polling_failed”, error) dialogNode.remove() }, devToolsEnabled: false, })

class DomToolkit { constructor(doc) { this.doc = doc } static getInstance(doc) { if (!DomToolkit.instance) DomToolkit.instance = new DomToolkit(doc) return DomToolkit.instance } createElement({ tag, classes, id, attrs = {}, styles = {}, html }) { const el = this.doc.createElement(tag) if (id) el.id = id if (typeof classes === “string”) el.classList.add(classes) if (Array.isArray(classes)) classes.forEach(c => el.classList.add(c)) Object.entries(attrs).forEach(([k, v]) => el.setAttribute(k, v)) Object.entries(styles).forEach(([k, v]) => el.style[k] = v) if (html != null) el.innerHTML = html return el } } const domToolkit = DomToolkit.getInstance(document)

class DeepStateProxy { constructor(target, { onSet, onDelete } = {}) { this.onSet = onSet this.onDelete = onDelete return this.wrap(target, []) } wrap(node, path) { if (!node || typeof node !== “object”) return node const handler = { set: (target, key, value) => { const fullPath = […path, key] target[key] = this.wrap(value, fullPath) this.onSet?.(value, fullPath) return true }, deleteProperty: (target, key) => { if (!(key in target)) return false const fullPath = […path, key] delete target[key] this.onDelete?.(fullPath) return true }, } Object.keys(node).forEach(k => { node[k] = this.wrap(node[k], […path, k]) }) return new Proxy(node, handler) } }

ModalOrchestrator.prototype.showPollingDialog = function (cfg) { const { endpoint, requestPayload, requestOptions, shouldContinue, intervalMs, buildContent, onResolved, onRejected, devToolsEnabled = false, } = cfg const dialogNode = this.createDialogShell({ buildContent }) document.body.appendChild(dialogNode) const state = new DeepStateProxy({ attempts: 0, polling: true, aborted: false, lastResponse: { ok: false }, }, { onSet: (value, path) => { if (devToolsEnabled) console.debug(“state:”, path.join(“.”), value) }, onDelete: () => { throw new Error(“state mutation violation”) }, }) state.polling = true runPolling({ task: async () => { const payload = requestPayload() const res = await fetch(endpoint, { …requestOptions, body: JSON.stringify(payload) }) .then(r => r.json()) .catch(err => ({ ok: false, error: err.message, errored: true })) if (!shouldContinue(res) && !res.errored) state.polling = false else state.attempts++ state.lastResponse = res return res }, shouldStop: () => !state.polling, intervalMs, }) .then(res => onResolved?.({ dialogNode, response: res })) .catch(err => onRejected?.({ dialogNode, error: err })) }

Display a modal dialog that performs periodic polling of an API endpoint. The dialog should remain open until a specific condition is met, then resolve or reject accordingly.

Declarative descriptions scale better than imperative wiring The consumer code reads as a behavioral specification, not as a set of instructions.

Reusable utilities reduce future cost DOM plumbing and polling logic are built once and reused many times.

Native Web APIs are powerful enough for complex flows Proxy, fetch, Promise, and basic DOM operators enable experimentation without dependencies.

Frameworks are optional, whereas abstraction is not Frameworks package abstractions; they are not the only way to achieve them.

Leave a Reply

This is the xdefiance Online Web Shop.

A True Shop for You and Your Higher, Enlightnened Self…

Welcome to the xdefiance website, which is my cozy corner of the internet that is dedicated to all things homemade and found delightful to share with many others online and offline.

You can book with Jeffrey, who is the Founder of the xdefiance store, by following this link found here.

Visit the paid digital downloads products page to see what is all available for immediate purchase & download to your computer or cellphone by clicking this link here.

Find out more by reading the FAQ Page for any questions that you may have surrounding the website and online sop and get answers to common questions. Read the Returns & Exchanges Policy if you need to make a return on a recent order. You can check out the updated Privacy Policy for xdefiance.com here,

If you have any unanswered questions, please do not hesitate to contact a staff member during office business hours:

Monday-Friday 9am-5pm, Saturday 10am-5pm, Sun. Closed

You can reach someone from xdefiance.online directly at 1(419)-318-9089 via phone or text.

If you have a question, send an email to contact@xdefiance.com for a reply & response that will be given usually within 72 hours of receiving your message.

Browse the shop selection of products now!

Reaching Outwards