zero-query 1.2.3 → 1.2.5
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 +18 -7
- package/cli/commands/build-api.js +21 -8
- package/cli/commands/create.js +63 -74
- package/cli/scaffold/default/package.json +14 -0
- package/cli/scaffold/minimal/package.json +14 -0
- package/cli/scaffold/ssr/package.json +4 -0
- package/dist/API.md +246 -69
- package/dist/zquery.dist.zip +0 -0
- package/dist/zquery.js +2 -2
- package/dist/zquery.min.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,21 +43,32 @@
|
|
|
43
43
|
|
|
44
44
|
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.
|
|
45
45
|
|
|
46
|
+
Pick a scaffold flavor — every variant auto-installs, auto-starts, and opens your browser:
|
|
47
|
+
|
|
46
48
|
```bash
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
+
# Default: full sidebar layout, router, demo components, responsive styles
|
|
50
|
+
npx zero-query create my-app # → http://localhost:3100
|
|
51
|
+
|
|
52
|
+
# Minimal: lightweight 3-page starter
|
|
53
|
+
npx zero-query create my-app --minimal # → http://localhost:3100 (alias: -m)
|
|
54
|
+
|
|
55
|
+
# SSR: Node.js server-side rendering project
|
|
56
|
+
npx zero-query create my-app --ssr # → http://localhost:3000 (alias: -s)
|
|
57
|
+
|
|
58
|
+
# WebRTC: one-page video room backed by zero-server
|
|
59
|
+
npx zero-query create my-app --webrtc-demo # → http://localhost:3000 (alias: -w)
|
|
49
60
|
```
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
That's it. One command scaffolds the project, installs dependencies, starts the server, and opens the browser. To restart later:
|
|
52
63
|
|
|
53
64
|
```bash
|
|
54
|
-
|
|
55
|
-
|
|
65
|
+
cd my-app
|
|
66
|
+
npm run dev # or: npm start
|
|
56
67
|
```
|
|
57
68
|
|
|
58
|
-
> **Tip:**
|
|
69
|
+
> **Tip:** For the default and minimal variants, you can 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.
|
|
59
70
|
|
|
60
|
-
The
|
|
71
|
+
The default scaffold ships a sidebar layout, router, multiple components (including folder components with external templates and styles), and responsive styles. The SSR variant runs a Node.js server that renders pages to HTML strings. The WebRTC variant is wired to [zero-server](https://github.com/tonywied17/zero-server) for signaling + TURN. The dev server watches for file changes, hot-swaps CSS in-place, full-reloads on other changes, and handles SPA fallback routing.
|
|
61
72
|
|
|
62
73
|
#### Error Overlay
|
|
63
74
|
|
|
@@ -220,9 +220,17 @@ function htmlToMarkdown(html) {
|
|
|
220
220
|
md = md.replace(/<div class="file-tree">[\s\S]*?<\/div>(?:\s*<\/div>)*/g, '');
|
|
221
221
|
|
|
222
222
|
// ---- Pass 5: Convert headings ----
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
// Preserve `id` attributes by emitting an explicit HTML anchor before the
|
|
224
|
+
// heading so cross-section duplicate titles (e.g. "Overview") still resolve
|
|
225
|
+
// to unique anchors in the rendered Markdown TOC.
|
|
226
|
+
const headingRepl = (level) => (_, attrs, c) => {
|
|
227
|
+
const idMatch = /\bid="([^"]+)"/.exec(attrs || '');
|
|
228
|
+
const anchor = idMatch ? `<a id="${idMatch[1]}"></a>\n` : '';
|
|
229
|
+
return '\n' + anchor + '#'.repeat(level) + ' ' + unesc(inlineMd(c)).trim() + '\n';
|
|
230
|
+
};
|
|
231
|
+
md = md.replace(/<h2([^>]*)>([\s\S]*?)<\/h2>/g, headingRepl(2));
|
|
232
|
+
md = md.replace(/<h3([^>]*)>([\s\S]*?)<\/h3>/g, headingRepl(3));
|
|
233
|
+
md = md.replace(/<h4([^>]*)>([\s\S]*?)<\/h4>/g, headingRepl(4));
|
|
226
234
|
|
|
227
235
|
// ---- Pass 6: Convert lists ----
|
|
228
236
|
md = md.replace(/<ul>([\s\S]*?)<\/ul>/g, (_, content) => {
|
|
@@ -298,14 +306,19 @@ function slugify(text) {
|
|
|
298
306
|
function buildToc(sections) {
|
|
299
307
|
const lines = [];
|
|
300
308
|
for (const section of sections) {
|
|
301
|
-
// Get the section title from the first <h2> in content
|
|
309
|
+
// Get the section title from the first <h2> in content, preferring an
|
|
310
|
+
// explicit `id` attribute when present so the TOC link is stable and
|
|
311
|
+
// unique across sections.
|
|
302
312
|
const html = section.content();
|
|
303
|
-
const h2Match = html.match(/<h2[^>]
|
|
304
|
-
const title
|
|
305
|
-
|
|
313
|
+
const h2Match = html.match(/<h2([^>]*)>([\s\S]*?)<\/h2>/);
|
|
314
|
+
const title = h2Match ? unesc(inlineMd(h2Match[2])).trim() : section.label;
|
|
315
|
+
const h2Id = h2Match && /\bid="([^"]+)"/.exec(h2Match[1] || '');
|
|
316
|
+
const anchor = h2Id ? h2Id[1] : (section.id || slugify(title));
|
|
317
|
+
lines.push(`- [${title}](#${anchor})`);
|
|
306
318
|
for (const h of section.headings) {
|
|
307
319
|
const hText = unesc(h.text);
|
|
308
|
-
|
|
320
|
+
const hAnchor = h.id || slugify(hText);
|
|
321
|
+
lines.push(` - [${hText}](#${hAnchor})`);
|
|
309
322
|
}
|
|
310
323
|
}
|
|
311
324
|
return lines.join('\n');
|
package/cli/commands/create.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// cli/commands/create.js - scaffold a new zQuery project
|
|
2
2
|
//
|
|
3
|
-
// Templates live in cli/scaffold/<variant>/ (default
|
|
3
|
+
// Templates live in cli/scaffold/<variant>/ (default, minimal, ssr, webrtc).
|
|
4
4
|
// Reads template files, replaces {{NAME}} with the project name,
|
|
5
5
|
// and writes them into the target directory.
|
|
6
6
|
|
|
@@ -25,6 +25,28 @@ function walkDir(dir, prefix = '') {
|
|
|
25
25
|
return entries;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Open the given URL in the user's default browser. Best-effort, silent on
|
|
30
|
+
* failure (the server still prints the URL).
|
|
31
|
+
*/
|
|
32
|
+
function openBrowser(url) {
|
|
33
|
+
const cmd = process.platform === 'win32' ? 'start ""'
|
|
34
|
+
: process.platform === 'darwin' ? 'open' : 'xdg-open';
|
|
35
|
+
try { execSync(`${cmd} ${url}`, { stdio: 'ignore' }); } catch { /* ignore */ }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Spawn a long-running child process, wire SIGINT/SIGTERM to terminate it,
|
|
40
|
+
* and exit when it does. Used by every scaffold variant to launch the dev /
|
|
41
|
+
* SSR / signaling server right after install.
|
|
42
|
+
*/
|
|
43
|
+
function runAndExit(cmd, cmdArgs, cwd) {
|
|
44
|
+
const child = spawn(cmd, cmdArgs, { cwd, stdio: 'inherit', shell: process.platform === 'win32' });
|
|
45
|
+
process.on('SIGINT', () => { child.kill(); process.exit(); });
|
|
46
|
+
process.on('SIGTERM', () => { child.kill(); process.exit(); });
|
|
47
|
+
child.on('exit', (code) => process.exit(code || 0));
|
|
48
|
+
}
|
|
49
|
+
|
|
28
50
|
function createProject(args) {
|
|
29
51
|
// First positional arg after "create" is the target dir (skip flags)
|
|
30
52
|
const dirArg = args.slice(1).find(a => !a.startsWith('-'));
|
|
@@ -38,7 +60,7 @@ function createProject(args) {
|
|
|
38
60
|
: 'default';
|
|
39
61
|
|
|
40
62
|
// Guard: refuse to overwrite existing files
|
|
41
|
-
const checkFiles = ['index.html', 'global.css', 'app', 'assets'];
|
|
63
|
+
const checkFiles = ['index.html', 'global.css', 'app', 'assets', 'package.json'];
|
|
42
64
|
if (variant === 'ssr' || variant === 'webrtc') checkFiles.push('server');
|
|
43
65
|
const conflicts = checkFiles.filter(f =>
|
|
44
66
|
fs.existsSync(path.join(target, f))
|
|
@@ -76,79 +98,53 @@ function createProject(args) {
|
|
|
76
98
|
console.log(` ✓ ${rel}`);
|
|
77
99
|
}
|
|
78
100
|
|
|
79
|
-
const devCmd = `npx zquery dev${target !== process.cwd() ? ` ${dirArg}` : ''}`;
|
|
80
|
-
|
|
81
101
|
// Copy zquery.min.js from the package's pre-built dist into the project root
|
|
82
102
|
// so file:// previews and the dev/SSR servers all serve the same minified
|
|
83
103
|
// bundle that ships with the installed zero-query package. The dev server
|
|
84
104
|
// also intercepts requests for "zquery.min.js" and will fall back to the
|
|
85
105
|
// package copy if the file is missing, so this is a convenience for direct
|
|
86
106
|
// file access (Open in Browser, etc.).
|
|
107
|
+
const zqRoot = path.resolve(__dirname, '..', '..');
|
|
87
108
|
{
|
|
88
|
-
const
|
|
89
|
-
const zqMin = path.join(zqRoot, 'dist', 'zquery.min.js');
|
|
109
|
+
const zqMin = path.join(zqRoot, 'dist', 'zquery.min.js');
|
|
90
110
|
if (fs.existsSync(zqMin)) {
|
|
91
111
|
fs.copyFileSync(zqMin, path.join(target, 'zquery.min.js'));
|
|
92
112
|
console.log(` ✓ zquery.min.js`);
|
|
93
113
|
}
|
|
94
114
|
}
|
|
95
115
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
// (works both in local dev and when installed from npm)
|
|
100
|
-
const zqRoot = path.resolve(__dirname, '..', '..');
|
|
101
|
-
try {
|
|
102
|
-
execSync(`npm install "${zqRoot}"`, { cwd: target, stdio: 'inherit' });
|
|
103
|
-
} catch {
|
|
104
|
-
console.error(`\n ✗ npm install failed. Run it manually:\n\n cd ${dirArg || '.'}\n npm install\n node server/index.js\n`);
|
|
105
|
-
process.exit(1);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Copy zquery.min.js into the project root so the SSR server can serve it
|
|
109
|
-
const zqMin = path.join(target, 'node_modules', 'zero-query', 'dist', 'zquery.min.js');
|
|
110
|
-
if (fs.existsSync(zqMin)) {
|
|
111
|
-
fs.copyFileSync(zqMin, path.join(target, 'zquery.min.js'));
|
|
112
|
-
console.log(` ✓ zquery.min.js`);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
console.log(`\n Starting SSR server...\n`);
|
|
116
|
-
const child = spawn('node', ['server/index.js'], { cwd: target, stdio: 'inherit' });
|
|
117
|
-
|
|
118
|
-
setTimeout(() => {
|
|
119
|
-
const open = process.platform === 'win32' ? 'start'
|
|
120
|
-
: process.platform === 'darwin' ? 'open' : 'xdg-open';
|
|
121
|
-
try { execSync(`${open} http://localhost:3000`, { stdio: 'ignore' }); } catch {}
|
|
122
|
-
}, 500);
|
|
123
|
-
|
|
124
|
-
process.on('SIGINT', () => { child.kill(); process.exit(); });
|
|
125
|
-
process.on('SIGTERM', () => { child.kill(); process.exit(); });
|
|
126
|
-
child.on('exit', (code) => process.exit(code || 0));
|
|
127
|
-
return; // keep process alive for the server
|
|
128
|
-
} else if (variant === 'webrtc') {
|
|
129
|
-
console.log(`\n Installing dependencies...\n`);
|
|
116
|
+
// ---- Install dependencies (all variants ship a package.json) ----
|
|
117
|
+
console.log(`\n Installing dependencies...\n`);
|
|
118
|
+
try {
|
|
130
119
|
// Install zero-query from the same package that provides this CLI so
|
|
131
|
-
// local-dev and published-npm both work.
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
console.error(`\n ✗ npm install failed. Run it manually:\n\n cd ${dirArg || '.'}\n npm install\n npm start\n`);
|
|
141
|
-
process.exit(1);
|
|
142
|
-
}
|
|
120
|
+
// local-dev and published-npm both work. Any extra devDependencies in
|
|
121
|
+
// the scaffold's package.json (e.g. @zero-server/* for webrtc) come in
|
|
122
|
+
// on the follow-up plain `npm install`.
|
|
123
|
+
execSync(`npm install "${zqRoot}"`, { cwd: target, stdio: 'inherit' });
|
|
124
|
+
execSync(`npm install`, { cwd: target, stdio: 'inherit' });
|
|
125
|
+
} catch {
|
|
126
|
+
console.error(`\n ✗ npm install failed. Run it manually:\n\n cd ${dirArg || '.'}\n npm install\n npm start\n`);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
143
129
|
|
|
144
|
-
|
|
145
|
-
|
|
130
|
+
// Refresh zquery.min.js from the freshly installed package (preferred
|
|
131
|
+
// over the pre-copied one above so post-install rebuilds win).
|
|
132
|
+
{
|
|
146
133
|
const zqMin = path.join(target, 'node_modules', 'zero-query', 'dist', 'zquery.min.js');
|
|
147
134
|
if (fs.existsSync(zqMin)) {
|
|
148
135
|
fs.copyFileSync(zqMin, path.join(target, 'zquery.min.js'));
|
|
149
|
-
console.log(` ✓ zquery.min.js`);
|
|
150
136
|
}
|
|
137
|
+
}
|
|
151
138
|
|
|
139
|
+
// ---- Launch the right server for the variant ----
|
|
140
|
+
if (variant === 'ssr') {
|
|
141
|
+
console.log(`\n Starting SSR server on http://localhost:3000 ...\n`);
|
|
142
|
+
setTimeout(() => openBrowser('http://localhost:3000'), 500);
|
|
143
|
+
runAndExit('node', ['server/index.js'], target);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (variant === 'webrtc') {
|
|
152
148
|
console.log(`
|
|
153
149
|
Camera, microphone, and screen-share are OFF by default - users opt in
|
|
154
150
|
from inside the room. Optional env vars:
|
|
@@ -157,26 +153,19 @@ function createProject(args) {
|
|
|
157
153
|
|
|
158
154
|
Starting WebRTC signaling + static server on http://localhost:3000 ...
|
|
159
155
|
`);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
setTimeout(() => {
|
|
164
|
-
const open = process.platform === 'win32' ? 'start'
|
|
165
|
-
: process.platform === 'darwin' ? 'open' : 'xdg-open';
|
|
166
|
-
try { execSync(`${open} http://localhost:3000`, { stdio: 'ignore' }); } catch {}
|
|
167
|
-
}, 500);
|
|
168
|
-
|
|
169
|
-
process.on('SIGINT', () => { child.kill(); process.exit(); });
|
|
170
|
-
process.on('SIGTERM', () => { child.kill(); process.exit(); });
|
|
171
|
-
child.on('exit', (code) => process.exit(code || 0));
|
|
172
|
-
return; // keep process alive for the server
|
|
173
|
-
} else {
|
|
174
|
-
console.log(`
|
|
175
|
-
Done! Next steps:
|
|
176
|
-
|
|
177
|
-
${devCmd}
|
|
178
|
-
`);
|
|
156
|
+
setTimeout(() => openBrowser('http://localhost:3000'), 500);
|
|
157
|
+
runAndExit('node', ['server/index.js'], target);
|
|
158
|
+
return;
|
|
179
159
|
}
|
|
160
|
+
|
|
161
|
+
// default / minimal: invoke the local zquery CLI's dev command. We point
|
|
162
|
+
// it at this same package's CLI entry so it works regardless of whether
|
|
163
|
+
// node_modules/.bin/zquery resolved a shim correctly (Windows .cmd quirks
|
|
164
|
+
// and all).
|
|
165
|
+
console.log(`\n Starting dev server on http://localhost:3100 ...\n`);
|
|
166
|
+
setTimeout(() => openBrowser('http://localhost:3100'), 800);
|
|
167
|
+
const cliEntry = path.resolve(__dirname, '..', 'index.js');
|
|
168
|
+
runAndExit('node', [cliEntry, 'dev', target], target);
|
|
180
169
|
}
|
|
181
170
|
|
|
182
171
|
module.exports = createProject;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{NAME}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "npx zquery dev",
|
|
7
|
+
"dev": "npx zquery dev",
|
|
8
|
+
"build": "npx zquery build",
|
|
9
|
+
"bundle": "npx zquery bundle"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"zero-query": "latest"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{NAME}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "npx zquery dev",
|
|
7
|
+
"dev": "npx zquery dev",
|
|
8
|
+
"build": "npx zquery build",
|
|
9
|
+
"bundle": "npx zquery bundle"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"zero-query": "latest"
|
|
13
|
+
}
|
|
14
|
+
}
|