glashjs 0.13.0 → 0.13.1

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/bin/glash.mjs CHANGED
@@ -12,7 +12,10 @@ import { createProject } from '../src/create.mjs';
12
12
  import { generateTypedRoutes } from '../src/typed-routes.mjs';
13
13
 
14
14
  const VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
15
- const [, , cmd, ...rest] = process.argv;
15
+ let [, , cmd, ...rest] = process.argv;
16
+ if (cmd === 'run') {
17
+ cmd = rest.shift() || 'dev';
18
+ }
16
19
 
17
20
  function arg(name, fallback) {
18
21
  const i = rest.indexOf(name);
@@ -55,11 +58,12 @@ function lanAddresses() {
55
58
  async function serve(dev) {
56
59
  const root = arg('--root', process.cwd());
57
60
  const { listen, cfg, routes } = await createGlashServer({ root, dev });
58
- const port = Number(arg('--port', cfg.port || 3000));
59
- await listen(port);
61
+ const preferredPort = Number(arg('--port', cfg.port || 3000));
62
+ const port = await listenOnAvailablePort(listen, preferredPort);
60
63
  const pages = routes.filter((r) => !r.isApi).length;
61
64
  const apis = routes.filter((r) => r.isApi).length;
62
65
  console.log(`\nglashjs ${dev ? 'dev' : 'serve'} — "${cfg.name}"`);
66
+ if (port !== preferredPort) console.log(` Port ${preferredPort} is in use; using ${port} instead.`);
63
67
  console.log(` ${pages} page route(s), ${apis} api route(s)`);
64
68
  routes.forEach((r) => console.log(` ${r.isApi ? 'api ' : 'page'} ${r.pattern}`));
65
69
  console.log('');
@@ -69,6 +73,18 @@ async function serve(dev) {
69
73
  console.log('');
70
74
  }
71
75
 
76
+ async function listenOnAvailablePort(listen, preferredPort) {
77
+ for (let port = preferredPort; port < preferredPort + 20; port += 1) {
78
+ try {
79
+ await listen(port);
80
+ return port;
81
+ } catch (error) {
82
+ if (error?.code !== 'EADDRINUSE') throw error;
83
+ }
84
+ }
85
+ throw new Error(`No available port found from ${preferredPort} to ${preferredPort + 19}`);
86
+ }
87
+
72
88
  async function main() {
73
89
  switch (cmd) {
74
90
  case 'create':
@@ -144,6 +160,7 @@ async function main() {
144
160
  console.log(`glashjs — fast, offline-capable, hard-to-hack sites
145
161
 
146
162
  Usage: (run as "glashjs <cmd>"; "glash <cmd>" also works unless the glashdb deploy CLI owns that name)
163
+ glashjs run dev Alias for glashjs dev (also: glash run dev)
147
164
  glashjs create [name] Create a new Glash project (interactive)
148
165
  glashjs dev [--port 3000] Run the dev server (routing, SSR, API, live reload) + Network preview URL
149
166
  glashjs serve [--port 3000] Run the production server over routes/ + built assets
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glashjs",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "glashjs — The Postgres-native full-stack framework for builders who want to ship without DevOps. Framework, hosting, database, auth, and deploy in one GlashDB-native runtime.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -120,7 +120,19 @@ export async function createGlashServer({ root = process.cwd(), dev = false } =
120
120
  });
121
121
 
122
122
  const listen = (port = cfg.port || 3000, host = '0.0.0.0') =>
123
- new Promise((resolve) => server.listen(port, host, () => resolve({ port, host })));
123
+ new Promise((resolve, reject) => {
124
+ const onError = (error) => {
125
+ server.off('listening', onListening);
126
+ reject(error);
127
+ };
128
+ const onListening = () => {
129
+ server.off('error', onError);
130
+ resolve({ port, host });
131
+ };
132
+ server.once('error', onError);
133
+ server.once('listening', onListening);
134
+ server.listen(port, host);
135
+ });
124
136
 
125
137
  return { server, listen, cfg, routes, routesDir, outDir };
126
138
  }