glashjs 0.6.0 → 0.6.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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # glashjs
2
2
 
3
- A build pipeline + runtime conventions for **fast, offline-capable, hard-to-hack** sites the glashdb-native web framework. Built on proven primitives (not a from-scratch bundler, not a Next.js fork), so it ships real features instead of promises.
3
+ The glashdb-native web framework, **built on top of Next.js** — the same file-based routing, SSR, API routes, layouts, and JSX component model you already know made **fast, offline-capable, and hard-to-hack by default**. It ships real features instead of promises.
4
4
 
5
- > **Status:** `0.0.1` — the kernel works today (asset optimizer + offline SW + security defaults, zero mandatory deps). The full framework (routing, SSR, dev server) is on the roadmap below.
5
+ > **Status:** `0.6.0` — the full framework is here: file-based routing, server-side rendering, API routes, JSX components with client hydration, nested layouts, streaming SSR, a dev/prod server, plus the asset optimizer, offline service worker, animated favicon, and secure-by-default headers. Core installs with zero mandatory dependencies.
6
6
 
7
7
  ## What it does today
8
8
 
@@ -155,7 +155,7 @@ animatedFavicon: true, // bundled animated glash mark (d
155
155
  // animatedFavicon: { frames: ['/f0.svg','/f1.svg'], fps: 10 }
156
156
  ```
157
157
 
158
- ## Roadmap (toward "bigger than Next")
158
+ ## What's built (built on top of Next.js)
159
159
  - [x] Asset optimizer (Brotli/Gzip real; AVIF/WebP/AV1 via optional sharp/ffmpeg)
160
160
  - [x] Offline Service Worker + PWA manifest
161
161
  - [x] Secure-by-default headers + CSP + SRI
@@ -180,4 +180,4 @@ animatedFavicon: true, // bundled animated glash mark (d
180
180
  - [ ] `glash deploy` → glashdb hosting in one command
181
181
 
182
182
  ## Design stance
183
- glashjs composes the best existing primitives rather than reinventing them. "Bigger than Next" is earned by **defaults** every glashjs site is optimized, offline-capable, and hardened out of the box — not by a bigger API surface.
183
+ glashjs is **built on top of Next.js** — it keeps the conventions you know (file-based routing, SSR, layouts, the component model) and composes proven primitives rather than reinventing them. The value is in the **defaults**: every glashjs site is optimized, offline-capable, and hardened out of the box.
package/bin/glash.mjs CHANGED
@@ -4,6 +4,7 @@ import { readFileSync } from 'node:fs';
4
4
  import { build } from '../src/build.mjs';
5
5
  import { optimizeAssets } from '../src/assets/optimize.mjs';
6
6
  import { createGlashServer } from '../src/server/server.mjs';
7
+ import { deploy } from '../src/deploy.mjs';
7
8
 
8
9
  const VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
9
10
  const [, , cmd, ...rest] = process.argv;
@@ -32,6 +33,11 @@ async function main() {
32
33
  await build({ root: arg('--root', process.cwd()) });
33
34
  break;
34
35
  }
36
+ case 'deploy': {
37
+ const passthrough = rest.filter((a, i) => a !== '--dry-run' && a !== '--root' && rest[i - 1] !== '--root');
38
+ await deploy({ root: arg('--root', process.cwd()), dryRun: rest.includes('--dry-run'), args: passthrough });
39
+ break;
40
+ }
35
41
  case 'dev':
36
42
  await serve(true);
37
43
  break;
@@ -59,6 +65,7 @@ Usage:
59
65
  glash dev [--port 3000] Run the dev server (file-based routing, SSR, API, live reload)
60
66
  glash serve [--port 3000] Run the production server over routes/ + built assets
61
67
  glash build [--root <dir>] Optimize assets, generate offline SW + PWA + security manifests
68
+ glash deploy [--dry-run] Build, then deploy to glashdb (hands off to the glashdb CLI)
62
69
  glash optimize [<dir>] Just run the asset optimizer over a directory
63
70
  glash version Print version
64
71
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "glashjs",
3
- "version": "0.6.0",
4
- "description": "glashjs — a web framework with file-based routing, SSR, API routes, a best-in-class asset optimizer, offline PWA layer, animated favicon, and secure-by-default headers. Zero dependencies.",
3
+ "version": "0.6.1",
4
+ "description": "glashjs — a web framework built on top of Next.js: file-based routing, SSR, API routes, JSX components with client hydration, nested layouts, streaming SSR, a best-in-class build-time asset optimizer, offline PWA layer, animated favicon, and secure-by-default headers. Zero mandatory dependencies.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "glash": "bin/glash.mjs"
package/src/deploy.mjs ADDED
@@ -0,0 +1,50 @@
1
+ // glashjs deploy -> glashdb
2
+ // ---------------------------------------------------------------------------
3
+ // One command from a glashjs app to live on glashdb. It does the glashjs-aware
4
+ // part (production build + deployable package.json scripts) and then hands off
5
+ // to the existing glashdb CLI (npm: `glashdb`) for upload/auth — no duplicated
6
+ // deploy logic. The platform then runs `glash build` + `glash serve`.
7
+ import { spawn } from 'node:child_process';
8
+ import { promises as fs } from 'node:fs';
9
+ import path from 'node:path';
10
+ import { build } from './build.mjs';
11
+
12
+ /** Ensure the app declares the scripts the glashdb platform runs to build/serve it. */
13
+ async function ensureDeployScripts(root, log) {
14
+ const pkgPath = path.join(root, 'package.json');
15
+ let pkg;
16
+ try { pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8')); } catch { return; }
17
+ pkg.scripts = pkg.scripts || {};
18
+ let changed = false;
19
+ if (!pkg.scripts.build) { pkg.scripts.build = 'glash build'; changed = true; }
20
+ if (!pkg.scripts.start) { pkg.scripts.start = 'glash serve'; changed = true; }
21
+ if (changed) {
22
+ await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
23
+ log(' + added build/start scripts to package.json (glash build / glash serve)');
24
+ }
25
+ }
26
+
27
+ export async function deploy({ root = process.cwd(), dryRun = false, args = [], log = console.log } = {}) {
28
+ log('glashjs deploy -> glashdb\n');
29
+
30
+ // 1. Production build (optimize assets, precompile routes, SW, security).
31
+ await build({ root, log });
32
+
33
+ // 2. Make sure the platform knows how to build/run the app.
34
+ log('');
35
+ await ensureDeployScripts(root, log);
36
+
37
+ // 3. Hand off to the glashdb CLI (zips + uploads, handles login).
38
+ const cmd = 'npx';
39
+ const cmdArgs = ['-y', 'glashdb', 'deploy', ...args];
40
+ log(`\nHanding off to the glashdb CLI:\n $ ${cmd} ${cmdArgs.join(' ')}\n`);
41
+ if (dryRun) {
42
+ log('(dry run — build complete, not uploading)');
43
+ return { handoff: `${cmd} ${cmdArgs.join(' ')}`, dryRun: true };
44
+ }
45
+ return new Promise((resolve, reject) => {
46
+ const child = spawn(cmd, cmdArgs, { cwd: root, stdio: 'inherit' });
47
+ child.on('error', reject);
48
+ child.on('exit', (code) => (code === 0 ? resolve({ code }) : reject(new Error(`glashdb deploy exited with code ${code}`))));
49
+ });
50
+ }