@hyperspan/framework 0.1.0 → 0.1.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/package.json CHANGED
@@ -1,13 +1,22 @@
1
1
  {
2
2
  "name": "@hyperspan/framework",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Hyperspan Web Framework",
5
- "type": "module",
6
- "module": "src/server.ts",
5
+ "main": "dist/index.js",
7
6
  "public": true,
8
7
  "publishConfig": {
9
8
  "access": "public"
10
9
  },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./assets": {
16
+ "types": "./dist/assets.d.ts",
17
+ "default": "./dist/assets.js"
18
+ }
19
+ },
11
20
  "author": "Vance Lucas <vance@vancelucas.com>",
12
21
  "license": "BSD-3-Clause",
13
22
  "keywords": [
@@ -23,18 +32,22 @@
23
32
  "homepage": "https://www.hyperspan.dev",
24
33
  "repository": {
25
34
  "type": "git",
26
- "url": "https://github.com/vlucas/hyperspan-framework"
35
+ "url": "git+https://github.com/vlucas/hyperspan.git"
27
36
  },
28
37
  "bugs": {
29
- "url": "https://github.com/vlucas/hyperspan-framework/issues"
38
+ "url": "https://github.com/vlucas/hyperspan/issues"
30
39
  },
31
40
  "scripts": {
32
- "test": "bun test"
41
+ "build": "bun ./build.ts",
42
+ "clean": "rm -rf dist",
43
+ "test": "bun test",
44
+ "prepack": "npm run clean && npm run build"
33
45
  },
34
46
  "devDependencies": {
35
47
  "@types/bun": "^1.1.9",
36
48
  "@types/node": "^22.5.5",
37
49
  "@types/react": "^19.1.0",
50
+ "bun-plugin-dts": "^0.3.0",
38
51
  "bun-types": "latest",
39
52
  "prettier": "^3.2.5"
40
53
  },
@@ -42,10 +55,10 @@
42
55
  "typescript": "^5.0.0"
43
56
  },
44
57
  "dependencies": {
45
- "@hyperspan/html": "^0.1.0",
58
+ "@hyperspan/html": "^0.1.1",
46
59
  "@preact/compat": "^18.3.1",
47
60
  "hono": "^4.7.4",
48
61
  "isbot": "^5.1.25",
49
- "valibot": "^1.0.0-rc.3"
62
+ "zod": "^4.0.0-beta.20250415T232143"
50
63
  }
51
64
  }
package/src/assets.ts CHANGED
@@ -3,7 +3,7 @@ import { md5 } from './clientjs/md5';
3
3
  import { readdir } from 'node:fs/promises';
4
4
  import { resolve } from 'node:path';
5
5
 
6
- export const IS_PROD = process.env.NODE_ENV === 'production';
6
+ const IS_PROD = process.env.NODE_ENV === 'production';
7
7
  const PWD = import.meta.dir;
8
8
 
