elegance-js 2.1.37 → 3.0.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.
Files changed (138) hide show
  1. package/README.md +90 -4
  2. package/bin/bootstrap.js +18 -0
  3. package/bin/run.js +2 -0
  4. package/dist/build/common.d.ts +147 -0
  5. package/dist/build/common.d.ts.map +1 -0
  6. package/dist/build/common.js +599 -0
  7. package/dist/build/dev.d.ts +2 -0
  8. package/dist/build/dev.d.ts.map +1 -0
  9. package/dist/build/dev.js +234 -0
  10. package/dist/build/prod.d.ts +2 -0
  11. package/dist/build/prod.d.ts.map +1 -0
  12. package/dist/build/prod.js +212 -0
  13. package/dist/build/render.d.ts +29 -0
  14. package/dist/build/render.d.ts.map +1 -0
  15. package/dist/build/render.js +234 -0
  16. package/dist/client.d.ts +13 -0
  17. package/dist/client.d.ts.map +1 -0
  18. package/dist/client.js +677 -0
  19. package/dist/config.d.ts +7 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +80 -0
  22. package/dist/constants.d.ts +10 -0
  23. package/dist/constants.d.ts.map +1 -0
  24. package/dist/constants.js +20 -0
  25. package/dist/elements.d.ts +2 -0
  26. package/dist/elements.d.ts.map +1 -0
  27. package/dist/elements.js +14 -0
  28. package/dist/error.d.ts +20 -0
  29. package/dist/error.d.ts.map +1 -0
  30. package/dist/error.js +123 -0
  31. package/dist/globals.d.ts +6 -0
  32. package/dist/globals.d.ts.map +1 -0
  33. package/dist/globals.js +106 -0
  34. package/dist/logger.d.ts +32 -0
  35. package/dist/logger.d.ts.map +1 -0
  36. package/dist/logger.js +72 -0
  37. package/dist/page-tools.d.ts +19 -0
  38. package/dist/page-tools.d.ts.map +1 -0
  39. package/dist/page-tools.js +141 -0
  40. package/dist/processing/oxc.d.ts +17 -0
  41. package/dist/processing/oxc.d.ts.map +1 -0
  42. package/dist/processing/oxc.js +938 -0
  43. package/dist/processing/taglist.d.ts +2 -0
  44. package/dist/processing/taglist.d.ts.map +1 -0
  45. package/dist/processing/taglist.js +215 -0
  46. package/dist/processing/tsx.d.ts +2 -0
  47. package/dist/processing/tsx.d.ts.map +1 -0
  48. package/dist/processing/tsx.js +131 -0
  49. package/dist/run.d.ts +3 -0
  50. package/dist/run.d.ts.map +1 -0
  51. package/dist/run.js +147 -0
  52. package/dist/server/dev.d.ts +2 -0
  53. package/dist/server/dev.d.ts.map +1 -0
  54. package/dist/server/dev.js +10 -0
  55. package/dist/server/prod.d.ts +2 -0
  56. package/dist/server/prod.d.ts.map +1 -0
  57. package/dist/server/prod.js +42 -0
  58. package/dist/server/security.d.ts +64 -0
  59. package/dist/server/security.d.ts.map +1 -0
  60. package/dist/server/security.js +120 -0
  61. package/dist/server/server.d.ts +73 -99
  62. package/dist/server/server.d.ts.map +1 -0
  63. package/dist/server/server.js +830 -680
  64. package/dist/types/component.d.ts +85 -0
  65. package/dist/types/component.d.ts.map +1 -0
  66. package/dist/types/component.js +0 -0
  67. package/dist/types/config.d.ts +12 -0
  68. package/dist/types/config.d.ts.map +1 -0
  69. package/dist/types/config.js +0 -0
  70. package/dist/types/elements.d.ts +412 -0
  71. package/dist/types/elements.d.ts.map +1 -0
  72. package/dist/types/elements.js +0 -0
  73. package/dist/types/index.d.ts +9 -0
  74. package/dist/types/index.d.ts.map +1 -0
  75. package/dist/types/index.js +5 -0
  76. package/dist/types/jsx.d.ts +976 -0
  77. package/dist/types/jsx.d.ts.map +1 -0
  78. package/dist/types/jsx.js +0 -0
  79. package/dist/types/server-actions.d.ts +60 -0
  80. package/dist/types/server-actions.d.ts.map +1 -0
  81. package/dist/types/server-actions.js +0 -0
  82. package/dist/user-utils.d.ts +23 -0
  83. package/dist/user-utils.d.ts.map +1 -0
  84. package/dist/user-utils.js +61 -0
  85. package/package.json +48 -27
  86. package/dist/client/effect.d.ts +0 -27
  87. package/dist/client/effect.js +0 -37
  88. package/dist/client/eventListener.d.ts +0 -39
  89. package/dist/client/eventListener.js +0 -52
  90. package/dist/client/loadHook.d.ts +0 -34
  91. package/dist/client/loadHook.js +0 -52
  92. package/dist/client/observer.d.ts +0 -36
  93. package/dist/client/observer.js +0 -66
  94. package/dist/client/runtime.d.ts +0 -105
  95. package/dist/client/runtime.js +0 -624
  96. package/dist/client/state.d.ts +0 -40
  97. package/dist/client/state.js +0 -110
  98. package/dist/compilation/compiler.d.ts +0 -163
  99. package/dist/compilation/compiler.js +0 -1164
  100. package/dist/components/ClientComponent.d.ts +0 -22
  101. package/dist/components/ClientComponent.js +0 -55
  102. package/dist/components/Link.d.ts +0 -16
  103. package/dist/components/Link.js +0 -21
  104. package/dist/components/Portal.d.ts +0 -2
  105. package/dist/components/Portal.js +0 -2
  106. package/dist/elements/element.d.ts +0 -87
  107. package/dist/elements/element.js +0 -33
  108. package/dist/elements/element_list.d.ts +0 -7
  109. package/dist/elements/element_list.js +0 -65
  110. package/dist/elements/raw.d.ts +0 -14
  111. package/dist/elements/raw.js +0 -78
  112. package/dist/elements/specific_props.d.ts +0 -750
  113. package/dist/elements/specific_props.js +0 -1
  114. package/dist/global.d.ts +0 -229
  115. package/dist/global.js +0 -1
  116. package/dist/index.d.ts +0 -16
  117. package/dist/index.js +0 -12
  118. package/dist/server/layout.d.ts +0 -34
  119. package/dist/server/layout.js +0 -6
  120. package/dist/server/log.d.ts +0 -12
  121. package/dist/server/log.js +0 -64
  122. package/dist/server/page.d.ts +0 -32
  123. package/dist/server/page.js +0 -6
  124. package/dist/server/runtime.d.ts +0 -6
  125. package/dist/server/runtime.js +0 -92
  126. package/scripts/bootstrap.js +0 -95
  127. package/scripts/bootstrap_files/elegance.txt +0 -40
  128. package/scripts/bootstrap_files/index.txt +0 -3
  129. package/scripts/bootstrap_files/layout.txt +0 -46
  130. package/scripts/bootstrap_files/middleware.txt +0 -18
  131. package/scripts/bootstrap_files/page.txt +0 -123
  132. package/scripts/bootstrap_files/route.txt +0 -6
  133. package/scripts/elegance_dev.ts +0 -42
  134. package/scripts/elegance_prod.ts +0 -42
  135. package/scripts/elegance_static.ts +0 -26
  136. package/scripts/prod.js +0 -13
  137. package/scripts/run.js +0 -13
  138. package/scripts/static.js +0 -13
