zero-query 0.3.1 → 0.4.9

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="docs/images/logo.svg" alt="zQuery logo" width="300" height="300">
2
+ <img src=".github/images/logo.svg" alt="zQuery logo" width="300" height="300">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">zQuery</h1>
@@ -15,14 +15,14 @@
15
15
 
16
16
  </p>
17
17
 
18
- > **Lightweight, zero-dependency frontend library that combines jQuery-style DOM manipulation with a modern reactive component system, SPA router, global state management, HTTP client, and utility toolkit — all in a single ~45 KB minified browser bundle. Works out of the box with ES modules — no build step required. An optional CLI bundler is available for single-file distribution.**
18
+ > **Lightweight, zero-dependency frontend library that combines jQuery-style DOM manipulation with a modern reactive component system, SPA router, global state management, HTTP client, and utility toolkit — all in a single ~54 KB minified browser bundle. Works out of the box with ES modules. An optional CLI bundler is available for single-file production builds.**
19
19
 
20
20
  ## Features
21
21
 
22
22
  | Module | Highlights |
23
23
  | --- | --- |
24
24
  | **Core `$()`** | jQuery-like chainable selectors, traversal, DOM manipulation, events, animation |
25
- | **Components** | Reactive state, template literals, `@event` delegation, `z-model` two-way binding, scoped styles, lifecycle hooks |
25
+ | **Components** | Reactive state, template literals, `@event` delegation (8 modifiers), `z-model` two-way binding, directives (`z-if`/`z-else-if`/`z-else`, `z-for`, `z-show`, `z-bind`/`:attr`, `z-class`, `z-style`, `z-text`, `z-html`, `z-ref`, `z-cloak`, `z-pre`), scoped styles, external templates (`templateUrl` / `styleUrl`), lifecycle hooks, auto-injected base styles (`z-cloak` hiding, mobile tap-highlight suppression) |
26
26
  | **Router** | History & hash mode, route params (`:id`), guards, lazy loading, `z-link` navigation |
27
27
  | **Store** | Reactive global state, named actions, computed getters, middleware, subscriptions |
28
28
  | **HTTP** | Fetch wrapper with auto-JSON, interceptors, timeout/abort, base URL |
@@ -46,11 +46,20 @@ Scaffold a new project and start the server:
46
46
 
47
47
  ```bash
48
48
  npx zquery create my-app
49
- cd my-app
50
- npx zquery dev
49
+ npx zquery dev my-app
51
50
  ```
52
51
 
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 other changes, and handles SPA fallback routing.
52
+ > **Tip:** Stay in the project root (where `node_modules` lives) instead of `cd`-ing into `my-app`. This keeps `index.d.ts` accessible to your IDE for full type/intellisense support.
53
+
54
+ The `create` command generates a ready-to-run project with a sidebar layout, router, multiple components (including a folder component with external template and styles), and responsive styles. The dev server watches for file changes, hot-swaps CSS in-place, full-reloads on other changes, and handles SPA fallback routing.
55
+
56
+ #### Error Overlay
57
+
58
+ The dev server includes a **full-screen error overlay** that surfaces errors directly in the browser — similar to Vite or Angular:
59
+
60
+ - **Syntax errors** — JS files are validated on every save *before* the reload is triggered. If a syntax error is found the page stays intact and a dark overlay appears with the error message, file path, line:column, and a code frame pointing to the exact location.
61
+ - **Runtime errors** — uncaught exceptions and unhandled promise rejections are captured and displayed in the same overlay with a cleaned-up stack trace.
62
+ - The overlay **auto-clears** when you fix the error and save. Press `Esc` or click `×` to dismiss manually.
54
63
 
55
64
  ### Alternative: Manual Setup (No npm)
56
65
 
