glashjs 0.13.2 → 0.13.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glashjs",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
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": {
@@ -0,0 +1,16 @@
1
+ // Minimal next/dynamic compatibility for migrated client components.
2
+ import { h } from 'preact';
3
+ import { lazy, Suspense } from 'preact/compat';
4
+
5
+ export default function dynamic(loader, options = {}) {
6
+ const Lazy = lazy(async () => {
7
+ const mod = await loader();
8
+ return { default: mod.default || mod };
9
+ });
10
+ const Loading = options.loading;
11
+
12
+ return function DynamicComponent(props) {
13
+ const fallback = Loading ? h(Loading, props) : null;
14
+ return h(Suspense, { fallback }, h(Lazy, props));
15
+ };
16
+ }
@@ -0,0 +1,23 @@
1
+ // Minimal next/headers compatibility for migrated API helpers.
2
+ // Glash handlers should prefer ctx.headers/cookies, but these no-op shims keep
3
+ // shared Next-era utilities importable during migration.
4
+
5
+ function emptyCookieStore() {
6
+ return {
7
+ get: () => undefined,
8
+ getAll: () => [],
9
+ has: () => false,
10
+ set: () => {},
11
+ delete: () => {},
12
+ clear: () => {},
13
+ toString: () => '',
14
+ };
15
+ }
16
+
17
+ export function cookies() {
18
+ return emptyCookieStore();
19
+ }
20
+
21
+ export function headers() {
22
+ return new Headers();
23
+ }
@@ -0,0 +1,50 @@
1
+ // Minimal Next navigation compatibility for migrated Glash routes.
2
+ // These browser-first shims keep common client components running without
3
+ // dragging the Next runtime into the Glash server bundle.
4
+
5
+ function hrefOf(href) {
6
+ if (typeof href === 'string') return href;
7
+ if (href && typeof href === 'object') {
8
+ const pathname = href.pathname || '';
9
+ const query = href.query ? `?${new URLSearchParams(href.query).toString()}` : '';
10
+ const hash = href.hash || '';
11
+ return `${pathname}${query}${hash}`;
12
+ }
13
+ return '/';
14
+ }
15
+
16
+ export function useRouter() {
17
+ return {
18
+ push: (href) => { if (typeof window !== 'undefined') window.location.assign(hrefOf(href)); },
19
+ replace: (href) => { if (typeof window !== 'undefined') window.location.replace(hrefOf(href)); },
20
+ refresh: () => { if (typeof window !== 'undefined') window.location.reload(); },
21
+ back: () => { if (typeof window !== 'undefined') window.history.back(); },
22
+ forward: () => { if (typeof window !== 'undefined') window.history.forward(); },
23
+ prefetch: () => Promise.resolve(),
24
+ };
25
+ }
26
+
27
+ export function usePathname() {
28
+ return typeof window === 'undefined' ? '/' : window.location.pathname;
29
+ }
30
+
31
+ export function useSearchParams() {
32
+ return new URLSearchParams(typeof window === 'undefined' ? '' : window.location.search);
33
+ }
34
+
35
+ export function useParams() {
36
+ return {};
37
+ }
38
+
39
+ export function redirect(href) {
40
+ if (typeof window !== 'undefined') window.location.replace(hrefOf(href));
41
+ const error = new Error(`NEXT_REDIRECT:${hrefOf(href)}`);
42
+ error.digest = `NEXT_REDIRECT;replace;${hrefOf(href)};307;`;
43
+ throw error;
44
+ }
45
+
46
+ export function notFound() {
47
+ const error = new Error('NEXT_NOT_FOUND');
48
+ error.status = 404;
49
+ throw error;
50
+ }
@@ -16,7 +16,7 @@
16
16
  import { promises as fs, existsSync } from 'node:fs';
17
17
  import path from 'node:path';
18
18
  import { createHash } from 'node:crypto';
19
- import { pathToFileURL } from 'node:url';
19
+ import { fileURLToPath, pathToFileURL } from 'node:url';
20
20
 
21
21
  const MISSING = 'JSX/TSX routes need the optional peers: npm i esbuild preact preact-render-to-string';
22
22
 
@@ -38,13 +38,20 @@ async function preactRuntime() {
38
38
  return { h: _h, renderToString: _renderToString };
39
39
  }
40
40
 
41
- // Make migrated React/Next components compile + run under Preact.
41
+ const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
42
+
43
+ // Make migrated React/Next components compile + run under Preact/Glash.
42
44
  const REACT_ALIAS = {
43
45
  react: 'preact/compat',
44
46
  'react-dom': 'preact/compat',
45
47
  'react-dom/client': 'preact/compat',
46
48
  'react/jsx-runtime': 'preact/jsx-runtime',
47
49
  'react/jsx-dev-runtime': 'preact/jsx-runtime',
50
+ 'next/link': path.join(pkgRoot, 'components/link.mjs'),
51
+ 'next/image': path.join(pkgRoot, 'components/image.mjs'),
52
+ 'next/navigation': path.join(pkgRoot, 'next/navigation.mjs'),
53
+ 'next/dynamic': path.join(pkgRoot, 'next/dynamic.mjs'),
54
+ 'next/headers': path.join(pkgRoot, 'next/headers.mjs'),
48
55
  };
49
56
 
50
57
  export function isComponentRoute(file) {