9
9
  /**
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './server';
package/src/server.ts CHANGED
@@ -1,86 +1,16 @@
1
- import { readdir } from 'node:fs/promises';
2
- import { basename, extname, join } from 'node:path';
3
- import { TmplHtml, html, renderStream, renderAsync, render } from '@hyperspan/html';
4
- import { isbot } from 'isbot';
5
- import { buildClientJS, buildClientCSS } from './assets';
6
- import { Hono } from 'hono';
7
- import { serveStatic } from 'hono/bun';
8
- import type { Context, Handler } from 'hono';
9
-
10
- import * as v from 'valibot';
11
- import type {
12
- AnySchema,
13
- ArraySchema,
14
- BigintSchema,
15
- BooleanSchema,
16
- DateSchema,
17
- EnumSchema,
18
- GenericIssue,
19
- IntersectSchema,
20
- LazySchema,
21
- LiteralSchema,
22
- NullSchema,
23
- NullableSchema,
24
- NullishSchema,
25
- NumberSchema,
26
- ObjectSchema,
27
- ObjectWithRestSchema,
28
- OptionalSchema,
29
- PicklistSchema,
30
- PipeItem,
31
- RecordSchema,
32
- SchemaWithPipe,
33
- StrictObjectSchema,
34
- StrictTupleSchema,
35
- StringSchema,
36
- TupleSchema,
37
- TupleWithRestSchema,
38
- UndefinedSchema,
39
- UnionSchema,
40
- VariantSchema,
41
- } from 'valibot';
1
+ import {readdir} from 'node:fs/promises';
2
+ import {basename, extname, join} from 'node:path';
3
+ import {TmplHtml, html, renderStream, renderAsync, render} from '@hyperspan/html';
4
+ import {isbot} from 'isbot';
5
+ import {buildClientJS, buildClientCSS} from './assets';
6
+ import {Hono} from 'hono';
7
+ import {serveStatic} from 'hono/bun';
8
+ import * as z from 'zod';
9
+ import type {Context, Handler} from 'hono';
42
10
 
43
11
  export const IS_PROD = process.env.NODE_ENV === 'production';
44
- const PWD = import.meta.dir;
45
12
  const CWD = process.cwd();
46
13
 
47
- type NonPipeSchemas =
48
- | AnySchema
49
- | LiteralSchema<any, any>
50
- | NullSchema<any>
51
- | NumberSchema<any>
52
- | BigintSchema<any>
53
- | StringSchema<any>
54
- | BooleanSchema<any>
55
- | NullableSchema<any, any>
56
- | StrictObjectSchema<any, any>
57
- | ObjectSchema<any, any>
58
- | ObjectWithRestSchema<any, any, any>
59
- | RecordSchema<any, any, any>
60
- | ArraySchema<any, any>
61
- | TupleSchema<any, any>
62
- | StrictTupleSchema<any, any>
63
- | TupleWithRestSchema<readonly any[], any, any>
64
- | IntersectSchema<any, any>
65
- | UnionSchema<any, any>
66
- | VariantSchema<any, any, any>
67
- | PicklistSchema<any, any>
68
- | EnumSchema<any, any>
69
- | LazySchema<any>
70
- | DateSchema<any>
71
- | NullishSchema<any, any>
72
- | OptionalSchema<any, any>
73
- | UndefinedSchema<any>;
74
-
75
- type PipeSchema = SchemaWithPipe<[NonPipeSchemas, ...PipeItem<any, any, GenericIssue<any>>[]]>;
76
- // Type inference for valibot taken from:
77
- // @link https://github.com/gcornut/valibot-json-schema/blob/main/src/toJSONSchema/schemas.ts
78
- export type TSupportedSchema = NonPipeSchemas | PipeSchema;
79
-
80
- /**
81
- * ===========================================================================
82
- */
83
-
84
14
  /**
85
15
  * Route
86
16
  * Define a route that can handle a direct HTTP request
@@ -114,7 +44,7 @@ export function createComponent(render: () => THSComponentReturn | Promise<THSCo
114
44
  */
115
45
  export function createForm(
116
46
  renderForm: (data?: any) => THSResponseTypes,
117
- schema?: TSupportedSchema | null
47
+ schema?: z.ZodSchema | null
118
48
  ): HSFormRoute {
119
49
  return new HSFormRoute(renderForm, schema);
120
50
  }