@@ -59,8 +68,8 @@ If you prefer **zero tooling**, download `dist/zQuery.min.js` from the [GitHub r
59
68
  ```bash
60
69
  git clone https://github.com/tonywied17/zero-query.git
61
70
  cd zero-query
62
- node build.js
63
- # → dist/zQuery.min.js (~45 KB)
71
+ npx zquery build
72
+ # → dist/zQuery.min.js (~54 KB)
64
73
  ```
65
74
 
66
75
  ### Include in HTML
@@ -91,6 +100,7 @@ node build.js
91
100
  // scripts/app.js
92
101
  import './components/home.js';
93
102
  import './components/about.js';
103
+ import './components/contacts/contacts.js';
94
104
  import { routes } from './routes.js';
95
105
 
96
106
  $.router({ el: '#app', routes, fallback: 'not-found' });
@@ -131,11 +141,21 @@ my-app/
131
141
  components/
132
142
  home.js
133
143
  counter.js
144
+ todos.js
145
+ api-demo.js
134
146
  about.js
147
+ not-found.js
148
+ contacts/ ← folder component (templateUrl + styleUrl)
149
+ contacts.js
150
+ contacts.html
151
+ contacts.css
152
+ styles/
153
+ styles.css
135
154
  ```
136
155
 
137
156
  - One component per file inside `components/`.
138
157
  - Names **must contain a hyphen** (Web Component convention): `home-page`, `app-counter`, etc.
158
+ - Components with external templates or styles can use a subfolder (e.g. `contacts/contacts.js` + `contacts.html` + `contacts.css`).
139
159
  - `app.js` is the single entry point — import components, create the store, and boot the router.
140
160
 
141
161
  ---
@@ -145,11 +165,11 @@ my-app/
145
165
  The CLI can compile your entire app — ES modules, the library, external templates, and assets — into a **single bundled file**.
146
166
 
147
167
  ```bash
148
- # Auto-detect entry from index.html
168
+ # Auto-detect entry from any .html with a module script
149
169
  npx zquery bundle
150
170
 
151
- # Or specify an entry point
152
- npx zquery bundle path/to/scripts/app.js
171
+ # Or point to an app directory from anywhere
172
+ npx zquery bundle my-app/
153
173
  ```
154
174
 
155
175
  Output goes to `dist/` next to your `index.html`:
@@ -176,7 +196,11 @@ dist/
176
196
 
177
197
  ### What the Bundler Does
178
198
 
179
- 1. Reads `index.html` for the `<script type="module">` entry point
199
+ 1. **Entry detection** a strict precedence order ensures the correct file is chosen:
200
+ 1. **HTML files** — `index.html` is checked first, then other `.html` files (root + one level deep).
201
+ 2. **Module scripts within HTML** — within each HTML file, a `<script type="module">` whose `src` resolves to `app.js` wins; otherwise the first module script tag is used.
202
+ 3. **JS file scan** — if no HTML match, JS files (up to 2 levels deep) are scanned in two passes: first for `$.router(` (the canonical app entry point), then for `$.mount(`, `$.store(`, or `mountAll(`.
203
+ 4. **Convention fallbacks** — `scripts/app.js`, `src/app.js`, `js/app.js`, `app.js`, `main.js`.
180
204
  2. Resolves all `import` statements and topologically sorts dependencies
181
205
  3. Strips `import`/`export` syntax, wraps in an IIFE
182
206
  4. Embeds zQuery library and inlines `templateUrl` / `styleUrl` / `pages` files
@@ -216,7 +240,7 @@ location / {
216
240
  | `$.all()` | Collection selector → `ZQueryCollection` |
217
241
  | `$.id` `$.class` `$.classes` `$.tag` `$.children` | Quick DOM refs |
218
242
  | `$.create` | Element factory |
219
- | `$.ready` `$.on` | DOM ready, global delegation |
243
+ | `$.ready` `$.on` `$.off` | DOM ready, global event delegation & direct listeners |
220
244
  | `$.fn` | Collection prototype (extend it) |
221
245
  | `$.component` `$.mount` `$.mountAll` `$.getInstance` `$.destroy` `$.components` | Component system |
222
246
  | `$.style` | Dynamically load global stylesheet file(s) at runtime |
@@ -231,13 +255,14 @@ location / {
231
255
  | `$.storage` `$.session` | Storage wrappers |
232
256
  | `$.bus` | Event bus |
233
257
  | `$.version` | Library version |
258
+ | `$.meta` | Build metadata (populated by CLI bundler) |
234
259
  | `$.noConflict` | Release `$` global |
235
260
 
236
261
  | CLI Command | Description |
237
262
  | --- | --- |
238
- | `zquery create [dir]` | Scaffold a new project (index.html, scripts, styles) |
239
- | `zquery dev [root]` | Dev server with live-reload (port 3100) |
240
- | `zquery bundle [entry]` | Bundle app into a single IIFE file |
263
+ | `zquery create [dir]` | Scaffold a new project (index.html, components, store, styles) |
264
+ | `zquery dev [root]` | Dev server with live-reload &amp; error overlay (port 3100) |
265
+ | `zquery bundle [dir]` | Bundle app into a single IIFE file |
241
266
  | `zquery build` | Build the zQuery library (`dist/zQuery.min.js`) |
242
267
  | `zquery --help` | Show CLI usage |
243
268
 
@@ -247,7 +272,7 @@ For full method signatures, options, and examples, see **[API.md](API.md)**.
247
272
 
248
273
  ## Editor Support
249
274
 
250
- The official **[zQuery for VS Code](https://marketplace.visualstudio.com/items?itemName=zQuery.zquery-vs-code)** extension provides autocomplete, hover docs, HTML directive support, and 55+ code snippets for every API method and directive. Install it from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=zQuery.zquery-vs-code) or search **"zQuery for VS Code"** in Extensions.
275
+ The official **[zQuery for VS Code](https://marketplace.visualstudio.com/items?itemName=zQuery.zquery-vs-code)** extension provides autocomplete, hover docs, HTML directive support, and 140+ code snippets for every API method and directive. Install it from the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=zQuery.zquery-vs-code) or search **"zQuery for VS Code"** in Extensions.
251
276
 
252
277
  ---
253
278
 
package/cli/args.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * cli/args.js — CLI argument parsing helpers
3
+ *
4
+ * Provides the raw args array and two helper functions for reading
5
+ * named flags (--verbose, -v) and valued options (--port 8080, -p 8080).
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ const args = process.argv.slice(2);
11
+
12
+ /**
13
+ * Check whether a boolean flag is present.
14
+ * flag('verbose', 'v') → true if --verbose or -v appears
15
+ */
16
+ function flag(name, short) {
17
+ const i = args.indexOf(`--${name}`);
18
+ const j = short ? args.indexOf(`-${short}`) : -1;
19
+ return i !== -1 || j !== -1;
20
+ }
21
+
22
+ /**
23
+ * Read a string-valued option.
24
+ * option('port', 'p', '3100') → the value after --port / -p, or '3100'
25
+ */
26
+ function option(name, short, fallback) {
27
+ let i = args.indexOf(`--${name}`);
28
+ if (i === -1 && short) i = args.indexOf(`-${short}`);
29
+ if (i !== -1 && i + 1 < args.length) return args[i + 1];
30
+ return fallback;
31
+ }
32
+
33
+ module.exports = { args, flag, option };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * cli/commands/build.js — library build command
3
+ *
4
+ * Concatenates the zQuery source modules into dist/zquery.js and
5
+ * dist/zquery.min.js.
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const { minify, sizeKB } = require('../utils');
13
+
14
+ function buildLibrary() {
15
+ const pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'));
16
+ const VERSION = pkg.version;
17
+
18
+ const modules = [
19
+ 'src/reactive.js', 'src/core.js', 'src/component.js',
20
+ 'src/router.js', 'src/store.js', 'src/http.js', 'src/utils.js',
21
+ ];
22
+
23
+ const DIST = path.join(process.cwd(), 'dist');
24
+ const OUT_FILE = path.join(DIST, 'zquery.js');
25
+ const MIN_FILE = path.join(DIST, 'zquery.min.js');
26
+
27
+ const start = Date.now();
28
+ if (!fs.existsSync(DIST)) fs.mkdirSync(DIST, { recursive: true });
29
+
30
+ const parts = modules.map(file => {
31
+ let code = fs.readFileSync(path.join(process.cwd(), file), 'utf-8');
32
+ code = code.replace(/^import\s+[\s\S]*?from\s+['"].*?['"];?\s*$/gm, '');
33
+ code = code.replace(/^export\s+(default\s+)?/gm, '');
34
+ code = code.replace(/^export\s*\{[\s\S]*?\};\s*$/gm, '');
35
+ return `// --- ${file} ${'—'.repeat(60 - file.length)}\n${code.trim()}`;
36
+ });
37
+
38
+ let indexCode = fs.readFileSync(path.join(process.cwd(), 'index.js'), 'utf-8');
39
+ indexCode = indexCode.replace(/^import\s+[\s\S]*?from\s+['"].*?['"];?\s*$/gm, '');
40
+ indexCode = indexCode.replace(/^export\s*\{[\s\S]*?\};\s*$/gm, '');
41
+ indexCode = indexCode.replace(/^export\s+(default\s+)?/gm, '');
42
+
43
+ const banner = `/**\n * zQuery (zeroQuery) v${VERSION}\n * Lightweight Frontend Library\n * https://github.com/tonywied17/zero-query\n * (c) ${new Date().getFullYear()} Anthony Wiedman — MIT License\n */`;
44
+
45
+ const bundle = `${banner}\n(function(global) {\n 'use strict';\n\n${parts.join('\n\n')}\n\n// --- index.js (assembly) ${'—'.repeat(42)}\n${indexCode.trim().replace("'__VERSION__'", `'${VERSION}'`)}\n\n})(typeof window !== 'undefined' ? window : globalThis);\n`;
46
+
47
+ fs.writeFileSync(OUT_FILE, bundle, 'utf-8');
48
+ fs.writeFileSync(MIN_FILE, minify(bundle, banner), 'utf-8');
49
+
50
+ const elapsed = Date.now() - start;
51
+ console.log(` ✓ dist/zquery.js (${sizeKB(fs.readFileSync(OUT_FILE))} KB)`);
52
+ console.log(` ✓ dist/zquery.min.js (${sizeKB(fs.readFileSync(MIN_FILE))} KB)`);
53
+ console.log(` Done in ${elapsed}ms\n`);
54
+
55
+ return { DIST, OUT_FILE, MIN_FILE };
56
+ }
57
+
58
+ module.exports = buildLibrary;