zero-query 0.2.7 → 0.2.8
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.
- package/README.md +26 -42
- package/cli.js +166 -5
- package/dist/zquery.js +2 -2
- package/dist/zquery.min.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,11 +33,28 @@
|
|
|
33
33
|
|
|
34
34
|
## Quick Start
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
### Recommended: CLI Dev Server
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
The fastest way to develop with zQuery is via the built-in **CLI dev server** with **live-reload**. It serves your ES modules as-is and automatically resolves the library — no manual downloads required.
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
```bash
|
|
41
|
+
# Install (per-project or globally)
|
|
42
|
+
npm install zero-query --save-dev # or: npm install zero-query -g
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Scaffold a new project and start the server:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx zquery create my-app
|
|
49
|
+
cd my-app
|
|
50
|
+
npx zquery dev
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The `create` command generates a ready-to-run project with `index.html`, a router, two components, and styles. The dev server watches for file changes, hot-swaps CSS in-place, full-reloads on JS/HTML changes, and handles SPA fallback routing.
|
|
54
|
+
|
|
55
|
+
### Alternative: Manual Setup (No npm)
|
|
56
|
+
|
|
57
|
+
If you prefer **zero tooling**, download `dist/zQuery.min.js` from the [GitHub releases](https://github.com/tonywied17/zero-query/releases/tag/RELEASE) and drop it into `scripts/vendor/`. Then open `index.html` directly in a browser — no Node.js required.
|
|
41
58
|
|
|
42
59
|
```bash
|
|
43
60
|
git clone https://github.com/tonywied17/zero-query.git
|
|
@@ -46,7 +63,7 @@ node build.js
|
|
|
46
63
|
# → dist/zQuery.min.js (~45 KB)
|
|
47
64
|
```
|
|
48
65
|
|
|
49
|
-
###
|
|
66
|
+
### Include in HTML
|
|
50
67
|
|
|
51
68
|
```html
|
|
52
69
|
<!DOCTYPE html>
|
|
@@ -68,7 +85,7 @@ node build.js
|
|
|
68
85
|
</html>
|
|
69
86
|
```
|
|
70
87
|
|
|
71
|
-
###
|
|
88
|
+
### Boot Your App
|
|
72
89
|
|
|
73
90
|
```js
|
|
74
91
|
// scripts/app.js
|
|
@@ -79,7 +96,7 @@ import { routes } from './routes.js';
|
|
|
79
96
|
$.router({ el: '#app', routes, fallback: 'not-found' });
|
|
80
97
|
```
|
|
81
98
|
|
|
82
|
-
###
|
|
99
|
+
### Define a Component
|
|
83
100
|
|
|
84
101
|
```js
|
|
85
102
|
// scripts/components/home.js
|
|
@@ -96,7 +113,7 @@ $.component('home-page', {
|
|
|
96
113
|
});
|
|
97
114
|
```
|
|
98
115
|
|
|
99
|
-
That's it — a fully working SPA with
|
|
116
|
+
That's it — a fully working SPA with the dev server's live-reload.
|
|
100
117
|
|
|
101
118
|
---
|
|
102
119
|
|
|
@@ -107,7 +124,7 @@ my-app/
|
|
|
107
124
|
index.html
|
|
108
125
|
scripts/
|
|
109
126
|
vendor/
|
|
110
|
-
zQuery.min.js
|
|
127
|
+
zQuery.min.js ← only needed for manual setup; dev server auto-resolves
|
|
111
128
|
app.js
|
|
112
129
|
routes.js
|
|
113
130
|
store.js
|
|
@@ -123,40 +140,6 @@ my-app/
|
|
|
123
140
|
|
|
124
141
|
---
|
|
125
142
|
|
|
126
|
-
## Development Server
|
|
127
|
-
|
|
128
|
-
The CLI includes a built-in dev server with **live-reload** powered by [zero-http](https://github.com/tonywied17/zero-http). Install once:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
# Per-project (recommended)
|
|
132
|
-
npm install zero-query --save-dev
|
|
133
|
-
|
|
134
|
-
# Or install globally to use zquery anywhere without npx
|
|
135
|
-
npm install zero-query -g
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Then start the server:
|
|
139
|
-
|
|
140
|
-
```bash
|
|
141
|
-
# Start dev server (default port 3100)
|
|
142
|
-
npx zquery dev
|
|
143
|
-
|
|
144
|
-
# Custom port
|
|
145
|
-
npx zquery dev --port 8080
|
|
146
|
-
|
|
147
|
-
# Serve a specific project folder
|
|
148
|
-
npx zquery dev path/to/my-app
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
- **No build step** — the server serves your ES modules as-is.
|
|
152
|
-
- **CSS hot-swap** — `.css` changes reload in-place without a full refresh.
|
|
153
|
-
- **Full reload** — `.js`, `.html`, `.json`, and `.svg` changes trigger a page refresh.
|
|
154
|
-
- **SPA fallback** — non-file requests serve `index.html` so deep routes work.
|
|
155
|
-
|
|
156
|
-
The server injects a tiny SSE (Server-Sent Events) client into the HTTP response at runtime. Your source files are never modified.
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
143
|
## CLI Bundler
|
|
161
144
|
|
|
162
145
|
The CLI can compile your entire app — ES modules, the library, external templates, and assets — into a **single bundled file**.
|
|
@@ -252,6 +235,7 @@ location / {
|
|
|
252
235
|
|
|
253
236
|
| CLI Command | Description |
|
|
254
237
|
| --- | --- |
|
|
238
|
+
| `zquery create [dir]` | Scaffold a new project (index.html, scripts, styles) |
|
|
255
239
|
| `zquery dev [root]` | Dev server with live-reload (port 3100) |
|
|
256
240
|
| `zquery bundle [entry]` | Bundle app into a single IIFE file |
|
|
257
241
|
| `zquery build` | Build the zQuery library (`dist/zQuery.min.js`) |
|
package/cli.js
CHANGED
|
@@ -947,25 +947,181 @@ function devServer() {
|
|
|
947
947
|
}
|
|
948
948
|
|
|
949
949
|
|
|
950
|
+
// ---------------------------------------------------------------------------
|
|
951
|
+
// Create — scaffold a new zQuery project
|
|
952
|
+
// ---------------------------------------------------------------------------
|
|
953
|
+
|
|
954
|
+
function createProject() {
|
|
955
|
+
const target = args[1] ? path.resolve(args[1]) : process.cwd();
|
|
956
|
+
const name = path.basename(target);
|
|
957
|
+
|
|
958
|
+
// Guard: refuse to overwrite existing files
|
|
959
|
+
const conflicts = ['index.html', 'scripts'].filter(f =>
|
|
960
|
+
fs.existsSync(path.join(target, f))
|
|
961
|
+
);
|
|
962
|
+
if (conflicts.length) {
|
|
963
|
+
console.error(`\n ✗ Directory already contains: ${conflicts.join(', ')}`);
|
|
964
|
+
console.error(` Aborting to avoid overwriting existing files.\n`);
|
|
965
|
+
process.exit(1);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
console.log(`\n zQuery — Create Project\n`);
|
|
969
|
+
console.log(` Scaffolding into ${target}\n`);
|
|
970
|
+
|
|
971
|
+
// ---- templates ----
|
|
972
|
+
|
|
973
|
+
const indexHTML = `<!DOCTYPE html>
|
|
974
|
+
<html lang="en">
|
|
975
|
+
<head>
|
|
976
|
+
<meta charset="UTF-8">
|
|
977
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
978
|
+
<title>${name}</title>
|
|
979
|
+
<link rel="stylesheet" href="styles/styles.css">
|
|
980
|
+
<script src="scripts/vendor/zQuery.min.js"></script>
|
|
981
|
+
<script type="module" src="scripts/app.js"></script>
|
|
982
|
+
</head>
|
|
983
|
+
<body>
|
|
984
|
+
<nav>
|
|
985
|
+
<a z-link="/">Home</a>
|
|
986
|
+
<a z-link="/about">About</a>
|
|
987
|
+
</nav>
|
|
988
|
+
<div id="app"></div>
|
|
989
|
+
</body>
|
|
990
|
+
</html>`;
|
|
991
|
+
|
|
992
|
+
const appJS = `// scripts/app.js — entry point
|
|
993
|
+
import './components/home.js';
|
|
994
|
+
import './components/about.js';
|
|
995
|
+
import { routes } from './routes.js';
|
|
996
|
+
|
|
997
|
+
$.router({ el: '#app', routes, fallback: 'not-found' });
|
|
998
|
+
|
|
999
|
+
$.ready(() => {
|
|
1000
|
+
console.log('zQuery v' + $.version + ' loaded');
|
|
1001
|
+
});`;
|
|
1002
|
+
|
|
1003
|
+
const routesJS = `// scripts/routes.js
|
|
1004
|
+
export const routes = [
|
|
1005
|
+
{ path: '/', component: 'home-page' },
|
|
1006
|
+
{ path: '/about', component: 'about-page' },
|
|
1007
|
+
];`;
|
|
1008
|
+
|
|
1009
|
+
const homeJS = `// scripts/components/home.js
|
|
1010
|
+
$.component('home-page', {
|
|
1011
|
+
state: () => ({ count: 0 }),
|
|
1012
|
+
|
|
1013
|
+
increment() { this.state.count++; },
|
|
1014
|
+
|
|
1015
|
+
render() {
|
|
1016
|
+
return \`
|
|
1017
|
+
<h1>Home</h1>
|
|
1018
|
+
<p>Count: \${this.state.count}</p>
|
|
1019
|
+
<button @click="increment">+1</button>
|
|
1020
|
+
\`;
|
|
1021
|
+
}
|
|
1022
|
+
});`;
|
|
1023
|
+
|
|
1024
|
+
const aboutJS = `// scripts/components/about.js
|
|
1025
|
+
$.component('about-page', {
|
|
1026
|
+
render() {
|
|
1027
|
+
return \`
|
|
1028
|
+
<h1>About</h1>
|
|
1029
|
+
<p>Built with <strong>zQuery</strong> — a lightweight, zero-dependency frontend library.</p>
|
|
1030
|
+
\`;
|
|
1031
|
+
}
|
|
1032
|
+
});`;
|
|
1033
|
+
|
|
1034
|
+
const stylesCSS = `/* styles/styles.css */
|
|
1035
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
1036
|
+
|
|
1037
|
+
body {
|
|
1038
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
1039
|
+
line-height: 1.6;
|
|
1040
|
+
color: #e6edf3;
|
|
1041
|
+
background: #0d1117;
|
|
1042
|
+
padding: 2rem;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
nav {
|
|
1046
|
+
display: flex;
|
|
1047
|
+
gap: 1rem;
|
|
1048
|
+
margin-bottom: 2rem;
|
|
1049
|
+
padding-bottom: 1rem;
|
|
1050
|
+
border-bottom: 1px solid #30363d;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
nav a {
|
|
1054
|
+
color: #58a6ff;
|
|
1055
|
+
text-decoration: none;
|
|
1056
|
+
font-weight: 500;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
nav a:hover { text-decoration: underline; }
|
|
1060
|
+
|
|
1061
|
+
h1 { margin-bottom: 0.5rem; }
|
|
1062
|
+
|
|
1063
|
+
button {
|
|
1064
|
+
margin-top: 0.75rem;
|
|
1065
|
+
padding: 0.5rem 1.25rem;
|
|
1066
|
+
background: #238636;
|
|
1067
|
+
color: #fff;
|
|
1068
|
+
border: none;
|
|
1069
|
+
border-radius: 6px;
|
|
1070
|
+
cursor: pointer;
|
|
1071
|
+
font-size: 0.95rem;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
button:hover { background: #2ea043; }`;
|
|
1075
|
+
|
|
1076
|
+
// ---- write files ----
|
|
1077
|
+
|
|
1078
|
+
const files = {
|
|
1079
|
+
'index.html': indexHTML,
|
|
1080
|
+
'scripts/app.js': appJS,
|
|
1081
|
+
'scripts/routes.js': routesJS,
|
|
1082
|
+
'scripts/components/home.js': homeJS,
|
|
1083
|
+
'scripts/components/about.js': aboutJS,
|
|
1084
|
+
'styles/styles.css': stylesCSS,
|
|
1085
|
+
};
|
|
1086
|
+
|
|
1087
|
+
for (const [rel, content] of Object.entries(files)) {
|
|
1088
|
+
const abs = path.join(target, rel);
|
|
1089
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
1090
|
+
fs.writeFileSync(abs, content, 'utf-8');
|
|
1091
|
+
console.log(` ✓ ${rel}`);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
console.log(`
|
|
1095
|
+
Done! Next steps:
|
|
1096
|
+
|
|
1097
|
+
${target !== process.cwd() ? `cd ${args[1]}\n ` : ''}npx zquery dev
|
|
1098
|
+
`);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
|
|
950
1102
|
// ---------------------------------------------------------------------------
|
|
951
1103
|
// Help
|
|
952
1104
|
// ---------------------------------------------------------------------------
|
|
953
1105
|
|
|
954
1106
|
function showHelp() {
|
|
955
1107
|
console.log(`
|
|
956
|
-
zQuery CLI —
|
|
1108
|
+
zQuery CLI — create, dev, bundle & build
|
|
957
1109
|
|
|
958
1110
|
COMMANDS
|
|
959
1111
|
|
|
960
|
-
|
|
961
|
-
|
|
1112
|
+
create [dir] Scaffold a new zQuery project
|
|
1113
|
+
Creates index.html, scripts/, styles/ in the target directory
|
|
1114
|
+
(defaults to the current directory)
|
|
1115
|
+
|
|
1116
|
+
dev [root] Start a dev server with live-reload
|
|
1117
|
+
--port, -p <number> Port number (default: 3100)
|
|
962
1118
|
|
|
963
1119
|
bundle [entry] Bundle app ES modules into a single file
|
|
964
1120
|
--out, -o <path> Output directory (default: dist/ next to index.html)
|
|
965
1121
|
--html <file> Use a specific HTML file (default: auto-detected)
|
|
966
1122
|
|
|
967
|
-
|
|
968
|
-
|
|
1123
|
+
build Build the zQuery library → dist/
|
|
1124
|
+
(must be run from the project root where src/ lives)
|
|
969
1125
|
|
|
970
1126
|
SMART DEFAULTS
|
|
971
1127
|
|
|
@@ -997,6 +1153,9 @@ function showHelp() {
|
|
|
997
1153
|
|
|
998
1154
|
EXAMPLES
|
|
999
1155
|
|
|
1156
|
+
# Scaffold a new project and start developing
|
|
1157
|
+
zquery create my-app && cd my-app && zquery dev
|
|
1158
|
+
|
|
1000
1159
|
# Start dev server with live-reload
|
|
1001
1160
|
cd my-app && zquery dev
|
|
1002
1161
|
|
|
@@ -1026,6 +1185,8 @@ function showHelp() {
|
|
|
1026
1185
|
|
|
1027
1186
|
if (!command || command === '--help' || command === '-h' || command === 'help') {
|
|
1028
1187
|
showHelp();
|
|
1188
|
+
} else if (command === 'create') {
|
|
1189
|
+
createProject();
|
|
1029
1190
|
} else if (command === 'build') {
|
|
1030
1191
|
console.log('\n zQuery Library Build\n');
|
|
1031
1192
|
buildLibrary();
|
package/dist/zquery.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* zQuery (zeroQuery) v0.2.
|
|
2
|
+
* zQuery (zeroQuery) v0.2.8
|
|
3
3
|
* Lightweight Frontend Library
|
|
4
4
|
* https://github.com/tonywied17/zero-query
|
|
5
5
|
* (c) 2026 Anthony Wiedman — MIT License
|
|
@@ -2576,7 +2576,7 @@ $.session = session;
|
|
|
2576
2576
|
$.bus = bus;
|
|
2577
2577
|
|
|
2578
2578
|
// --- Meta ------------------------------------------------------------------
|
|
2579
|
-
$.version = '0.2.
|
|
2579
|
+
$.version = '0.2.8';
|
|
2580
2580
|
$.meta = {}; // populated at build time by CLI bundler
|
|
2581
2581
|
|
|
2582
2582
|
$.noConflict = () => {
|
package/dist/zquery.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* zQuery (zeroQuery) v0.2.
|
|
2
|
+
* zQuery (zeroQuery) v0.2.8
|
|
3
3
|
* Lightweight Frontend Library
|
|
4
4
|
* https://github.com/tonywied17/zero-query
|
|
5
5
|
* (c) 2026 Anthony Wiedman — MIT License
|
|
@@ -13,5 +13,5 @@ class Router { constructor(config = {}) { this._el = null; const isFile = typeof
|
|
|
13
13
|
class Store { constructor(config = {}) { this._subscribers = new Map(); this._wildcards = new Set(); this._actions = config.actions || {}; this._getters = config.getters || {}; this._middleware = []; this._history = []; this._debug = config.debug || false; const initial = typeof config.state === 'function' ? config.state() : { ...(config.state || {}) }; this.state = reactive(initial, (key, value, old) => { const subs = this._subscribers.get(key); if (subs) subs.forEach(fn => fn(value, old, key)); this._wildcards.forEach(fn => fn(key, value, old)); }); this.getters = {}; for (const [name, fn] of Object.entries(this._getters)) { Object.defineProperty(this.getters, name, { get: () => fn(this.state.__raw || this.state), enumerable: true }); } } dispatch(name, ...args) { const action = this._actions[name]; if (!action) { console.warn(`zQuery Store: Unknown action "${name}"`); return; } for (const mw of this._middleware) { const result = mw(name, args, this.state); if (result === false) return; } if (this._debug) { console.log(`%c[Store] ${name}`, 'color: #4CAF50; font-weight: bold;', ...args); } const result = action(this.state, ...args); this._history.push({ action: name, args, timestamp: Date.now() }); return result; } subscribe(keyOrFn, fn) { if (typeof keyOrFn === 'function') { this._wildcards.add(keyOrFn); return () => this._wildcards.delete(keyOrFn); } if (!this._subscribers.has(keyOrFn)) { this._subscribers.set(keyOrFn, new Set()); } this._subscribers.get(keyOrFn).add(fn); return () => this._subscribers.get(keyOrFn)?.delete(fn); } snapshot() { return JSON.parse(JSON.stringify(this.state.__raw || this.state)); } replaceState(newState) { const raw = this.state.__raw || this.state; for (const key of Object.keys(raw)) { delete this.state[key]; } Object.assign(this.state, newState); } use(fn) { this._middleware.push(fn); return this; } get history() { return [...this._history]; } reset(initialState) { this.replaceState(initialState); this._history = []; }
|
|
14
14
|
const _config = { baseURL: '', headers: { 'Content-Type': 'application/json' }, timeout: 30000,
|
|
15
15
|
function debounce(fn, ms = 250) { let timer; const debounced = (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), ms); }; debounced.cancel = () => clearTimeout(timer); return debounced;
|
|
16
|
-
function $(selector, context) { if (typeof selector === 'function') { query.ready(selector); return; } return query(selector, context);
|
|
16
|
+
function $(selector, context) { if (typeof selector === 'function') { query.ready(selector); return; } return query(selector, context);
|
|
17
17
|
})(typeof window !== 'undefined' ? window : globalThis);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zero-query",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "Lightweight modern frontend library — jQuery-like selectors, reactive components, SPA router, and state management with zero dependencies.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|