@@ -165,12 +95,12 @@ export class HSFormRoute {
165
95
  _handlers: Record<string, Handler> = {};
166
96
  _form: THSFormRenderer;
167
97
  _methods: null | string[] = null;
168
- _schema: null | TSupportedSchema = null;
98
+ _schema: null | z.ZodSchema = null;
169
99
 
170
- constructor(renderForm: THSFormRenderer, schema: TSupportedSchema | null = null) {
100
+ constructor(renderForm: THSFormRenderer, schema: z.ZodSchema | null = null) {
171
101
  // Haz schema?
172
102
  if (schema) {
173
- type TSchema = v.InferInput<typeof schema>;
103
+ type TSchema = z.infer<typeof schema>;
174
104
  this._form = renderForm as (data: TSchema) => THSResponseTypes;
175
105
  this._schema = schema;
176
106
  } else {
@@ -178,7 +108,7 @@ export class HSFormRoute {
178
108
  }
179
109
 
180
110
  // GET request is render form by default
181
- this._handlers.GET = (ctx: Context) => renderForm(this.getDefaultData());
111
+ this._handlers.GET = () => renderForm(this.getDefaultData());
182
112
  }
183
113
 
184
114
  // Form data
@@ -187,8 +117,8 @@ export class HSFormRoute {
187
117
  return {};
188
118
  }
189
119
 
190
- type TSchema = v.InferInput<typeof this._schema>;
191
- const data = v.parse(this._schema, {});
120
+ type TSchema = z.infer<typeof this._schema>;
121
+ const data = z.parse(this._schema, {});
192
122
  return data as TSchema;
193
123
  }
194
124
 
@@ -263,7 +193,7 @@ export async function runFileRoute(RouteModule: any, context: Context): Promise<
263
193
  if (!routeMethodHandler) {
264
194
  return new Response('Method Not Allowed', {
265
195
  status: 405,
266
- headers: { 'content-type': 'text/plain' },
196
+ headers: {'content-type': 'text/plain'},
267
197
  });
268
198
  }
269
199
 
@@ -305,13 +235,13 @@ async function runAPIRoute(routeFn: any, context: Context, middlewareResult?: an
305
235
 
306
236
  return context.json(
307
237
  {
308
- meta: { success: false },
238
+ meta: {success: false},
309
239
  data: {
310
240
  message: e.message,
311
241
  stack: IS_PROD ? undefined : e.stack?.split('\n'),
312
242
  },
313
243
  },
314
- { status: 500 }
244
+ {status: 500}
315
245
  );
316
246
  }
317
247
  }
@@ -337,7 +267,7 @@ async function showErrorReponse(context: Context, err: Error) {
337
267
  export type THSServerConfig = {
338
268
  appDir: string;
339
269
  staticFileRoot: string;
340
- rewrites?: Array<{ source: string; destination: string }>;
270
+ rewrites?: Array<{source: string; destination: string}>;
341
271
  // For customizing the routes and adding your own...
342
272
  beforeRoutesAdded?: (app: Hono) => void;
343
273
  afterRoutesAdded?: (app: Hono) => void;
@@ -357,7 +287,7 @@ export async function buildRoutes(config: THSServerConfig): Promise<THSRouteMap[
357
287
  // Walk all pages and add them as routes
358
288
  const routesDir = join(config.appDir, 'routes');
359
289
  console.log(routesDir);
360
- const files = await readdir(routesDir, { recursive: true });
290
+ const files = await readdir(routesDir, {recursive: true});
361
291
  const routes: THSRouteMap[] = [];
362
292
 
363
293
  for (const file of files) {
@@ -379,7 +309,7 @@ export async function buildRoutes(config: THSServerConfig): Promise<THSRouteMap[
379
309
 
380
310
  if (dynamicPaths) {
381
311
  params = [];
382
- route = route.replace(ROUTE_SEGMENT, (match: string, p1: string, offset: number) => {
312
+ route = route.replace(ROUTE_SEGMENT, (match: string) => {
383
313
  const paramName = match.replace(/[^a-zA-Z_\.]+/g, '');
384
314
 
385
315
  if (match.includes('...')) {
@@ -423,7 +353,7 @@ export async function createServer(config: THSServerConfig): Promise<Hono> {
423
353
  const fullRouteFile = join(CWD, route.file);
424
354
  const routePattern = normalizePath(route.route);
425
355
 
426
- routeMap.push({ route: routePattern, file: route.file });
356
+ routeMap.push({route: routePattern, file: route.file});
427
357
 
428
358
  // Import route
429
359
  const routeModule = await import(fullRouteFile);
@@ -443,7 +373,7 @@ export async function createServer(config: THSServerConfig): Promise<Hono> {
443
373
  app.get('/', (context) => {
444
374
  return context.text(
445
375
  'No routes found. Add routes to app/routes. Example: `app/routes/index.ts`',
446
- { status: 404 }
376
+ {status: 404}
447
377
  );
448
378
  });
449
379
  }
@@ -466,7 +396,7 @@ export async function createServer(config: THSServerConfig): Promise<Hono> {
466
396
  );
467
397
 
468
398
  app.notFound((context) => {
469
- return context.text('Not... found?', { status: 404 });
399
+ return context.text('Not... found?', {status: 404});
470
400
  });
471
401
 
472
402
  return app;
@@ -501,7 +431,7 @@ export function createReadableStreamFromAsyncGenerator(output: AsyncGenerator) {
501
431
  return new ReadableStream({
502
432
  async start(controller) {
503
433
  while (true) {
504
- const { done, value } = await output.next();
434
+ const {done, value} = await output.next();
505
435
 
506
436
  if (done) {
507
437
  controller.close();