Declarative async checks for input values via HTML data-* attributes.
Bind an input, debounce, request an API, and reflect idle / pending / success / invalid / error onto the DOM. Styling is left to your CSS.
npm install @b4moss/existianimport { init } from "@b4moss/existian";
const handle = init();
// init({ prefix: "data-ex", root: document });
// handle.unbind(el); handle.refresh(); handle.destroy();CDN (after build / publish):
<script src="https://unpkg.com/@b4moss/existian/dist/existian.iife.min.js"></script>
<script>
Existian.init();
</script><input
type="text"
data-ex-check="/api/users/exists"
data-ex-debounce="300"
data-ex-timeout="5000"
data-ex-state="username"
data-ex-response-property="exists"
data-ex-response-value="false"
/>
<p data-ex-state="username"></p>
<script type="module">
import { init } from "@b4moss/existian";
init();
</script>[data-ex-status="pending"] { opacity: 0.6; }
[data-ex-status="success"] { outline: 2px solid green; }
[data-ex-status="invalid"] { outline: 2px solid red; }
[data-ex-status="error"] { outline: 2px solid purple; }| Attribute | Role |
|---|---|
data-ex-check |
Check URL (required to bind) |
data-ex-method |
HTTP method (default GET) |
data-ex-debounce |
Debounce ms (unset → 0) |
data-ex-timeout |
Request timeout ms (unset / negative → no timeout) |
data-ex-events |
Event names, space-separated (default input) |
data-ex-state |
Shared state name for status targets (document-wide) |
data-ex-pending |
Value written to data-ex-pending-active while pending |
data-ex-target |
CSS selector for an extra status target (querySelector) |
data-ex-response-property |
JSON property to judge |
data-ex-response-value |
Expected value (exact / regex) |
data-ex-response-match |
exact (default) or regex |
Status is written to data-ex-status. Errors also set data-ex-error (network / timeout / http:<code>, e.g. http:500).
GET/DELETE: queryvalue=<input>POST/PUT/PATCH: JSON body{"value":"<input>"}
const handle = init({
buildRequest: (ctx) => ({
init: {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: "Bearer …" },
body: JSON.stringify({ username: ctx.value, orgId: 1 }),
},
}),
// fetch: customFetch,
});
handle.refresh(); // bind newly added [data-ex-check] under root
handle.unbind(inputEl);
handle.destroy();No attribute template DSL — complex payloads stay in JS.
- Debounce before request
- At most one in-flight request per bound element (latest value queued)
- Stale responses ignored via generation id
- Timeout supported
- UI components / message copy / CSS frameworks
- Attribute template DSL / expression language
- Full form validation framework
Public smoke page: https://existian.oss.b4m.jp/
npm run build:doc-site
# serve doc-site/ (needs vendor/existian.iife.min.js from the build)Deploy: merge/push to the doc-site branch (GitHub Pages).
npm install
npm test
npm run build
npm run build:doc-siteDocs: docs/README.md · docs/roadmap.md · docs/index.md
- Delivery branch:
release(charter) - Publish: GitHub Release for
v*whose commit is onreleaseancestry (.github/workflows/publish.yml) - Requires repository secret
NPM_TOKEN
MIT