voodoojs 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +77 -0
  2. package/dist/chunk-234ZLC6W.js +401 -0
  3. package/dist/chunk-4HQEOXTK.js +10271 -0
  4. package/dist/chunk-5777LJVW.js +64 -0
  5. package/dist/chunk-5CKGDARU.js +1845 -0
  6. package/dist/chunk-A2UOVQBP.js +82 -0
  7. package/dist/chunk-E27NRARW.js +16 -0
  8. package/dist/chunk-JZIYRIY6.js +1196 -0
  9. package/dist/chunk-NNU6WOOU.js +641 -0
  10. package/dist/chunk-PQZEVFVZ.js +448 -0
  11. package/dist/chunk-RJUNPXQF.js +946 -0
  12. package/dist/chunk-U76IRJKH.js +72 -0
  13. package/dist/essential.cjs +13889 -0
  14. package/dist/essential.d.cts +24 -0
  15. package/dist/essential.d.ts +24 -0
  16. package/dist/essential.js +51 -0
  17. package/dist/gpu.cjs +2008 -0
  18. package/dist/gpu.d.cts +68 -0
  19. package/dist/gpu.d.ts +68 -0
  20. package/dist/gpu.js +273 -0
  21. package/dist/http.cjs +467 -0
  22. package/dist/http.d.cts +148 -0
  23. package/dist/http.d.ts +148 -0
  24. package/dist/http.js +7 -0
  25. package/dist/index-CaLD-0oh.d.cts +608 -0
  26. package/dist/index-CaLD-0oh.d.ts +608 -0
  27. package/dist/index-DTllqUtj.d.cts +261 -0
  28. package/dist/index-DTllqUtj.d.ts +261 -0
  29. package/dist/index.cjs +23063 -0
  30. package/dist/index.d.cts +1603 -0
  31. package/dist/index.d.ts +1603 -0
  32. package/dist/index.js +6924 -0
  33. package/dist/query-CKJ4oSpG.d.cts +1595 -0
  34. package/dist/query-DQFRmu3u.d.ts +1595 -0
  35. package/dist/reactivity.cjs +676 -0
  36. package/dist/reactivity.d.cts +188 -0
  37. package/dist/reactivity.d.ts +188 -0
  38. package/dist/reactivity.js +4 -0
  39. package/dist/socket.cjs +2685 -0
  40. package/dist/socket.d.cts +167 -0
  41. package/dist/socket.d.ts +167 -0
  42. package/dist/socket.js +238 -0
  43. package/dist/style-XEUAGGJK.js +5 -0
  44. package/dist/utils.cjs +397 -0
  45. package/dist/utils.d.cts +111 -0
  46. package/dist/utils.d.ts +111 -0
  47. package/dist/utils.js +4 -0
  48. package/dist/voodoo.core.js +8213 -0
  49. package/dist/voodoo.core.min.js +146 -0
  50. package/dist/voodoo.full.js +21193 -0
  51. package/dist/voodoo.full.min.js +1784 -0
  52. package/dist/voodoo.js +14185 -0
  53. package/dist/voodoo.min.js +420 -0
  54. package/package.json +127 -0
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # Voodoo.js
2
+
3
+ **The HTML-first JavaScript framework.** Build reactive applications directly in HTML.
4
+
5
+ No mandatory build step · No runtime dependencies · No Virtual DOM · No configuration required
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install voodoojs
13
+ ```
14
+
15
+ Or drop it into a page, with nothing else:
16
+
17
+ ```html
18
+ <script src="https://cdn.jsdelivr.net/npm/voodoojs/dist/voodoo.min.js" defer></script>
19
+
20
+ <div v-data="{ count: 0 }">
21
+ <button @click="count++">Clicked { count } times</button>
22
+ </div>
23
+ ```
24
+
25
+ That page is a complete application. There is no build step, no bundler and no configuration.
26
+
27
+ ## Two ways to write it
28
+
29
+ HTML, when the declarative form reads better:
30
+
31
+ ```html
32
+ <input v-model="search">
33
+ <ul>
34
+ <li v-for="user in users" :key="user.id">{ user.name }</li>
35
+ </ul>
36
+ ```
37
+
38
+ JavaScript, when the logic belongs in JavaScript:
39
+
40
+ ```js
41
+ import V, { reactive, effect } from 'voodoojs';
42
+
43
+ const state = reactive({ count: 0 });
44
+ effect(() => console.log(state.count));
45
+ state.count++;
46
+ ```
47
+
48
+ ## Builds
49
+
50
+ | File | What it carries |
51
+ | --- | --- |
52
+ | `dist/voodoo.core.min.js` | Reactivity, expressions, DOM engine, components, core directives |
53
+ | `dist/voodoo.min.js` | The above plus forms, validation, masks, UI and HTTP. Served by default on the CDN |
54
+ | `dist/voodoo.full.min.js` | Everything: charts, motion, router, i18n, sound and the devtools inspector |
55
+
56
+ Module entry points are also published for bundlers:
57
+
58
+ ```js
59
+ import { reactive } from 'voodoojs/reactivity';
60
+ import { http } from 'voodoojs/http';
61
+ ```
62
+
63
+ TypeScript definitions ship with the package.
64
+
65
+ ## Documentation
66
+
67
+ Full documentation, guides, examples and the API reference live in the repository:
68
+
69
+ **https://github.com/kwy404/Voodoo.js**
70
+
71
+ The documentation is written in Portuguese under `docs/`, with an English set under `docs/en/`.
72
+
73
+ ## License
74
+
75
+ MIT
76
+
77
+ *JavaScript feels like magic.*
@@ -0,0 +1,401 @@
1
+ import { __export } from './chunk-E27NRARW.js';
2
+
3
+ /**
4
+ * Voodoo.js v0.4.6
5
+ * JavaScript feels like magic.
6
+ * (c) 2026 Voodoo.js contributors. MIT License.
7
+ */
8
+
9
+ // src/utils/index.ts
10
+ var utils_exports = {};
11
+ __export(utils_exports, {
12
+ capitalize: () => capitalize,
13
+ chunk: () => chunk,
14
+ clone: () => clone,
15
+ debounce: () => debounce,
16
+ device: () => device,
17
+ escapeHtml: () => escapeHtml,
18
+ formatCurrency: () => formatCurrency,
19
+ formatDate: () => formatDate,
20
+ formatFileSize: () => formatFileSize,
21
+ formatNumber: () => formatNumber,
22
+ formatPercent: () => formatPercent,
23
+ get: () => get,
24
+ groupBy: () => groupBy,
25
+ isBrowser: () => isBrowser,
26
+ matchesMedia: () => matchesMedia,
27
+ memoize: () => memoize,
28
+ merge: () => merge,
29
+ once: () => once,
30
+ parseDuration: () => parseDuration,
31
+ random: () => random,
32
+ relativeTime: () => relativeTime,
33
+ sample: () => sample,
34
+ set: () => set,
35
+ setFormatDefaults: () => setFormatDefaults,
36
+ sleep: () => sleep,
37
+ slugify: () => slugify,
38
+ sortBy: () => sortBy,
39
+ stripTags: () => stripTags,
40
+ throttle: () => throttle,
41
+ titleCase: () => titleCase,
42
+ truncate: () => truncate,
43
+ uid: () => uid,
44
+ unique: () => unique,
45
+ uuid: () => uuid
46
+ });
47
+ function uuid() {
48
+ const c = globalThis.crypto;
49
+ if (c?.randomUUID) return c.randomUUID();
50
+ if (c?.getRandomValues) {
51
+ const bytes = c.getRandomValues(new Uint8Array(16));
52
+ bytes[6] = bytes[6] & 15 | 64;
53
+ bytes[8] = bytes[8] & 63 | 128;
54
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
55
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
56
+ }
57
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (ch) => {
58
+ const r = Math.random() * 16 | 0;
59
+ return (ch === "x" ? r : r & 3 | 8).toString(16);
60
+ });
61
+ }
62
+ function uid(prefix = "v") {
63
+ return `${prefix}${Math.random().toString(36).slice(2, 9)}`;
64
+ }
65
+ function sleep(ms) {
66
+ return new Promise((resolve) => setTimeout(resolve, ms));
67
+ }
68
+ function parseDuration(value, fallback = 0) {
69
+ if (value == null || value === "") return fallback;
70
+ if (typeof value === "number") return value;
71
+ const match = /^\s*([\d.]+)\s*(ms|s|m|h)?\s*$/i.exec(String(value));
72
+ if (!match) return fallback;
73
+ const amount = parseFloat(match[1]);
74
+ switch ((match[2] || "ms").toLowerCase()) {
75
+ case "s":
76
+ return amount * 1e3;
77
+ case "m":
78
+ return amount * 6e4;
79
+ case "h":
80
+ return amount * 36e5;
81
+ default:
82
+ return amount;
83
+ }
84
+ }
85
+ function debounce(fn, wait = 250, immediate = false) {
86
+ let timer = null;
87
+ let lastArgs = null;
88
+ let lastThis;
89
+ const debounced = function(...args) {
90
+ lastArgs = args;
91
+ lastThis = this;
92
+ const callNow = immediate && timer === null;
93
+ if (timer) clearTimeout(timer);
94
+ timer = setTimeout(() => {
95
+ timer = null;
96
+ if (!immediate && lastArgs) fn.apply(lastThis, lastArgs);
97
+ }, wait);
98
+ if (callNow) fn.apply(this, args);
99
+ };
100
+ debounced.cancel = () => {
101
+ if (timer) clearTimeout(timer);
102
+ timer = null;
103
+ lastArgs = null;
104
+ };
105
+ debounced.flush = () => {
106
+ if (timer && lastArgs) {
107
+ clearTimeout(timer);
108
+ timer = null;
109
+ fn.apply(lastThis, lastArgs);
110
+ }
111
+ };
112
+ return debounced;
113
+ }
114
+ function throttle(fn, wait = 250) {
115
+ let last = 0;
116
+ let timer = null;
117
+ let lastArgs = null;
118
+ const throttled = function(...args) {
119
+ const now = Date.now();
120
+ lastArgs = args;
121
+ const remaining = wait - (now - last);
122
+ if (remaining <= 0) {
123
+ if (timer) {
124
+ clearTimeout(timer);
125
+ timer = null;
126
+ }
127
+ last = now;
128
+ fn.apply(this, args);
129
+ } else if (!timer) {
130
+ timer = setTimeout(() => {
131
+ last = Date.now();
132
+ timer = null;
133
+ if (lastArgs) fn.apply(this, lastArgs);
134
+ }, remaining);
135
+ }
136
+ };
137
+ throttled.cancel = () => {
138
+ if (timer) clearTimeout(timer);
139
+ timer = null;
140
+ };
141
+ throttled.flush = () => {
142
+ if (timer && lastArgs) {
143
+ clearTimeout(timer);
144
+ timer = null;
145
+ fn.apply(null, lastArgs);
146
+ }
147
+ };
148
+ return throttled;
149
+ }
150
+ function once(fn) {
151
+ let called = false;
152
+ let result;
153
+ return function(...args) {
154
+ if (!called) {
155
+ called = true;
156
+ result = fn.apply(this, args);
157
+ }
158
+ return result;
159
+ };
160
+ }
161
+ function memoize(fn, keyFn = (...args) => JSON.stringify(args)) {
162
+ const cache = /* @__PURE__ */ new Map();
163
+ const memoized = function(...args) {
164
+ const key = keyFn(...args);
165
+ if (cache.has(key)) return cache.get(key);
166
+ const value = fn.apply(this, args);
167
+ cache.set(key, value);
168
+ return value;
169
+ };
170
+ memoized.cache = cache;
171
+ return memoized;
172
+ }
173
+ function clone(value) {
174
+ if (value === null || typeof value !== "object") return value;
175
+ if (typeof structuredClone === "function") {
176
+ try {
177
+ return structuredClone(value);
178
+ } catch {
179
+ }
180
+ }
181
+ if (Array.isArray(value)) return value.map((v) => clone(v));
182
+ if (value instanceof Date) return new Date(value.getTime());
183
+ if (value instanceof Map) return new Map([...value].map(([k, v]) => [k, clone(v)]));
184
+ if (value instanceof Set) return new Set([...value].map((v) => clone(v)));
185
+ const out = {};
186
+ for (const [k, v] of Object.entries(value)) out[k] = clone(v);
187
+ return out;
188
+ }
189
+ function merge(target, ...sources) {
190
+ for (const source of sources) {
191
+ if (!source) continue;
192
+ for (const [key, value] of Object.entries(source)) {
193
+ const current = target[key];
194
+ if (value && typeof value === "object" && !Array.isArray(value) && current && typeof current === "object" && !Array.isArray(current)) {
195
+ target[key] = merge({ ...current }, value);
196
+ } else {
197
+ target[key] = value;
198
+ }
199
+ }
200
+ }
201
+ return target;
202
+ }
203
+ function groupBy(list, key) {
204
+ const out = {};
205
+ const getKey = typeof key === "function" ? key : (item) => item?.[key];
206
+ for (const item of list) {
207
+ const k = String(getKey(item));
208
+ (out[k] || (out[k] = [])).push(item);
209
+ }
210
+ return out;
211
+ }
212
+ function unique(list, key) {
213
+ if (!key) return [...new Set(list)];
214
+ const getKey = typeof key === "function" ? key : (item) => item?.[key];
215
+ const seen = /* @__PURE__ */ new Set();
216
+ const out = [];
217
+ for (const item of list) {
218
+ const k = getKey(item);
219
+ if (seen.has(k)) continue;
220
+ seen.add(k);
221
+ out.push(item);
222
+ }
223
+ return out;
224
+ }
225
+ function chunk(list, size = 10) {
226
+ if (size < 1) return [list];
227
+ const out = [];
228
+ for (let i = 0; i < list.length; i += size) out.push(list.slice(i, i + size));
229
+ return out;
230
+ }
231
+ function sortBy(list, key, direction = "asc") {
232
+ const getKey = typeof key === "function" ? key : (item) => item?.[key];
233
+ const factor = direction === "desc" ? -1 : 1;
234
+ return [...list].sort((a, b) => {
235
+ const va = getKey(a);
236
+ const vb = getKey(b);
237
+ if (va == null && vb == null) return 0;
238
+ if (va == null) return 1;
239
+ if (vb == null) return -1;
240
+ if (typeof va === "string" && typeof vb === "string") {
241
+ return va.localeCompare(vb, void 0, { numeric: true }) * factor;
242
+ }
243
+ return (va > vb ? 1 : va < vb ? -1 : 0) * factor;
244
+ });
245
+ }
246
+ function get(object, path, fallback) {
247
+ const parts = path.split(".");
248
+ let current = object;
249
+ for (const part of parts) {
250
+ if (current == null) return fallback;
251
+ current = current[part];
252
+ }
253
+ return current ?? fallback;
254
+ }
255
+ function set(object, path, value) {
256
+ const parts = path.split(".");
257
+ let current = object;
258
+ for (let i = 0; i < parts.length - 1; i++) {
259
+ const key = parts[i];
260
+ if (typeof current[key] !== "object" || current[key] === null) {
261
+ current[key] = /^\d+$/.test(parts[i + 1]) ? [] : {};
262
+ }
263
+ current = current[key];
264
+ }
265
+ current[parts[parts.length - 1]] = value;
266
+ }
267
+ function random(min = 0, max = 1) {
268
+ return Math.floor(Math.random() * (max - min + 1)) + min;
269
+ }
270
+ function sample(list) {
271
+ return list[Math.floor(Math.random() * list.length)];
272
+ }
273
+ function slugify(text, separator = "-") {
274
+ return String(text).normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().trim().replace(/[^a-z0-9]+/g, separator).replace(new RegExp(`\\${separator}{2,}`, "g"), separator).replace(new RegExp(`^\\${separator}|\\${separator}$`, "g"), "");
275
+ }
276
+ function truncate(text, length = 100, suffix = "...") {
277
+ const value = String(text ?? "");
278
+ if (value.length <= length) return value;
279
+ return value.slice(0, Math.max(0, length - suffix.length)).trimEnd() + suffix;
280
+ }
281
+ function capitalize(text) {
282
+ const value = String(text ?? "");
283
+ return value.charAt(0).toUpperCase() + value.slice(1);
284
+ }
285
+ function titleCase(text) {
286
+ return String(text ?? "").replace(/\w\S*/g, (word) => capitalize(word.toLowerCase()));
287
+ }
288
+ function escapeHtml(text) {
289
+ return String(text ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
290
+ }
291
+ function stripTags(html) {
292
+ return String(html ?? "").replace(/<\/?[^>]+(>|$)/g, "");
293
+ }
294
+ var defaultLocale = "pt-BR";
295
+ var defaultCurrency = "BRL";
296
+ function setFormatDefaults(locale, currency) {
297
+ if (locale) defaultLocale = locale;
298
+ if (currency) defaultCurrency = currency;
299
+ }
300
+ function formatCurrency(value, options = {}) {
301
+ const n = typeof value === "string" ? parseFloat(value) : value;
302
+ if (n == null || Number.isNaN(n)) return "";
303
+ return new Intl.NumberFormat(options.locale ?? defaultLocale, {
304
+ style: "currency",
305
+ currency: options.currency ?? defaultCurrency
306
+ }).format(n);
307
+ }
308
+ function formatNumber(value, options = {}) {
309
+ const n = typeof value === "string" ? parseFloat(value) : value;
310
+ if (n == null || Number.isNaN(n)) return "";
311
+ const { locale, ...rest } = options;
312
+ return new Intl.NumberFormat(locale ?? defaultLocale, rest).format(n);
313
+ }
314
+ function formatDate(value, format = "short", locale) {
315
+ const date = value instanceof Date ? value : new Date(value);
316
+ if (Number.isNaN(date.getTime())) return "";
317
+ const loc = locale ?? defaultLocale;
318
+ if (typeof format === "object") return new Intl.DateTimeFormat(loc, format).format(date);
319
+ const presets = {
320
+ short: { day: "2-digit", month: "2-digit", year: "numeric" },
321
+ long: { day: "2-digit", month: "long", year: "numeric" },
322
+ full: { dateStyle: "full" },
323
+ time: { hour: "2-digit", minute: "2-digit" },
324
+ datetime: { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit" }
325
+ };
326
+ if (presets[format]) return new Intl.DateTimeFormat(loc, presets[format]).format(date);
327
+ const pad = (n) => String(n).padStart(2, "0");
328
+ return format.replace(/YYYY/g, String(date.getFullYear())).replace(/YY/g, String(date.getFullYear()).slice(-2)).replace(/MM/g, pad(date.getMonth() + 1)).replace(/DD/g, pad(date.getDate())).replace(/HH/g, pad(date.getHours())).replace(/mm/g, pad(date.getMinutes())).replace(/ss/g, pad(date.getSeconds()));
329
+ }
330
+ function relativeTime(value, locale) {
331
+ const date = value instanceof Date ? value : new Date(value);
332
+ if (Number.isNaN(date.getTime())) return "";
333
+ const diff = date.getTime() - Date.now();
334
+ const abs = Math.abs(diff);
335
+ const units = [
336
+ ["year", 31536e6],
337
+ ["month", 2592e6],
338
+ ["week", 6048e5],
339
+ ["day", 864e5],
340
+ ["hour", 36e5],
341
+ ["minute", 6e4],
342
+ ["second", 1e3]
343
+ ];
344
+ const rtf = new Intl.RelativeTimeFormat(locale ?? defaultLocale, { numeric: "auto" });
345
+ for (const [unit, ms] of units) {
346
+ if (abs >= ms || unit === "second") {
347
+ return rtf.format(Math.round(diff / ms), unit);
348
+ }
349
+ }
350
+ return "";
351
+ }
352
+ function formatFileSize(bytes, decimals = 1) {
353
+ const n = Number(bytes);
354
+ if (!n || Number.isNaN(n)) return "0 B";
355
+ const units = ["B", "KB", "MB", "GB", "TB", "PB"];
356
+ const i = Math.min(Math.floor(Math.log(Math.abs(n)) / Math.log(1024)), units.length - 1);
357
+ return `${(n / 1024 ** i).toFixed(i === 0 ? 0 : decimals)} ${units[i]}`;
358
+ }
359
+ function formatPercent(value, decimals = 0, locale) {
360
+ return new Intl.NumberFormat(locale ?? defaultLocale, {
361
+ style: "percent",
362
+ minimumFractionDigits: decimals,
363
+ maximumFractionDigits: decimals
364
+ }).format(value);
365
+ }
366
+ var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
367
+ function matchesMedia(query) {
368
+ if (!isBrowser || typeof window.matchMedia !== "function") return false;
369
+ try {
370
+ return window.matchMedia(query).matches;
371
+ } catch {
372
+ return false;
373
+ }
374
+ }
375
+ var device = {
376
+ get touch() {
377
+ return isBrowser && ("ontouchstart" in window || navigator.maxTouchPoints > 0);
378
+ },
379
+ get mobile() {
380
+ return matchesMedia("(max-width: 767px)");
381
+ },
382
+ get tablet() {
383
+ return matchesMedia("(min-width: 768px) and (max-width: 1023px)");
384
+ },
385
+ get desktop() {
386
+ return matchesMedia("(min-width: 1024px)");
387
+ },
388
+ get online() {
389
+ return !isBrowser || navigator.onLine;
390
+ },
391
+ get reducedMotion() {
392
+ return matchesMedia("(prefers-reduced-motion: reduce)");
393
+ },
394
+ get darkMode() {
395
+ return matchesMedia("(prefers-color-scheme: dark)");
396
+ }
397
+ };
398
+
399
+ export { capitalize, chunk, clone, debounce, device, escapeHtml, formatCurrency, formatDate, formatFileSize, formatNumber, formatPercent, get, groupBy, isBrowser, matchesMedia, memoize, merge, once, parseDuration, random, relativeTime, sample, set, setFormatDefaults, sleep, slugify, sortBy, stripTags, throttle, titleCase, truncate, uid, unique, utils_exports, uuid };
400
+ //# sourceMappingURL=chunk-234ZLC6W.js.map
401
+ //# sourceMappingURL=chunk-234ZLC6W.js.map