package/dist/config.js ADDED
@@ -0,0 +1,80 @@
1
+ import { existsSync } from "fs";
2
+ import { join } from "path";
3
+ const defaultConfig = {
4
+ security: {
5
+ contentSecurityPolicy: {
6
+ defaultSrc: [],
7
+ scriptSrc: ["'self'", "blob:"],
8
+ scriptSrcElem: ["'self'", "blob:"],
9
+ imgSrc: ["'self'", "data:", "https:"],
10
+ fontSrc: [],
11
+ connectSrc: [],
12
+ frameSrc: ["'none'"],
13
+ objectSrc: ["'none'"],
14
+ baseUri: ["'self'"],
15
+ formAction: ["'self'"],
16
+ upgradeInsecureRequests: false
17
+ },
18
+ strictTransportSecurity: {
19
+ maxAge: 31536e3,
20
+ includeSubDomains: true
21
+ },
22
+ xFrameOptions: "DENY",
23
+ xContentTypeOptions: true,
24
+ referrerPolicy: "strict-origin-when-cross-origin",
25
+ permissionsPolicy: {
26
+ camera: ["'none'"],
27
+ microphone: ["'none'"],
28
+ geolocation: ["'none'"]
29
+ },
30
+ crossOriginOpenerPolicy: "same-origin",
31
+ crossOriginResourcePolicy: "same-origin",
32
+ xDnsPrefetchControl: "off"
33
+ },
34
+ output: {
35
+ outputDirectory: ".elegance",
36
+ pagesDirectory: "pages"
37
+ },
38
+ server: {
39
+ port: 3e3,
40
+ serveAPI: true,
41
+ allowDynamicPages: true,
42
+ allowStatusCodePages: true
43
+ }
44
+ };
45
+ let userConfig;
46
+ async function loadConfig() {
47
+ const CONFIG_PATH = join(process.cwd(), "elegance.config.ts");
48
+ if (!existsSync(CONFIG_PATH)) {
49
+ userConfig = defaultConfig;
50
+ return;
51
+ }
52
+ const module = await import(CONFIG_PATH);
53
+ if (module.config) {
54
+ userConfig = module.config;
55
+ return;
56
+ }
57
+ userConfig = defaultConfig;
58
+ }
59
+ function deepMerge(defaults, overrides) {
60
+ const result = { ...defaults };
61
+ for (const key in overrides) {
62
+ const override = overrides[key];
63
+ const defaultValue = defaults[key];
64
+ if (override && typeof override === "object" && !Array.isArray(override) && defaultValue && typeof defaultValue === "object" && !Array.isArray(defaultValue)) {
65
+ result[key] = deepMerge(defaultValue, override);
66
+ } else if (override !== void 0) {
67
+ result[key] = override;
68
+ }
69
+ }
70
+ return result;
71
+ }
72
+ async function getConfig() {
73
+ if (!userConfig) {
74
+ await loadConfig();
75
+ }
76
+ return deepMerge(defaultConfig, userConfig);
77
+ }
78
+ export {
79
+ getConfig
80
+ };
@@ -0,0 +1,10 @@
1
+ export type OutputOptions = {
2
+ outputDirectory?: string;
3
+ pagesDirectory?: string;
4
+ };
5
+ export declare let OUT_DIR: string;
6
+ export declare let DIST_DIR: string;
7
+ export declare let CACHE_DIR: string;
8
+ export declare let PAGES_DIR: string;
9
+ export declare function loadPaths(): Promise<void>;
10
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,aAAa,GAAG;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,eAAO,IAAI,OAAO,EAAE,MAAM,CAAC;AAC3B,eAAO,IAAI,QAAQ,EAAE,MAAM,CAAC;AAC5B,eAAO,IAAI,SAAS,EAAE,MAAM,CAAC;AAC7B,eAAO,IAAI,SAAS,EAAE,MAAM,CAAC;AAE7B,wBAAsB,SAAS,kBAQ9B"}
@@ -0,0 +1,20 @@
1
+ import { join } from "node:path";
2
+ import { getConfig } from "./config.js";
3
+ let OUT_DIR;
4
+ let DIST_DIR;
5
+ let CACHE_DIR;
6
+ let PAGES_DIR;
7
+ async function loadPaths() {
8
+ const config = await getConfig();
9
+ OUT_DIR = config.output.outputDirectory;
10
+ DIST_DIR = join(OUT_DIR, "dist");
11
+ CACHE_DIR = join(OUT_DIR, "cache");
12
+ PAGES_DIR = config.output.pagesDirectory;
13
+ }
14
+ export {
15
+ CACHE_DIR,
16
+ DIST_DIR,
17
+ OUT_DIR,
18
+ PAGES_DIR,
19
+ loadPaths
20
+ };
@@ -0,0 +1,2 @@
1
+ export declare function makeEl<T extends AnyTag>(tagName: T): ElementGenerator<T>;
2
+ //# sourceMappingURL=elements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../src/elements.ts"],"names":[],"mappings":"AAEA,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAoBxE"}
@@ -0,0 +1,14 @@
1
+ function makeEl(tagName) {
2
+ return function(options, ...children) {
3
+ const isOptions = typeof options === "object" && options !== null && !Array.isArray(options) && !("__type" in options);
4
+ return {
5
+ __type: "element",
6
+ tag: tagName,
7
+ options: isOptions ? options : {},
8
+ children: isOptions ? children : [options, ...children]
9
+ };
10
+ };
11
+ }
12
+ export {
13
+ makeEl
14
+ };
@@ -0,0 +1,20 @@
1
+ export interface RichErrorOptions {
2
+ title: string;
3
+ message?: string;
4
+ description?: string;
5
+ hint?: string;
6
+ origin?: string;
7
+ meta?: Record<string, unknown>;
8
+ cause?: unknown;
9
+ doShowStack: boolean;
10
+ }
11
+ export type RichError = Error & RichErrorOptions;
12
+ export declare function richError(opts: RichErrorOptions): RichError;
13
+ export declare function isRichError(value: unknown): value is RichError;
14
+ export interface FormatOptions {
15
+ colors?: boolean;
16
+ maxCauseDepth?: number;
17
+ }
18
+ export declare function formatError(err: unknown, opts?: FormatOptions): string;
19
+ export declare function printError(err: unknown, opts?: FormatOptions): void;
20
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAS,MAAM,CAAA;IACpB,OAAO,CAAC,EAAM,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAS,MAAM,CAAA;IACpB,MAAM,CAAC,EAAO,MAAM,CAAA;IACpB,IAAI,CAAC,EAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,KAAK,CAAC,EAAQ,OAAO,CAAA;IACrB,WAAW,EAAG,OAAO,CAAA;CACxB;AAED,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,gBAAgB,CAAA;AAEhD,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,SAAS,CAwB3D;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAE9D;AAgBD,MAAM,WAAW,aAAa;IAC1B,MAAM,CAAC,EAAS,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAQD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CAa1E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAEnE"}
package/dist/error.js ADDED
@@ -0,0 +1,123 @@
1
+ import { relative } from "node:path";
2
+ function richError(opts) {
3
+ const message = opts.message ?? opts.title;
4
+ const err = new Error(message);
5
+ err.title = opts.title;
6
+ err.description = opts.description;
7
+ err.hint = opts.hint;
8
+ err.origin = relative(process.cwd(), opts.origin ?? "");
9
+ err.meta = opts.meta;
10
+ err.doShowStack = opts.doShowStack;
11
+ if (opts.cause !== void 0) err.cause = opts.cause;
12
+ if (opts.message !== void 0) err.message = opts.message;
13
+ if (typeof Error.captureStackTrace === "function") {
14
+ Error.captureStackTrace(err, richError);
15
+ } else if (err.stack) {
16
+ err.stack = err.stack.split("\n").filter((l, i) => i === 0 || !l.includes("richError")).join("\n");
17
+ }
18
+ return err;
19
+ }
20
+ function isRichError(value) {
21
+ return value instanceof Error && "title" in value;
22
+ }
23
+ const ansi = {
24
+ reset: "\x1B[0m",
25
+ bold: "\x1B[1m",
26
+ dim: "\x1B[2m",
27
+ red: "\x1B[31m",
28
+ yellow: "\x1B[33m",
29
+ cyan: "\x1B[36m",
30
+ magenta: "\x1B[35m",
31
+ gray: "\x1B[90m"
32
+ };
33
+ const BOX_W = 56;
34
+ const I1 = " ";
35
+ const I2 = " ";
36
+ const I3 = " ";
37
+ function formatError(err, opts = {}) {
38
+ const { colors = true, maxCauseDepth = 4 } = opts;
39
+ const paint = colors ? (text, ...keys) => keys.map((k) => ansi[k]).join("") + text + ansi.reset : (text) => text;
40
+ const out = [""];
41
+ out.push(...banner(paint));
42
+ out.push("");
43
+ renderNode(err, 0, out, paint, maxCauseDepth);
44
+ out.push("");
45
+ return out.join("\n");
46
+ }
47
+ function printError(err, opts) {
48
+ console.error(formatError(err, opts));
49
+ }
50
+ function banner(paint) {
51
+ const W = BOX_W;
52
+ const top = paint(`\u256D${"\u2500".repeat(W)}\u256E`, "red");
53
+ const bot = paint(`\u2570${"\u2500".repeat(W)}\u256F`, "red");
54
+ const rawLabel = " \u2717 ERROR";
55
+ const pad = " ".repeat(W - rawLabel.length);
56
+ const mid = paint("\u2502", "red") + " " + paint("\u2717", "red", "bold") + " " + paint("ERROR", "red", "bold") + pad + paint("\u2502", "red");
57
+ return [top, mid, bot];
58
+ }
59
+ function renderNode(error, depth, out, paint, maxDepth) {
60
+ if (depth > maxDepth) {
61
+ out.push(`${I2}${paint("\u21B3 \u2026 further causes omitted", "dim")}`);
62
+ return;
63
+ }
64
+ if (error === null || error === void 0 || typeof error !== "object") {
65
+ const label = typeof error === "string" ? error : error === null || error === void 0 ? String(error) : `(${typeof error}) ${String(error)}`;
66
+ const indent = depth === 0 ? I1 : I2;
67
+ out.push(`${indent}${paint("\u26A0", "yellow", "bold")} ${paint(label, "dim")}`);
68
+ return;
69
+ }
70
+ const err = error;
71
+ const rich = isRichError(err);
72
+ const titleText = rich ? err.title : `${err.constructor?.name ?? "Error"}: ${err.message}`;
73
+ const titleIndent = depth === 0 ? I1 : I2;
74
+ out.push(
75
+ `${titleIndent}${paint("\u26A0", "yellow", "bold")} ${paint(titleText, "bold")}`
76
+ );
77
+ const fi = depth === 0 ? I2 : I3;
78
+ const si = depth === 0 ? I3 : I3 + " ";
79
+ if (rich && err.description) {
80
+ out.push("");
81
+ out.push(`${fi}${err.description}`);
82
+ }
83
+ if (rich && err.origin) {
84
+ out.push(`${fi}${paint(err.origin, "gray")}`);
85
+ }
86
+ const hasFields = rich && (err.hint || err.origin);
87
+ if (hasFields) out.push("");
88
+ const cause = err.cause;
89
+ if (cause !== void 0) {
90
+ out.push("");
91
+ if (typeof cause === "string" && cause.startsWith("\\")) {
92
+ out.push(paint(cause.slice(1)));
93
+ } else {
94
+ out.push(`${fi}${paint(cause)}`);
95
+ }
96
+ }
97
+ if (rich && err.hint) {
98
+ out.push("");
99
+ if (err.hint.startsWith("\\")) {
100
+ out.push(paint(err.hint.slice(1), "yellow"));
101
+ } else {
102
+ out.push(`${fi}${paint(err.hint, "yellow")}`);
103
+ }
104
+ }
105
+ const showStack = (err.stack || err.cause instanceof Error) && (rich ? err.doShowStack : depth > 0);
106
+ if (showStack) {
107
+ const stack = err.cause instanceof Error ? cause.stack : err.stack;
108
+ const frames = stack.split("\n").slice(1).filter(Boolean);
109
+ if (frames.length > 0) {
110
+ out.push("");
111
+ out.push(`${fi}${paint("Stack", "gray")}`);
112
+ for (const frame of frames) {
113
+ out.push(`${si}${paint("\u254E", "dim")} ${paint(frame.trim(), "dim")}`);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ export {
119
+ formatError,
120
+ isRichError,
121
+ printError,
122
+ richError
123
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * this is quite literallyll the worst file that i have ever seen in my entire life
3
+ * i hate every single thing about this file, and the fact that it even exists at all.
4
+ */
5
+ export declare function hookGlobals(): void;
6
+ //# sourceMappingURL=globals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,WAAW,SA4H1B"}
@@ -0,0 +1,106 @@
1
+ import { makeEl } from "./elements.js";
2
+ import { renderContextStorage } from "./build/render.js";
3
+ import { importContext } from "./build/common.js";
4
+ function hookGlobals() {
5
+ globalThis.__tags = new Proxy({}, {
6
+ get(_, tag) {
7
+ return makeEl(tag);
8
+ }
9
+ });
10
+ globalThis.serverAction = (params) => {
11
+ console.log("Register serverAction:", params.id);
12
+ if (globalThis.__serverActions === void 0) globalThis.__serverActions = [];
13
+ globalThis.__serverActions.push(params);
14
+ };
15
+ globalThis.rawHTML = (content) => ({ content, __rawHTML: true });
16
+ globalThis.onPageLoad = () => {
17
+ };
18
+ globalThis.atom = function(id, initial) {
19
+ const context = importContext.getStore();
20
+ if (!context) {
21
+ throw new Error("atom() called outside of import context. This is an invalid invocation.");
22
+ }
23
+ const seeds = context.atomSeeds;
24
+ seeds.push({ id, initial });
25
+ const atom = {
26
+ id,
27
+ get value() {
28
+ const ctx = renderContextStorage.getStore();
29
+ if (!ctx) return initial;
30
+ if (!ctx.atomValues.has(id)) {
31
+ ctx.atomValues.set(id, initial);
32
+ ctx.atomRegistry.push({ id });
33
+ }
34
+ return ctx.atomValues.get(id);
35
+ },
36
+ set value(v) {
37
+ const ctx = renderContextStorage.getStore();
38
+ if (!ctx) return;
39
+ if (!ctx.atomValues.has(id)) {
40
+ ctx.atomValues.set(id, initial);
41
+ ctx.atomRegistry.push({ id });
42
+ }
43
+ ctx.atomValues.set(id, v);
44
+ }
45
+ };
46
+ return atom;
47
+ };
48
+ globalThis.view = (fn) => fn;
49
+ globalThis.component = function component(cfg) {
50
+ const { __id: cid, view, init, atoms } = cfg;
51
+ if (!cid) throw "Invalid component call, was the preprocessor ran on this file?";
52
+ if (!view) {
53
+ throw new Error(`Component "${cid}": must provide 'view', otherwise the component cannot be rendered.`);
54
+ }
55
+ const generator = (props, children) => {
56
+ const atomsObj = {};
57
+ if (atoms) {
58
+ for (const key of Object.keys(atoms)) {
59
+ let value = atoms[key];
60
+ atomsObj[key] = {
61
+ get value() {
62
+ return value;
63
+ },
64
+ set value(v) {
65
+ value = v;
66
+ },
67
+ id: `${cid}:${key}`
68
+ };
69
+ }
70
+ }
71
+ const self = {
72
+ props: props ?? {},
73
+ root: void 0
74
+ };
75
+ const descriptor = {
76
+ __type: "live",
77
+ __componentId: cid,
78
+ __definition: {
79
+ state: () => ({}),
80
+ callbacks: {},
81
+ render: () => view({ self, atoms: atomsObj, children }),
82
+ serverInit: async () => {
83
+ if (init) await init(self, atomsObj);
84
+ }
85
+ },
86
+ props: props ?? {}
87
+ };
88
+ const originalInit = descriptor.__definition.serverInit;
89
+ descriptor.__definition.serverInit = async () => {
90
+ await originalInit();
91
+ };
92
+ return descriptor;
93
+ };
94
+ generator.__config = { ...cfg };
95
+ return generator;
96
+ };
97
+ globalThis.track = () => {
98
+ console.warn("WARNING: The track() function is a no-op on the server, make sure to only call it within browser-code.");
99
+ };
100
+ globalThis.untrack = () => {
101
+ console.warn("WARNING: The untrack() function is a no-op on the server, make sure to only call it within browser-code.");
102
+ };
103
+ }
104
+ export {
105
+ hookGlobals
106
+ };
@@ -0,0 +1,32 @@
1
+ export declare const c: {
2
+ readonly reset: "\u001B[0m";
3
+ readonly bold: "\u001B[1m";
4
+ readonly dim: "\u001B[2m";
5
+ readonly italic: "\u001B[3m";
6
+ readonly red: "\u001B[31m";
7
+ readonly green: "\u001B[32m";
8
+ readonly yellow: "\u001B[33m";
9
+ readonly blue: "\u001B[34m";
10
+ readonly cyan: "\u001B[36m";
11
+ readonly magenta: "\u001B[35m";
12
+ readonly white: "\u001B[37m";
13
+ readonly gray: "\u001B[90m";
14
+ };
15
+ export type ColorKey = keyof typeof c;
16
+ export interface LogOptions {
17
+ /** A secondary, dimmed line printed beneath the message. */
18
+ detail?: string;
19
+ /** Prepend an HH:MM:SS timestamp to each line. */
20
+ timestamp?: boolean;
21
+ }
22
+ export declare const logger: {
23
+ info(msg: string, opts?: LogOptions): void;
24
+ success(msg: string, opts?: LogOptions): void;
25
+ warn(msg: string, opts?: LogOptions): void;
26
+ error(msg: string, opts?: LogOptions): void;
27
+ debug(msg: string, opts?: LogOptions): void;
28
+ gap(): void;
29
+ divider(label?: string): void;
30
+ field(key: string, value: string, color?: ColorKey): void;
31
+ };
32
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,CAAC;;;;;;;;;;;;;CAaJ,CAAA;AAEV,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,CAAA;AAkBrC,MAAM,WAAW,UAAU;IACvB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAA;CACtB;AAkBD,eAAO,MAAM,MAAM;cACF,MAAM,SAAS,UAAU,GAAG,IAAI;iBAChC,MAAM,SAAS,UAAU,GAAG,IAAI;cAChC,MAAM,SAAS,UAAU,GAAG,IAAI;eAChC,MAAM,SAAS,UAAU,GAAG,IAAI;eAChC,MAAM,SAAS,UAAU,GAAG,IAAI;WAEtC,IAAI;oBAIK,MAAM,GAAG,IAAI;eAUlB,MAAM,SAAS,MAAM,UAAS,QAAQ,GAAY,IAAI;CAIpE,CAAA"}
package/dist/logger.js ADDED
@@ -0,0 +1,72 @@
1
+ const c = {
2
+ reset: "\x1B[0m",
3
+ bold: "\x1B[1m",
4
+ dim: "\x1B[2m",
5
+ italic: "\x1B[3m",
6
+ red: "\x1B[31m",
7
+ green: "\x1B[32m",
8
+ yellow: "\x1B[33m",
9
+ blue: "\x1B[34m",
10
+ cyan: "\x1B[36m",
11
+ magenta: "\x1B[35m",
12
+ white: "\x1B[37m",
13
+ gray: "\x1B[90m"
14
+ };
15
+ function paint(text, ...styles) {
16
+ return styles.map((k) => c[k]).join("") + text + c.reset;
17
+ }
18
+ const LEVELS = {
19
+ info: { icon: "!", badge: "info", color: "cyan" },
20
+ success: { icon: "\u2713", badge: "ok", color: "green" },
21
+ warn: { icon: "\u26A0", badge: "warn", color: "yellow" },
22
+ error: { icon: "\u2717", badge: "error", color: "red" },
23
+ debug: { icon: "\u25C6", badge: "debug", color: "magenta" }
24
+ };
25
+ const MSG_INDENT = " ";
26
+ function emit(level, msg, opts = {}) {
27
+ const { icon, badge, color } = LEVELS[level];
28
+ const fn = level === "error" ? console.error : console.log;
29
+ const ts = opts.timestamp ? paint((/* @__PURE__ */ new Date()).toTimeString().slice(0, 8), "gray") + " " : "";
30
+ fn(` ${ts}${paint(icon, color)} ${paint(badge.padEnd(6), color, "bold")}${msg}`);
31
+ if (opts.detail) {
32
+ const tsGap = opts.timestamp ? " " : "";
33
+ fn(` ${tsGap}${MSG_INDENT}${paint(opts.detail, "dim")}`);
34
+ }
35
+ }
36
+ const logger = {
37
+ info(msg, opts) {
38
+ emit("info", msg, opts);
39
+ },
40
+ success(msg, opts) {
41
+ emit("success", msg, opts);
42
+ },
43
+ warn(msg, opts) {
44
+ emit("warn", msg, opts);
45
+ },
46
+ error(msg, opts) {
47
+ emit("error", msg, opts);
48
+ },
49
+ debug(msg, opts) {
50
+ emit("debug", msg, opts);
51
+ },
52
+ gap() {
53
+ console.log("");
54
+ },
55
+ divider(label) {
56
+ const W = 54;
57
+ if (label) {
58
+ const dashes = "\u2500".repeat(Math.max(2, W - label.length - 4));
59
+ console.log(" " + paint(`\u2500\u2500 ${label} ${dashes}`, "gray"));
60
+ } else {
61
+ console.log(" " + paint("\u2500".repeat(W), "gray"));
62
+ }
63
+ },
64
+ field(key, value, color = "cyan") {
65
+ const k = paint(key.padEnd(10), color);
66
+ console.log(` ${MSG_INDENT}${k} ${value}`);
67
+ }
68
+ };
69
+ export {
70
+ c,
71
+ logger
72
+ };
@@ -0,0 +1,19 @@
1
+ import type esbuild from "esbuild";
2
+ import type { CompiledLayout } from "./build/common";
3
+ export interface RouteInfo {
4
+ pathname: string;
5
+ pageFile: string;
6
+ layouts: string[];
7
+ }
8
+ export interface PageRoute extends RouteInfo {
9
+ isDynamic: boolean;
10
+ }
11
+ export declare function pathnameFromFile(filePath: string): string;
12
+ export declare function getPageRoutes(pagesDir: string): Promise<PageRoute[]>;
13
+ export declare function collectLayouts(pageDir: string, rootDir: string): Promise<string[]>;
14
+ export declare function fileHasDynamicExport(path: string): Promise<boolean>;
15
+ export declare function sanitize(pathname: string): string;
16
+ export declare const eleganceTsxPlugin: esbuild.Plugin;
17
+ export declare function composeRenderFn(pageModule: any, layoutModules: CompiledLayout[]): (params: any, req: any, res: any) => any;
18
+ export declare function gatherMetaFromModules(pageModule: any, layoutModules: any[], params: Record<string, any>): Promise<any[]>;
19
+ //# sourceMappingURL=page-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-tools.d.ts","sourceRoot":"","sources":["../src/page-tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,SAAS;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAG,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,SAAU,SAAQ,SAAS;IACxC,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKzD;AAkCD,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAmB1E;AAmBD,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAcxF;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOzE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,eAAO,MAAM,iBAAiB,EAAE,OAAO,CAAC,MAQvC,CAAC;AAEF,wBAAgB,eAAe,CAC3B,UAAU,EAAK,GAAG,EAClB,aAAa,EAAE,cAAc,EAAE,GAChC,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,GAAG,CAiB1C;AAED,wBAAsB,qBAAqB,CACvC,UAAU,EAAK,GAAG,EAClB,aAAa,EAAE,GAAG,EAAE,EACpB,MAAM,EAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACnC,OAAO,CAAC,GAAG,EAAE,CAAC,CAiBhB"}
@@ -0,0 +1,141 @@
1
+ import { readdir, stat, readFile } from "node:fs/promises";
2
+ import { join, dirname, relative } from "node:path";
3
+ import { transformJSX } from "./processing/tsx.js";
4
+ import { PAGES_DIR } from "./constants.js";
5
+ function pathnameFromFile(filePath) {
6
+ const withoutExt = filePath.replace(/\.[^.]+$/, "");
7
+ const rel = relative(PAGES_DIR, withoutExt);
8
+ const normalized = rel.replace(/[\\/]?index$/, "") || "index";
9
+ return normalized === "index" ? "/" : `/${normalized}`;
10
+ }
11
+ async function getRoutes(pagesDir) {
12
+ const routes = [];
13
+ await walkDir(pagesDir, "/");
14
+ return routes;
15
+ async function walkDir(dir, urlPrefix) {
16
+ const entries = await readdir(dir, { withFileTypes: true });
17
+ const pageFile = await resolveTs(dir, "page");
18
+ if (pageFile) {
19
+ const layouts = await collectLayouts(dir, pagesDir);
20
+ routes.push({
21
+ pathname: urlPrefix === "/" ? "/" : urlPrefix.replace(/\/$/, ""),
22
+ pageFile,
23
+ layouts
24
+ });
25
+ }
26
+ for (const entry of entries) {
27
+ if (entry.isDirectory() && !entry.name.startsWith(".") && !entry.name.startsWith("_")) {
28
+ await walkDir(join(dir, entry.name), urlPrefix + entry.name + "/");
29
+ }
30
+ }
31
+ }
32
+ }
33
+ function hasSlugSegment(pathname) {
34
+ const segments = pathname.split("/").filter(Boolean);
35
+ return segments.some(
36
+ (seg) => /^\[.+\]$/.test(seg) || /^\.\.\.\[.+\]$/.test(seg) || /^:\[.+\]$/.test(seg)
37
+ );
38
+ }
39
+ async function getPageRoutes(pagesDir) {
40
+ const raw = await getRoutes(pagesDir);
41
+ const result = [];
42
+ for (const r of raw) {
43
+ const pageDynamic = await fileHasDynamicExport(r.pageFile) || hasSlugSegment(r.pathname);
44
+ const layoutInfos = await Promise.all(
45
+ r.layouts.map(async (lp) => ({
46
+ path: lp,
47
+ isDynamic: await fileHasDynamicExport(lp)
48
+ }))
49
+ );
50
+ result.push({
51
+ ...r,
52
+ isDynamic: pageDynamic || layoutInfos.some((l) => l.isDynamic)
53
+ });
54
+ }
55
+ return result;
56
+ }
57
+ async function fileExists(path) {
58
+ try {
59
+ const s = await stat(path);
60
+ return s.isFile();
61
+ } catch {
62
+ return false;
63
+ }
64
+ }
65
+ async function resolveTs(dir, base) {
66
+ for (const ext of [".ts", ".tsx"]) {
67
+ const p = join(dir, base + ext);
68
+ if (await fileExists(p)) return p;
69
+ }
70
+ return null;
71
+ }
72
+ async function collectLayouts(pageDir, rootDir) {
73
+ const layouts = [];
74
+ let current = pageDir;
75
+ while (current !== rootDir && current !== dirname(current)) {
76
+ const candidate = await resolveTs(current, "layout");
77
+ if (candidate) layouts.unshift(candidate);
78
+ current = dirname(current);
79
+ }
80
+ const rootCandidate = await resolveTs(rootDir, "layout");
81
+ if (rootCandidate) layouts.unshift(rootCandidate);
82
+ return layouts;
83
+ }
84
+ async function fileHasDynamicExport(path) {
85
+ try {
86
+ const source = await readFile(path, "utf-8");
87
+ return /\bexport\s+(?:const|let)\s+isDynamic\s*=\s*true\b/.test(source);
88
+ } catch {
89
+ return false;
90
+ }
91
+ }
92
+ function sanitize(pathname) {
93
+ return pathname.replace(/\//g, "_") || "index";
94
+ }
95
+ const eleganceTsxPlugin = {
96
+ name: "elegance-tsx",
97
+ setup(build) {
98
+ build.onLoad({ filter: /\.tsx$/ }, async (args) => {
99
+ const source = await readFile(args.path, "utf-8");
100
+ return { contents: transformJSX(source, args.path), loader: "ts" };
101
+ });
102
+ }
103
+ };
104
+ function composeRenderFn(pageModule, layoutModules) {
105
+ return (params, req, res) => {
106
+ let renderFn = (props) => pageModule.default({ ...props, ...params, req, res });
107
+ for (let i = layoutModules.length - 1; i >= 0; i--) {
108
+ const layout = layoutModules[i];
109
+ const inner = renderFn;
110
+ renderFn = (props) => layout.default({
111
+ ...props,
112
+ child: (childProps) => inner(childProps ?? {})
113
+ });
114
+ }
115
+ return renderFn({});
116
+ };
117
+ }
118
+ async function gatherMetaFromModules(pageModule, layoutModules, params) {
119
+ const metas = [];
120
+ const sources = [...layoutModules, pageModule];
121
+ for (const src of sources) {
122
+ try {
123
+ if (src && typeof src.metadata !== "undefined") {
124
+ const raw = typeof src.metadata === "function" ? await src.metadata(params) : src.metadata;
125
+ if (Array.isArray(raw)) metas.push(...raw);
126
+ }
127
+ } catch {
128
+ }
129
+ }
130
+ return metas;
131
+ }
132
+ export {
133
+ collectLayouts,
134
+ composeRenderFn,
135
+ eleganceTsxPlugin,
136
+ fileHasDynamicExport,
137
+ gatherMetaFromModules,
138
+ getPageRoutes,
139
+ pathnameFromFile,
140
+ sanitize
141
+ };