@hyperspan/framework 0.0.2 → 0.0.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/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  > [!NOTE] > **Hyperspan is still in the early stages of development, your feedback is appreciated.**
4
4
 
5
- No JSX. No Virtual DOM. No hydration time. No nonsense. Just blazing fast HTML strings with reactive templates.
5
+ Hyperspan is a full-stack framework built with [Bun](https://bun.sh) that is focused on simplicity and ease of use.
6
6
 
7
- Hyperspan is a full-stack framework built with [Bun](https://bun.sh) that is focused on simplicity and perforamnce.
7
+ No JSX. No Virtual DOM. No hydration time. No nonsense. Just blazing fast HTML strings with reactive templates.
8
8
 
9
9
  ## Who Is Hyperspan For?
10
10
 
package/bun.lockb CHANGED
Binary file
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
2
  var __getProtoOf = Object.getPrototypeOf;
3
+ var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
6
  var __toESM = (mod, isNodeMode, target) => {
@@ -18,7 +18,7 @@ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports,
18
18
 
19
19
  // node_modules/escape-html/index.js
20
20
  var require_escape_html = __commonJS((exports, module) => {
21
- var escapeHtml = function(string) {
21
+ function escapeHtml(string) {
22
22
  var str = "" + string;
23
23
  var match = matchHtmlRegExp.exec(str);
24
24
  if (!match) {
@@ -55,7 +55,7 @@ var require_escape_html = __commonJS((exports, module) => {
55
55
  html += escape;
56
56
  }
57
57
  return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
58
- };
58
+ }
59
59
  /*!
60
60
  * escape-html
61
61
  * Copyright(c) 2012-2013 TJ Holowaychuk
@@ -71,7 +71,7 @@ var require_escape_html = __commonJS((exports, module) => {
71
71
  var import_escape_html = __toESM(require_escape_html(), 1);
72
72
 
73
73
  // src/clientjs/md5.js
74
- var md5cycle = function(x, k) {
74
+ function md5cycle(x, k) {
75
75
  var a = x[0], b = x[1], c = x[2], d = x[3];
76
76
  a = ff(a, b, c, d, k[0], 7, -680876936);
77
77
  d = ff(d, a, b, c, k[1], 12, -389564586);
@@ -141,24 +141,24 @@ var md5cycle = function(x, k) {
141
141
  x[1] = add32(b, x[1]);
142
142
  x[2] = add32(c, x[2]);
143
143
  x[3] = add32(d, x[3]);
144
- };
145
- var cmn = function(q, a, b, x, s, t) {
144
+ }
145
+ function cmn(q, a, b, x, s, t) {
146
146
  a = add32(add32(a, q), add32(x, t));
147
147
  return add32(a << s | a >>> 32 - s, b);
148
- };
149
- var ff = function(a, b, c, d, x, s, t) {
148
+ }
149
+ function ff(a, b, c, d, x, s, t) {
150
150
  return cmn(b & c | ~b & d, a, b, x, s, t);
151
- };
152
- var gg = function(a, b, c, d, x, s, t) {
151
+ }
152
+ function gg(a, b, c, d, x, s, t) {
153
153
  return cmn(b & d | c & ~d, a, b, x, s, t);
154
- };
155
- var hh = function(a, b, c, d, x, s, t) {
154
+ }
155
+ function hh(a, b, c, d, x, s, t) {
156
156
  return cmn(b ^ c ^ d, a, b, x, s, t);
157
- };
158
- var ii = function(a, b, c, d, x, s, t) {
157
+ }
158
+ function ii(a, b, c, d, x, s, t) {
159
159
  return cmn(c ^ (b | ~d), a, b, x, s, t);
160
- };
161
- var md51 = function(s) {
160
+ }
161
+ function md51(s) {
162
162
  var txt = "";
163
163
  var n = s.length, state = [1732584193, -271733879, -1732584194, 271733878], i;
164
164
  for (i = 64;i <= s.length; i += 64) {
@@ -177,28 +177,28 @@ var md51 = function(s) {
177
177
  tail[14] = n * 8;
178
178
  md5cycle(state, tail);
179
179
  return state;
180
- };
181
- var md5blk = function(s) {
180
+ }
181
+ function md5blk(s) {
182
182
  var md5blks = [], i;
183
183
  for (i = 0;i < 64; i += 4) {
184
184
  md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
185
185
  }
186
186
  return md5blks;
187
- };
188
- var rhex = function(n) {
187
+ }
188
+ function rhex(n) {
189
189
  var s = "", j = 0;
190
190
  for (;j < 4; j++)
191
191
  s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];
192
192
  return s;
193
- };
194
- var hex = function(x) {
193
+ }
194
+ function hex(x) {
195
195
  for (var i = 0;i < x.length; i++)
196
196
  x[i] = rhex(x[i]);
197
197
  return x.join("");
198
- };
199
- var add32 = function(a, b) {
198
+ }
199
+ function add32(a, b) {
200
200
  return a + b & 4294967295;
201
- };
201
+ }
202
202
  function md5(s) {
203
203
  return hex(md51(s));
204
204
  }
@@ -232,7 +232,7 @@ async function* _render(obj, promises = [], { js }) {
232
232
  kind = _typeOf(obj);
233
233
  value = obj;
234
234
  }
235
- if (value instanceof HSTemplate) {
235
+ if (value instanceof HSTemplate || value.__hsTemplate) {
236
236
  yield* renderToStream(value);
237
237
  } else if (typeof value.render !== "undefined") {
238
238
  value.id = id;
@@ -269,6 +269,9 @@ async function* _render(obj, promises = [], { js }) {
269
269
  case "json":
270
270
  yield "";
271
271
  break;
272
+ case "number":
273
+ yield String(value);
274
+ break;
272
275
  case "object":
273
276
  if (typeof value.render === "function") {
274
277
  yield value.render();
@@ -322,9 +325,9 @@ async function renderToString(template) {
322
325
  function compressHTMLString(str) {
323
326
  return str.replace(/(<(pre|script|style|textarea)[^]+?<\/\2)|(^|>)\s+|\s+(?=<|$)/g, "$1$3");
324
327
  }
325
- var randomId = function() {
328
+ function randomId() {
326
329
  return Math.random().toString(36).substring(2, 9);
327
- };
330
+ }
328
331
  function _typeOf(obj) {
329
332
  if (obj instanceof Promise)
330
333
  return "promise";
@@ -352,12 +355,12 @@ function _typeOf(obj) {
352
355
  return "json";
353
356
  return typeof obj;
354
357
  }
355
- var isGenerator = function(obj) {
358
+ function isGenerator(obj) {
356
359
  return obj && typeof obj.next == "function" && typeof obj.throw == "function";
357
- };
358
- var isPlainObject = function(val) {
360
+ }
361
+ function isPlainObject(val) {
359
362
  return Object == val.constructor;
360
- };
363
+ }
361
364
  function clientComponent(id, wc) {
362
365
  const comp = {
363
366
  ...wc,
@@ -414,7 +417,7 @@ function renderFunctionToString(fn) {
414
417
  }
415
418
  return fns;
416
419
  }
417
- var renderObjectToLiteralString = function(obj) {
420
+ function renderObjectToLiteralString(obj) {
418
421
  const lines = [];
419
422
  let str = 'hyperspan.wc.set("' + obj.id + '", {\n';
420
423
  for (const prop in obj) {
@@ -444,7 +447,7 @@ var renderObjectToLiteralString = function(obj) {
444
447
  str += lines.map((line) => line.join("") + ",").join("\n");
445
448
  str += "\n})";
446
449
  return str;
447
- };
450
+ }
448
451
  var IS_CLIENT = typeof window !== "undefined";
449
452
 
450
453
  class HSTemplate {
package/dist/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
2
  var __getProtoOf = Object.getPrototypeOf;
3
+ var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
6
  var __toESM = (mod, isNodeMode, target) => {
@@ -18,7 +18,7 @@ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports,
18
18
 
19
19
  // node_modules/escape-html/index.js
20
20
  var require_escape_html = __commonJS((exports, module) => {
21
- var escapeHtml = function(string) {
21
+ function escapeHtml(string) {
22
22
  var str = "" + string;
23
23
  var match = matchHtmlRegExp.exec(str);
24
24
  if (!match) {
@@ -55,7 +55,7 @@ var require_escape_html = __commonJS((exports, module) => {
55
55
  html += escape;
56
56
  }
57
57
  return lastIndex !== index ? html + str.substring(lastIndex, index) : html;
58
- };
58
+ }
59
59
  /*!
60
60
  * escape-html
61
61
  * Copyright(c) 2012-2013 TJ Holowaychuk
@@ -299,7 +299,7 @@ var require_trek_middleware = __commonJS((exports, module) => {
299
299
 
300
300
  // node_modules/@fastify/deepmerge/index.js
301
301
  var require_deepmerge = __commonJS((exports, module) => {
302
- var deepmergeConstructor = function(options) {
302
+ function deepmergeConstructor(options) {
303
303
  function isNotPrototypeKey(value) {
304
304
  return value !== "constructor" && value !== "prototype" && value !== "__proto__";
305
305
  }
@@ -403,7 +403,7 @@ var require_deepmerge = __commonJS((exports, module) => {
403
403
  return result;
404
404
  }
405
405
  return options && options.all ? _deepmergeAll : _deepmerge;
406
- };
406
+ }
407
407
  var JSON_PROTO = Object.getPrototypeOf({});
408
408
  module.exports = deepmergeConstructor;
409
409
  module.exports.default = deepmergeConstructor;
@@ -411,14 +411,14 @@ var require_deepmerge = __commonJS((exports, module) => {
411
411
  });
412
412
 
413
413
  // src/server.ts
414
- import {readdir} from "node:fs/promises";
415
- import {basename, extname, join, resolve} from "node:path";
414
+ import { readdir } from "node:fs/promises";
415
+ import { basename, extname, join, resolve } from "node:path";
416
416
 
417
417
  // src/html.ts
418
418
  var import_escape_html = __toESM(require_escape_html(), 1);
419
419
 
420
420
  // src/clientjs/md5.js
421
- var md5cycle = function(x, k) {
421
+ function md5cycle(x, k) {
422
422
  var a = x[0], b = x[1], c = x[2], d = x[3];
423
423
  a = ff(a, b, c, d, k[0], 7, -680876936);
424
424
  d = ff(d, a, b, c, k[1], 12, -389564586);
@@ -488,24 +488,24 @@ var md5cycle = function(x, k) {
488
488
  x[1] = add32(b, x[1]);
489
489
  x[2] = add32(c, x[2]);
490
490
  x[3] = add32(d, x[3]);
491
- };
492
- var cmn = function(q, a, b, x, s, t) {
491
+ }
492
+ function cmn(q, a, b, x, s, t) {
493
493
  a = add32(add32(a, q), add32(x, t));
494
494
  return add32(a << s | a >>> 32 - s, b);
495
- };
496
- var ff = function(a, b, c, d, x, s, t) {
495
+ }
496
+ function ff(a, b, c, d, x, s, t) {
497
497
  return cmn(b & c | ~b & d, a, b, x, s, t);
498
- };
499
- var gg = function(a, b, c, d, x, s, t) {
498
+ }
499
+ function gg(a, b, c, d, x, s, t) {
500
500
  return cmn(b & d | c & ~d, a, b, x, s, t);
501
- };
502
- var hh = function(a, b, c, d, x, s, t) {
501
+ }
502
+ function hh(a, b, c, d, x, s, t) {
503
503
  return cmn(b ^ c ^ d, a, b, x, s, t);
504
- };
505
- var ii = function(a, b, c, d, x, s, t) {
504
+ }
505
+ function ii(a, b, c, d, x, s, t) {
506
506
  return cmn(c ^ (b | ~d), a, b, x, s, t);
507
- };
508
- var md51 = function(s) {
507
+ }
508
+ function md51(s) {
509
509
  var txt = "";
510
510
  var n = s.length, state = [1732584193, -271733879, -1732584194, 271733878], i;
511
511
  for (i = 64;i <= s.length; i += 64) {
@@ -524,28 +524,28 @@ var md51 = function(s) {
524
524
  tail[14] = n * 8;
525
525
  md5cycle(state, tail);
526
526
  return state;
527
- };
528
- var md5blk = function(s) {
527
+ }
528
+ function md5blk(s) {
529
529
  var md5blks = [], i;
530
530
  for (i = 0;i < 64; i += 4) {
531
531
  md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
532
532
  }
533
533
  return md5blks;
534
- };
535
- var rhex = function(n) {
534
+ }
535
+ function rhex(n) {
536
536
  var s = "", j = 0;
537
537
  for (;j < 4; j++)
538
538
  s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];
539
539
  return s;
540
- };
541
- var hex = function(x) {
540
+ }
541
+ function hex(x) {
542
542
  for (var i = 0;i < x.length; i++)
543
543
  x[i] = rhex(x[i]);
544
544
  return x.join("");
545
- };
546
- var add32 = function(a, b) {
545
+ }
546
+ function add32(a, b) {
547
547
  return a + b & 4294967295;
548
- };
548
+ }
549
549
  function md5(s) {
550
550
  return hex(md51(s));
551
551
  }
@@ -579,7 +579,7 @@ async function* _render(obj, promises = [], { js }) {
579
579
  kind = _typeOf(obj);
580
580
  value = obj;
581
581
  }
582
- if (value instanceof HSTemplate) {
582
+ if (value instanceof HSTemplate || value.__hsTemplate) {
583
583
  yield* renderToStream(value);
584
584
  } else if (typeof value.render !== "undefined") {
585
585
  value.id = id;
@@ -616,6 +616,9 @@ async function* _render(obj, promises = [], { js }) {
616
616
  case "json":
617
617
  yield "";
618
618
  break;
619
+ case "number":
620
+ yield String(value);
621
+ break;
619
622
  case "object":
620
623
  if (typeof value.render === "function") {
621
624
  yield value.render();
@@ -666,9 +669,9 @@ async function renderToString(template) {
666
669
  }
667
670
  return result;
668
671
  }
669
- var randomId = function() {
672
+ function randomId() {
670
673
  return Math.random().toString(36).substring(2, 9);
671
- };
674
+ }
672
675
  function _typeOf(obj) {
673
676
  if (obj instanceof Promise)
674
677
  return "promise";
@@ -696,12 +699,12 @@ function _typeOf(obj) {
696
699
  return "json";
697
700
  return typeof obj;
698
701
  }
699
- var isGenerator = function(obj) {
702
+ function isGenerator(obj) {
700
703
  return obj && typeof obj.next == "function" && typeof obj.throw == "function";
701
- };
702
- var isPlainObject = function(val) {
704
+ }
705
+ function isPlainObject(val) {
703
706
  return Object == val.constructor;
704
- };
707
+ }
705
708
  function renderFunctionToString(fn) {
706
709
  let fns = fn.toString();
707
710
  const firstLine = fns.split("\n")[0];
@@ -734,7 +737,7 @@ html.raw = (value) => {
734
737
  };
735
738
 
736
739
  // node_modules/isbot/index.mjs
737
- var getPattern = function() {
740
+ function getPattern() {
738
741
  if (pattern instanceof RegExp) {
739
742
  return pattern;
740
743
  }
@@ -744,10 +747,10 @@ var getPattern = function() {
744
747
  pattern = naivePattern;
745
748
  }
746
749
  return pattern;
747
- };
748
- var isbot = function(userAgent) {
750
+ }
751
+ function isbot(userAgent) {
749
752
  return Boolean(userAgent) && getPattern().test(userAgent);
750
- };
753
+ }
751
754
  var fullPattern = " daum[ /]| deusu/| yadirectfetcher|(?:^|[^g])news(?!sapphire)|(?<! (?:channel/|google/))google(?!(app|/google| pixel))|(?<! cu)bots?(?:\\b|_)|(?<!(?:lib))http|(?<![hg]m)score|@[a-z][\\w-]+\\.|\\(\\)|\\.com\\b|\\btime/|^<|^[\\w \\.\\-\\(?:\\):]+(?:/v?\\d+(?:\\.\\d+)?(?:\\.\\d{1,10})*?)?(?:,|$)|^[^ ]{50,}$|^\\d+\\b|^\\w*search\\b|^\\w+/[\\w\\(\\)]*$|^active|^ad muncher|^amaya|^avsdevicesdk/|^biglotron|^bot|^bw/|^clamav[ /]|^client/|^cobweb/|^custom|^ddg[_-]android|^discourse|^dispatch/\\d|^downcast/|^duckduckgo|^facebook|^getright/|^gozilla/|^hobbit|^hotzonu|^hwcdn/|^jeode/|^jetty/|^jigsaw|^microsoft bits|^movabletype|^mozilla/5\\.0\\s[a-z\\.-]+$|^mozilla/\\d\\.\\d \\(compatible;?\\)$|^mozilla/\\d\\.\\d \\w*$|^navermailapp|^netsurf|^offline|^owler|^php|^postman|^python|^rank|^read|^reed|^rest|^rss|^snapchat|^space bison|^svn|^swcd |^taringa|^thumbor/|^track|^valid|^w3c|^webbandit/|^webcopier|^wget|^whatsapp|^wordpress|^xenu link sleuth|^yahoo|^yandex|^zdm/\\d|^zoom marketplace/|^{{.*}}$|adscanner/|analyzer|archive|ask jeeves/teoma|bit\\.ly/|bluecoat drtr|browsex|burpcollaborator|capture|catch|check\\b|checker|chrome-lighthouse|chromeframe|classifier|cloudflare|convertify|crawl|cypress/|dareboost|datanyze|dejaclick|detect|dmbrowser|download|evc-batch/|exaleadcloudview|feed|firephp|functionize|gomezagent|headless|httrack|hubspot marketing grader|hydra|ibisbrowser|images|infrawatch|insight|inspect|iplabel|ips-agent|java(?!;)|jsjcw_scanner|library|linkcheck|mail\\.ru/|manager|measure|neustar wpm|node|nutch|offbyone|optimize|pageburst|pagespeed|parser|perl|phantomjs|pingdom|powermarks|preview|proxy|ptst[ /]\\d|reputation|resolver|retriever|rexx;|rigor|rss\\b|scanner\\.|scrape|server|sogou|sparkler/|speedcurve|spider|splash|statuscake|supercleaner|synapse|synthetic|tools|torrent|trace|transcoder|url|virtuoso|wappalyzer|webglance|webkit2png|whatcms/|zgrab";
752
755
  var naivePattern = /bot|crawl|http|lighthouse|scan|search|spider/i;
753
756
  var pattern;
@@ -755,7 +758,7 @@ var pattern;
755
758
  // src/app.ts
756
759
  var import_trek_router = __toESM(require_trek_router(), 1);
757
760
  var import_trek_middleware = __toESM(require_trek_middleware(), 1);
758
- var deepmerge = __toESM(require_deepmerge(), 1);
761
+ var import_deepmerge = __toESM(require_deepmerge(), 1);
759
762
 
760
763
  // node_modules/@mjackson/headers/dist/lib/param-values.js
761
764
  function parseParams(input, delimiter = ";") {
@@ -1022,7 +1025,7 @@ class CacheControl {
1022
1025
  }
1023
1026
  }
1024
1027
  // node_modules/@mjackson/headers/dist/lib/content-disposition.js
1025
- var decodeFilenameSplat = function(value) {
1028
+ function decodeFilenameSplat(value) {
1026
1029
  let match = value.match(/^([\w-]+)'([^']*)'(.+)$/);
1027
1030
  if (!match)
1028
1031
  return null;
@@ -1036,12 +1039,12 @@ var decodeFilenameSplat = function(value) {
1036
1039
  console.warn(`Failed to decode filename from charset ${charset}:`, error);
1037
1040
  return decodedFilename;
1038
1041
  }
1039
- };
1040
- var percentDecode = function(value) {
1042
+ }
1043
+ function percentDecode(value) {
1041
1044
  return value.replace(/\+/g, " ").replace(/%([0-9A-Fa-f]{2})/g, (_, hex2) => {
1042
1045
  return String.fromCharCode(parseInt(hex2, 16));
1043
1046
  });
1044
- };
1047
+ }
1045
1048
 
1046
1049
  class ContentDisposition {
1047
1050
  filename;
@@ -1601,7 +1604,7 @@ class SuperHeaders extends Headers {
1601
1604
  function normalizePath(urlPath) {
1602
1605
  return (urlPath.endsWith("/") ? urlPath.substring(0, urlPath.length - 1) : urlPath).toLowerCase() || "/";
1603
1606
  }
1604
- var mergeAll = deepmerge.default({ all: true });
1607
+ var mergeAll = import_deepmerge.default({ all: true });
1605
1608
 
1606
1609
  class HSRequestContext {
1607
1610
  req;
@@ -1706,10 +1709,10 @@ class HSApp {
1706
1709
  }
1707
1710
 
1708
1711
  // src/server.ts
1709
- var requestIsBot = function(req) {
1712
+ function requestIsBot(req) {
1710
1713
  const ua = req.headers.get("User-Agent");
1711
1714
  return ua ? isbot(ua) : false;
1712
- };
1715
+ }
1713
1716
  async function runFileRoute(routeFile, context) {
1714
1717
  const req = context.req;
1715
1718
  const url = new URL(req.url);
@@ -1807,7 +1810,7 @@ async function buildRoutes(config) {
1807
1810
  });
1808
1811
  }
1809
1812
  routes.push({
1810
- file,
1813
+ file: join("./", routesDir, file),
1811
1814
  route: route || "/",
1812
1815
  params
1813
1816
  });
@@ -1816,50 +1819,50 @@ async function buildRoutes(config) {
1816
1819
  }
1817
1820
  async function createServer(config) {
1818
1821
  await Promise.all([buildClientJS(), buildClientCSS()]);
1819
- const app2 = new HSApp;
1820
- app2.defaultRoute(() => {
1822
+ const app = new HSApp;
1823
+ app.defaultRoute(() => {
1821
1824
  return new Response("Not... found?", { status: 404 });
1822
1825
  });
1823
- config.beforeRoutesAdded && config.beforeRoutesAdded(app2);
1826
+ config.beforeRoutesAdded && config.beforeRoutesAdded(app);
1824
1827
  const fileRoutes = await buildRoutes(config);
1825
1828
  const routeMap = [];
1826
1829
  for (let i = 0;i < fileRoutes.length; i++) {
1827
1830
  let route = fileRoutes[i];
1828
- const fullRouteFile = join("../../", config.appDir, "routes", route.file);
1831
+ const fullRouteFile = join(CWD, route.file);
1829
1832
  const routePattern = normalizePath(route.route);
1830
- routeMap.push({ route: routePattern, file: config.appDir + "/routes/" + route.file });
1831
- app2.all(routePattern, async (context) => {
1833
+ routeMap.push({ route: routePattern, file: route.file });
1834
+ app.all(routePattern, async (context) => {
1832
1835
  const matchedRoute = await runFileRoute(fullRouteFile, context);
1833
1836
  if (matchedRoute) {
1834
1837
  return matchedRoute;
1835
1838
  }
1836
- return app2._defaultRoute(context);
1839
+ return app._defaultRoute(context);
1837
1840
  });
1838
1841
  }
1839
1842
  if (!IS_PROD) {
1840
1843
  console.log("[Hyperspan] File system routes (in app/routes):");
1841
1844
  console.table(routeMap);
1842
1845
  }
1843
- config.afterRoutesAdded && config.afterRoutesAdded(app2);
1844
- app2.all("*", (context) => {
1846
+ config.afterRoutesAdded && config.afterRoutesAdded(app);
1847
+ app.all("*", (context) => {
1845
1848
  const req = context.req;
1846
1849
  if (STATIC_FILE_MATCHER.test(req.url)) {
1847
1850
  const filePath = config.staticFileRoot + new URL(req.url).pathname;
1848
1851
  const file = Bun.file(filePath);
1849
- let headers2 = {};
1852
+ let headers = {};
1850
1853
  if (IS_PROD) {
1851
- headers2 = {
1854
+ headers = {
1852
1855
  "cache-control": "public, max-age=31557600"
1853
1856
  };
1854
1857
  }
1855
- return new Response(file, { headers: headers2 });
1858
+ return new Response(file, { headers });
1856
1859
  }
1857
- return app2._defaultRoute(context);
1860
+ return app._defaultRoute(context);
1858
1861
  });
1859
- return app2;
1862
+ return app;
1860
1863
  }
1861
1864
  async function buildClientJS() {
1862
- const sourceFile = resolve(CWD, "../", "./src/clientjs/hyperspan-client.ts");
1865
+ const sourceFile = resolve(PWD, "../", "./src/clientjs/hyperspan-client.ts");
1863
1866
  const output = await Bun.build({
1864
1867
  entrypoints: [sourceFile],
1865
1868
  outdir: `./public/_hs/js`,
@@ -1905,7 +1908,8 @@ function formRoute(handlerFn) {
1905
1908
  };
1906
1909
  }
1907
1910
  var IS_PROD = false;
1908
- var CWD = import.meta.dir;
1911
+ var PWD = import.meta.dir;
1912
+ var CWD = process.cwd();
1909
1913
  var STATIC_FILE_MATCHER = /[^/\\&\?]+\.([a-zA-Z]+)$/;
1910
1914
  var _routeCache = {};
1911
1915
  var ROUTE_SEGMENT = /(\[[a-zA-Z_\.]+\])/g;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperspan/framework",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Hyperspan Web Framework",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -42,10 +42,10 @@
42
42
  "trek-router": "^1.2.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@types/bun": "^1.1.9",
45
+ "@types/bun": "^1.1.11",
46
46
  "@types/escape-html": "^1.0.4",
47
- "@types/node": "^22.5.5",
48
- "bun-plugin-dts": "^0.2.3",
49
- "typescript": "^5.6.2"
47
+ "@types/node": "^22.7.5",
48
+ "bun-plugin-dts": "^0.3.0",
49
+ "typescript": "^5.6.3"
50
50
  }
51
51
  }
package/src/html.ts CHANGED
@@ -68,7 +68,7 @@ async function* _render(
68
68
  value = obj;
69
69
  }
70
70
 
71
- if (value instanceof HSTemplate) {
71
+ if (value instanceof HSTemplate || value.__hsTemplate) {
72
72
  yield* renderToStream(value);
73
73
  } else if (typeof value.render !== 'undefined') {
74
74
  value.id = id;
@@ -108,6 +108,9 @@ async function* _render(
108
108
  case 'json':
109
109
  yield ''; //JSON.stringify(value);
110
110
  break;
111
+ case 'number':
112
+ yield String(value);
113
+ break;
111
114
  case 'object':
112
115
  if (typeof value.render === 'function') {
113
116
  yield value.render();
package/src/server.ts CHANGED
@@ -6,7 +6,8 @@ import { HSTemplate } from './html';
6
6
  import { HSApp, HSRequestContext, normalizePath } from './app';
7
7
 
8
8
  export const IS_PROD = process.env.NODE_ENV === 'production';
9
- const CWD = import.meta.dir;
9
+ const PWD = import.meta.dir;
10
+ const CWD = process.cwd();
10
11
  const STATIC_FILE_MATCHER = /[^/\\&\?]+\.([a-zA-Z]+)$/;
11
12
 
12
13
  // Cached route components
@@ -189,7 +190,7 @@ export async function buildRoutes(config: THSServerConfig): Promise<THSRouteMap[
189
190
  }
190
191
 
191
192
  routes.push({
192
- file,
193
+ file: join('./', routesDir, file),
193
194
  route: route || '/',
194
195
  params,
195
196
  });
@@ -220,10 +221,10 @@ export async function createServer(config: THSServerConfig): Promise<HSApp> {
220
221
 
221
222
  for (let i = 0; i < fileRoutes.length; i++) {
222
223
  let route = fileRoutes[i];
223
- const fullRouteFile = join('../../', config.appDir, 'routes', route.file);
224
+ const fullRouteFile = join(CWD, route.file);
224
225
  const routePattern = normalizePath(route.route);
225
226
 
226
- routeMap.push({ route: routePattern, file: config.appDir + '/routes/' + route.file });
227
+ routeMap.push({ route: routePattern, file: route.file });
227
228
 
228
229
  app.all(routePattern, async (context) => {
229
230
  const matchedRoute = await runFileRoute(fullRouteFile, context);
@@ -274,7 +275,7 @@ export async function createServer(config: THSServerConfig): Promise<HSApp> {
274
275
  */
275
276
  export let clientJSFile: string;
276
277
  export async function buildClientJS() {
277
- const sourceFile = resolve(CWD, '../', './src/clientjs/hyperspan-client.ts');
278
+ const sourceFile = resolve(PWD, '../', './src/clientjs/hyperspan-client.ts');
278
279
  const output = await Bun.build({
279
280
  entrypoints: [sourceFile],
280
281
  outdir: `./public/_hs/js`,