@hypen-space/core 0.3.9 → 0.3.11

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 (80) hide show
  1. package/dist/{src/app.js → app.js} +15 -2
  2. package/dist/{src/app.js.map → app.js.map} +3 -3
  3. package/dist/{src/components → components}/builtin.js +22 -7
  4. package/dist/{src/components → components}/builtin.js.map +4 -4
  5. package/dist/context.js +387 -0
  6. package/dist/context.js.map +12 -0
  7. package/dist/{src/discovery.js → discovery.js} +18 -4
  8. package/dist/{src/discovery.js.map → discovery.js.map} +4 -4
  9. package/dist/disposable.js +377 -0
  10. package/dist/disposable.js.map +11 -0
  11. package/dist/engine.browser.js +347 -0
  12. package/dist/engine.browser.js.map +11 -0
  13. package/dist/engine.js +320 -0
  14. package/dist/engine.js.map +11 -0
  15. package/dist/events.js +282 -0
  16. package/dist/events.js.map +11 -0
  17. package/dist/{src/index.browser.js → index.browser.js} +278 -229
  18. package/dist/index.browser.js.map +22 -0
  19. package/dist/{src/index.js → index.js} +1377 -1330
  20. package/dist/index.js.map +31 -0
  21. package/dist/loader.js +286 -0
  22. package/dist/loader.js.map +11 -0
  23. package/dist/plugin.js +334 -0
  24. package/dist/plugin.js.map +11 -0
  25. package/dist/{src/remote → remote}/client.js +215 -11
  26. package/dist/remote/client.js.map +14 -0
  27. package/dist/{src/remote → remote}/index.js +234 -210
  28. package/dist/remote/index.js.map +19 -0
  29. package/dist/remote/server.js +1442 -0
  30. package/dist/remote/server.js.map +16 -0
  31. package/dist/renderer.js +264 -0
  32. package/dist/renderer.js.map +11 -0
  33. package/dist/{src/router.js → router.js} +209 -8
  34. package/dist/router.js.map +12 -0
  35. package/package.json +69 -69
  36. package/src/components/builtin.ts +9 -6
  37. package/src/context.ts +10 -7
  38. package/src/discovery.ts +3 -2
  39. package/src/disposable.ts +6 -2
  40. package/src/engine.browser.ts +30 -11
  41. package/src/engine.ts +6 -3
  42. package/src/events.ts +5 -1
  43. package/src/index.browser.ts +20 -0
  44. package/src/index.ts +2 -0
  45. package/src/loader.ts +8 -8
  46. package/src/logger.ts +28 -0
  47. package/src/plugin.ts +2 -1
  48. package/src/remote/client.ts +8 -9
  49. package/src/remote/server.ts +6 -3
  50. package/src/renderer.ts +4 -5
  51. package/src/router.ts +10 -7
  52. package/wasm-browser/hypen_engine_bg.wasm +0 -0
  53. package/wasm-browser/package.json +1 -1
  54. package/wasm-node/hypen_engine_bg.wasm +0 -0
  55. package/wasm-node/package.json +5 -3
  56. package/dist/src/context.js +0 -182
  57. package/dist/src/context.js.map +0 -11
  58. package/dist/src/engine.browser.js +0 -137
  59. package/dist/src/engine.browser.js.map +0 -10
  60. package/dist/src/engine.js +0 -119
  61. package/dist/src/engine.js.map +0 -10
  62. package/dist/src/events.js +0 -80
  63. package/dist/src/events.js.map +0 -10
  64. package/dist/src/index.browser.js.map +0 -22
  65. package/dist/src/index.js.map +0 -31
  66. package/dist/src/loader.js +0 -85
  67. package/dist/src/loader.js.map +0 -10
  68. package/dist/src/plugin.js +0 -134
  69. package/dist/src/plugin.js.map +0 -10
  70. package/dist/src/remote/client.js.map +0 -13
  71. package/dist/src/remote/index.js.map +0 -19
  72. package/dist/src/renderer.js +0 -66
  73. package/dist/src/renderer.js.map +0 -10
  74. package/dist/src/router.js.map +0 -11
  75. /package/dist/{src/remote → remote}/types.js +0 -0
  76. /package/dist/{src/remote → remote}/types.js.map +0 -0
  77. /package/dist/{src/resolver.js → resolver.js} +0 -0
  78. /package/dist/{src/resolver.js.map → resolver.js.map} +0 -0
  79. /package/dist/{src/state.js → state.js} +0 -0
  80. /package/dist/{src/state.js.map → state.js.map} +0 -0
package/dist/loader.js ADDED
@@ -0,0 +1,286 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
+
13
+ // src/logger.ts
14
+ function isProduction() {
15
+ if (typeof process !== "undefined" && process.env) {
16
+ return false;
17
+ }
18
+ return false;
19
+ }
20
+ function setLogLevel(level) {
21
+ config.level = level;
22
+ }
23
+ function getLogLevel() {
24
+ return config.level;
25
+ }
26
+ function configureLogger(options) {
27
+ config = { ...config, ...options };
28
+ }
29
+ function enableLogging() {
30
+ config.level = "debug";
31
+ }
32
+ function disableLogging() {
33
+ config.level = "none";
34
+ }
35
+ function setDebugMode(enabled) {
36
+ config.level = enabled ? "debug" : "error";
37
+ }
38
+ function isDebugMode() {
39
+ return config.level === "debug";
40
+ }
41
+ function shouldLog(level) {
42
+ return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
43
+ }
44
+ function formatTag(tag, level) {
45
+ const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
46
+ if (config.colors && level !== "none") {
47
+ const color = LOG_LEVEL_COLORS[level];
48
+ return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
49
+ }
50
+ return `${timestamp}[${tag}]`;
51
+ }
52
+
53
+ class Logger {
54
+ tag;
55
+ constructor(tag) {
56
+ this.tag = tag;
57
+ }
58
+ debug(...args) {
59
+ if (!shouldLog("debug"))
60
+ return;
61
+ if (config.handler) {
62
+ config.handler.debug(this.tag, ...args);
63
+ } else {
64
+ console.log(formatTag(this.tag, "debug"), ...args);
65
+ }
66
+ }
67
+ info(...args) {
68
+ if (!shouldLog("info"))
69
+ return;
70
+ if (config.handler) {
71
+ config.handler.info(this.tag, ...args);
72
+ } else {
73
+ console.info(formatTag(this.tag, "info"), ...args);
74
+ }
75
+ }
76
+ warn(...args) {
77
+ if (!shouldLog("warn"))
78
+ return;
79
+ if (config.handler) {
80
+ config.handler.warn(this.tag, ...args);
81
+ } else {
82
+ console.warn(formatTag(this.tag, "warn"), ...args);
83
+ }
84
+ }
85
+ error(...args) {
86
+ if (!shouldLog("error"))
87
+ return;
88
+ if (config.handler) {
89
+ config.handler.error(this.tag, ...args);
90
+ } else {
91
+ console.error(formatTag(this.tag, "error"), ...args);
92
+ }
93
+ }
94
+ time(label, fn) {
95
+ if (!shouldLog("debug")) {
96
+ return fn();
97
+ }
98
+ const start = performance.now();
99
+ try {
100
+ return fn();
101
+ } finally {
102
+ const duration = performance.now() - start;
103
+ this.debug(`${label}: ${duration.toFixed(2)}ms`);
104
+ }
105
+ }
106
+ async timeAsync(label, fn) {
107
+ if (!shouldLog("debug")) {
108
+ return fn();
109
+ }
110
+ const start = performance.now();
111
+ try {
112
+ return await fn();
113
+ } finally {
114
+ const duration = performance.now() - start;
115
+ this.debug(`${label}: ${duration.toFixed(2)}ms`);
116
+ }
117
+ }
118
+ child(subTag) {
119
+ return new Logger(`${this.tag}:${subTag}`);
120
+ }
121
+ debugIf(condition, ...args) {
122
+ if (condition)
123
+ this.debug(...args);
124
+ }
125
+ warnIf(condition, ...args) {
126
+ if (condition)
127
+ this.warn(...args);
128
+ }
129
+ errorIf(condition, ...args) {
130
+ if (condition)
131
+ this.error(...args);
132
+ }
133
+ loggedOnce = new Set;
134
+ warnOnce(key, ...args) {
135
+ if (this.loggedOnce.has(key))
136
+ return;
137
+ this.loggedOnce.add(key);
138
+ this.warn(...args);
139
+ }
140
+ debugOnce(key, ...args) {
141
+ if (this.loggedOnce.has(key))
142
+ return;
143
+ this.loggedOnce.add(key);
144
+ this.debug(...args);
145
+ }
146
+ }
147
+ function createLogger(tag) {
148
+ return new Logger(tag);
149
+ }
150
+ var LOG_LEVEL_ORDER, LOG_LEVEL_COLORS, RESET_COLOR = "\x1B[0m", config, logger, log, frameworkLoggers;
151
+ var init_logger = __esm(() => {
152
+ LOG_LEVEL_ORDER = {
153
+ debug: 0,
154
+ info: 1,
155
+ warn: 2,
156
+ error: 3,
157
+ none: 4
158
+ };
159
+ LOG_LEVEL_COLORS = {
160
+ debug: "\x1B[36m",
161
+ info: "\x1B[32m",
162
+ warn: "\x1B[33m",
163
+ error: "\x1B[31m"
164
+ };
165
+ config = {
166
+ level: isProduction() ? "error" : "debug",
167
+ colors: true,
168
+ timestamps: false
169
+ };
170
+ logger = createLogger("Hypen");
171
+ log = {
172
+ debug: (tag, ...args) => {
173
+ if (!shouldLog("debug"))
174
+ return;
175
+ console.log(formatTag(tag, "debug"), ...args);
176
+ },
177
+ info: (tag, ...args) => {
178
+ if (!shouldLog("info"))
179
+ return;
180
+ console.info(formatTag(tag, "info"), ...args);
181
+ },
182
+ warn: (tag, ...args) => {
183
+ if (!shouldLog("warn"))
184
+ return;
185
+ console.warn(formatTag(tag, "warn"), ...args);
186
+ },
187
+ error: (tag, ...args) => {
188
+ if (!shouldLog("error"))
189
+ return;
190
+ console.error(formatTag(tag, "error"), ...args);
191
+ }
192
+ };
193
+ frameworkLoggers = {
194
+ hypen: createLogger("Hypen"),
195
+ engine: createLogger("Engine"),
196
+ router: createLogger("Router"),
197
+ state: createLogger("State"),
198
+ events: createLogger("Events"),
199
+ remote: createLogger("Remote"),
200
+ renderer: createLogger("Renderer"),
201
+ module: createLogger("Module"),
202
+ lifecycle: createLogger("Lifecycle"),
203
+ loader: createLogger("Loader"),
204
+ context: createLogger("Context"),
205
+ discovery: createLogger("Discovery"),
206
+ plugin: createLogger("Plugin"),
207
+ canvas: createLogger("Canvas"),
208
+ debug: createLogger("Debug")
209
+ };
210
+ });
211
+
212
+ // src/loader.ts
213
+ init_logger();
214
+ import { existsSync, readdirSync, readFileSync } from "fs";
215
+ import { join } from "path";
216
+ var log2 = frameworkLoggers.loader;
217
+
218
+ class ComponentLoader {
219
+ components = new Map;
220
+ register(name, module, template, path) {
221
+ this.components.set(name, {
222
+ name,
223
+ module,
224
+ template,
225
+ path: path || name
226
+ });
227
+ }
228
+ get(name) {
229
+ return this.components.get(name);
230
+ }
231
+ has(name) {
232
+ return this.components.has(name);
233
+ }
234
+ getNames() {
235
+ return Array.from(this.components.keys());
236
+ }
237
+ getAll() {
238
+ return Array.from(this.components.values());
239
+ }
240
+ clear() {
241
+ this.components.clear();
242
+ }
243
+ async loadFromDirectory(name, dirPath) {
244
+ try {
245
+ const modulePath = join(dirPath, "component.ts");
246
+ const moduleExport = await import(modulePath);
247
+ const module = moduleExport.default;
248
+ const templatePath = join(dirPath, "component.hypen");
249
+ const template = readFileSync(templatePath, "utf-8");
250
+ this.register(name, module, template, dirPath);
251
+ log2.debug(`Loaded component: ${name} from ${dirPath}`);
252
+ } catch (error) {
253
+ log2.error(`Failed to load component ${name} from ${dirPath}:`, error);
254
+ throw error;
255
+ }
256
+ }
257
+ async loadFromComponentsDir(baseDir) {
258
+ try {
259
+ if (!existsSync(baseDir)) {
260
+ log2.warn(`Components directory not found: ${baseDir}`);
261
+ return;
262
+ }
263
+ const entries = readdirSync(baseDir, { withFileTypes: true });
264
+ for (const entry of entries) {
265
+ if (!entry.isDirectory())
266
+ continue;
267
+ const componentDir = join(baseDir, entry.name);
268
+ const hypenPath = join(componentDir, "component.hypen");
269
+ if (existsSync(hypenPath)) {
270
+ await this.loadFromDirectory(entry.name, componentDir);
271
+ }
272
+ }
273
+ log2.debug(`Loaded ${this.components.size} components from ${baseDir}`);
274
+ } catch (error) {
275
+ log2.error(`Failed to load components from ${baseDir}:`, error);
276
+ throw error;
277
+ }
278
+ }
279
+ }
280
+ var componentLoader = new ComponentLoader;
281
+ export {
282
+ componentLoader,
283
+ ComponentLoader
284
+ };
285
+
286
+ //# debugId=A992D7F8B8CCB84164756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/logger.ts", "../src/loader.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Configurable Debug Logger\n *\n * Provides environment-aware logging that can be disabled in production.\n * Supports log levels, tagged output, and performance timing.\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"none\";\n\nexport interface LoggerConfig {\n /** Minimum log level (default: \"debug\" in dev, \"error\" in prod) */\n level: LogLevel;\n /** Enable colored output (default: true) */\n colors: boolean;\n /** Include timestamps (default: false) */\n timestamps: boolean;\n /** Custom log handler (default: console) */\n handler?: LogHandler;\n}\n\nexport interface LogHandler {\n debug(tag: string, ...args: unknown[]): void;\n info(tag: string, ...args: unknown[]): void;\n warn(tag: string, ...args: unknown[]): void;\n error(tag: string, ...args: unknown[]): void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst LOG_LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n none: 4,\n};\n\nconst LOG_LEVEL_COLORS: Record<Exclude<LogLevel, \"none\">, string> = {\n debug: \"\\x1b[36m\", // Cyan\n info: \"\\x1b[32m\", // Green\n warn: \"\\x1b[33m\", // Yellow\n error: \"\\x1b[31m\", // Red\n};\n\nconst RESET_COLOR = \"\\x1b[0m\";\n\n// ============================================================================\n// Global Configuration\n// ============================================================================\n\n/**\n * Detect if running in production environment\n */\nfunction isProduction(): boolean {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env.NODE_ENV === \"production\";\n }\n return false;\n}\n\n/**\n * Default configuration\n */\nlet config: LoggerConfig = {\n level: isProduction() ? \"error\" : \"debug\",\n colors: true,\n timestamps: false,\n};\n\n// ============================================================================\n// Configuration API\n// ============================================================================\n\n/**\n * Set the global log level\n */\nexport function setLogLevel(level: LogLevel): void {\n config.level = level;\n}\n\n/**\n * Get the current log level\n */\nexport function getLogLevel(): LogLevel {\n return config.level;\n}\n\n/**\n * Configure the logger\n */\nexport function configureLogger(options: Partial<LoggerConfig>): void {\n config = { ...config, ...options };\n}\n\n/**\n * Enable all logging (sets level to \"debug\")\n */\nexport function enableLogging(): void {\n config.level = \"debug\";\n}\n\n/**\n * Disable all logging (sets level to \"none\")\n */\nexport function disableLogging(): void {\n config.level = \"none\";\n}\n\n/**\n * Enable debug mode - alias for enableLogging()\n * Call this at app startup to see all debug logs\n *\n * @example\n * ```typescript\n * import { setDebugMode } from \"@hypen-space/core\";\n * setDebugMode(true);\n * ```\n */\nexport function setDebugMode(enabled: boolean): void {\n config.level = enabled ? \"debug\" : \"error\";\n}\n\n/**\n * Check if debug mode is enabled\n */\nexport function isDebugMode(): boolean {\n return config.level === \"debug\";\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\nfunction shouldLog(level: LogLevel): boolean {\n return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];\n}\n\nfunction formatTag(tag: string, level: LogLevel): string {\n const timestamp = config.timestamps ? `${new Date().toISOString()} ` : \"\";\n\n if (config.colors && level !== \"none\") {\n const color = LOG_LEVEL_COLORS[level as Exclude<LogLevel, \"none\">];\n return `${timestamp}${color}[${tag}]${RESET_COLOR}`;\n }\n\n return `${timestamp}[${tag}]`;\n}\n\n// ============================================================================\n// Logger Class\n// ============================================================================\n\n/**\n * Tagged logger instance\n *\n * @example\n * ```typescript\n * const log = createLogger(\"MyComponent\");\n * log.debug(\"initialized with\", { props });\n * log.error(\"failed to load\", error);\n * ```\n */\nexport class Logger {\n private readonly tag: string;\n\n constructor(tag: string) {\n this.tag = tag;\n }\n\n debug(...args: unknown[]): void {\n if (!shouldLog(\"debug\")) return;\n\n if (config.handler) {\n config.handler.debug(this.tag, ...args);\n } else {\n console.log(formatTag(this.tag, \"debug\"), ...args);\n }\n }\n\n info(...args: unknown[]): void {\n if (!shouldLog(\"info\")) return;\n\n if (config.handler) {\n config.handler.info(this.tag, ...args);\n } else {\n console.info(formatTag(this.tag, \"info\"), ...args);\n }\n }\n\n warn(...args: unknown[]): void {\n if (!shouldLog(\"warn\")) return;\n\n if (config.handler) {\n config.handler.warn(this.tag, ...args);\n } else {\n console.warn(formatTag(this.tag, \"warn\"), ...args);\n }\n }\n\n error(...args: unknown[]): void {\n if (!shouldLog(\"error\")) return;\n\n if (config.handler) {\n config.handler.error(this.tag, ...args);\n } else {\n console.error(formatTag(this.tag, \"error\"), ...args);\n }\n }\n\n /**\n * Time a function execution\n */\n time<T>(label: string, fn: () => T): T {\n if (!shouldLog(\"debug\")) {\n return fn();\n }\n\n const start = performance.now();\n try {\n return fn();\n } finally {\n const duration = performance.now() - start;\n this.debug(`${label}: ${duration.toFixed(2)}ms`);\n }\n }\n\n /**\n * Time an async function execution\n */\n async timeAsync<T>(label: string, fn: () => Promise<T>): Promise<T> {\n if (!shouldLog(\"debug\")) {\n return fn();\n }\n\n const start = performance.now();\n try {\n return await fn();\n } finally {\n const duration = performance.now() - start;\n this.debug(`${label}: ${duration.toFixed(2)}ms`);\n }\n }\n\n /**\n * Create a child logger with additional context\n */\n child(subTag: string): Logger {\n return new Logger(`${this.tag}:${subTag}`);\n }\n\n /**\n * Conditionally log based on a condition\n */\n debugIf(condition: boolean, ...args: unknown[]): void {\n if (condition) this.debug(...args);\n }\n\n warnIf(condition: boolean, ...args: unknown[]): void {\n if (condition) this.warn(...args);\n }\n\n errorIf(condition: boolean, ...args: unknown[]): void {\n if (condition) this.error(...args);\n }\n\n /**\n * Log once (useful for deprecation warnings)\n */\n private loggedOnce = new Set<string>();\n\n warnOnce(key: string, ...args: unknown[]): void {\n if (this.loggedOnce.has(key)) return;\n this.loggedOnce.add(key);\n this.warn(...args);\n }\n\n debugOnce(key: string, ...args: unknown[]): void {\n if (this.loggedOnce.has(key)) return;\n this.loggedOnce.add(key);\n this.debug(...args);\n }\n}\n\n// ============================================================================\n// Factory Functions\n// ============================================================================\n\n/**\n * Create a tagged logger\n *\n * @example\n * ```typescript\n * const log = createLogger(\"Router\");\n * log.info(\"navigating to\", path);\n * ```\n */\nexport function createLogger(tag: string): Logger {\n return new Logger(tag);\n}\n\n// ============================================================================\n// Default Logger Instance\n// ============================================================================\n\n/**\n * Default logger for general use\n */\nexport const logger = createLogger(\"Hypen\");\n\n// ============================================================================\n// Shorthand Functions (untagged)\n// ============================================================================\n\n/**\n * Shorthand logging functions for quick use\n * Prefer createLogger() for component-specific logging\n */\nexport const log = {\n debug: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"debug\")) return;\n console.log(formatTag(tag, \"debug\"), ...args);\n },\n\n info: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"info\")) return;\n console.info(formatTag(tag, \"info\"), ...args);\n },\n\n warn: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"warn\")) return;\n console.warn(formatTag(tag, \"warn\"), ...args);\n },\n\n error: (tag: string, ...args: unknown[]): void => {\n if (!shouldLog(\"error\")) return;\n console.error(formatTag(tag, \"error\"), ...args);\n },\n};\n\n// ============================================================================\n// Predefined Loggers for Framework Components\n// ============================================================================\n\nexport const frameworkLoggers = {\n hypen: createLogger(\"Hypen\"),\n engine: createLogger(\"Engine\"),\n router: createLogger(\"Router\"),\n state: createLogger(\"State\"),\n events: createLogger(\"Events\"),\n remote: createLogger(\"Remote\"),\n renderer: createLogger(\"Renderer\"),\n module: createLogger(\"Module\"),\n lifecycle: createLogger(\"Lifecycle\"),\n loader: createLogger(\"Loader\"),\n context: createLogger(\"Context\"),\n discovery: createLogger(\"Discovery\"),\n plugin: createLogger(\"Plugin\"),\n canvas: createLogger(\"Canvas\"),\n debug: createLogger(\"Debug\"),\n};\n",
6
+ "/**\n * Component Loader\n *\n * Loads and registers Hypen components from file system.\n * Works in both Node.js and Bun environments.\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport type { HypenModuleDefinition } from \"./app.js\";\nimport { frameworkLoggers } from \"./logger.js\";\n\nconst log = frameworkLoggers.loader;\n\nexport interface ComponentDefinition {\n name: string;\n module: HypenModuleDefinition<any>;\n template: string; // The .hypen file content\n path: string;\n}\n\nexport class ComponentLoader {\n private components = new Map<string, ComponentDefinition>();\n\n /**\n * Register a component with its module and template\n */\n register(\n name: string,\n module: HypenModuleDefinition<any>,\n template: string,\n path?: string\n ): void {\n this.components.set(name, {\n name,\n module,\n template,\n path: path || name,\n });\n }\n\n /**\n * Get a registered component by name\n */\n get(name: string): ComponentDefinition | undefined {\n return this.components.get(name);\n }\n\n /**\n * Check if a component is registered\n */\n has(name: string): boolean {\n return this.components.has(name);\n }\n\n /**\n * Get all registered component names\n */\n getNames(): string[] {\n return Array.from(this.components.keys());\n }\n\n /**\n * Get all registered components\n */\n getAll(): ComponentDefinition[] {\n return Array.from(this.components.values());\n }\n\n /**\n * Clear all registered components\n */\n clear(): void {\n this.components.clear();\n }\n\n /**\n * Load a component from a directory\n * Expects: component.ts and component.hypen in the same directory\n */\n async loadFromDirectory(name: string, dirPath: string): Promise<void> {\n try {\n // Dynamic import of the module\n const modulePath = join(dirPath, \"component.ts\");\n const moduleExport = await import(modulePath);\n const module = moduleExport.default as HypenModuleDefinition<any>;\n\n // Read the .hypen template file\n const templatePath = join(dirPath, \"component.hypen\");\n const template = readFileSync(templatePath, \"utf-8\");\n\n // Register the component\n this.register(name, module, template, dirPath);\n\n log.debug(`Loaded component: ${name} from ${dirPath}`);\n } catch (error) {\n log.error(`Failed to load component ${name} from ${dirPath}:`, error);\n throw error;\n }\n }\n\n /**\n * Auto-load all components from a directory\n * Scans for subdirectories containing component.ts and component.hypen\n */\n async loadFromComponentsDir(baseDir: string): Promise<void> {\n try {\n if (!existsSync(baseDir)) {\n log.warn(`Components directory not found: ${baseDir}`);\n return;\n }\n\n const entries = readdirSync(baseDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n\n const componentDir = join(baseDir, entry.name);\n const hypenPath = join(componentDir, \"component.hypen\");\n\n // Only load if component.hypen exists\n if (existsSync(hypenPath)) {\n await this.loadFromDirectory(entry.name, componentDir);\n }\n }\n\n log.debug(`Loaded ${this.components.size} components from ${baseDir}`);\n } catch (error) {\n log.error(`Failed to load components from ${baseDir}:`, error);\n throw error;\n }\n }\n}\n\n// Global component loader instance\nexport const componentLoader = new ComponentLoader();\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "A992D7F8B8CCB84164756E2164756E21",
10
+ "names": []
11
+ }
package/dist/plugin.js ADDED
@@ -0,0 +1,334 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
+
13
+ // src/logger.ts
14
+ function isProduction() {
15
+ if (typeof process !== "undefined" && process.env) {
16
+ return false;
17
+ }
18
+ return false;
19
+ }
20
+ function setLogLevel(level) {
21
+ config.level = level;
22
+ }
23
+ function getLogLevel() {
24
+ return config.level;
25
+ }
26
+ function configureLogger(options) {
27
+ config = { ...config, ...options };
28
+ }
29
+ function enableLogging() {
30
+ config.level = "debug";
31
+ }
32
+ function disableLogging() {
33
+ config.level = "none";
34
+ }
35
+ function setDebugMode(enabled) {
36
+ config.level = enabled ? "debug" : "error";
37
+ }
38
+ function isDebugMode() {
39
+ return config.level === "debug";
40
+ }
41
+ function shouldLog(level) {
42
+ return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
43
+ }
44
+ function formatTag(tag, level) {
45
+ const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
46
+ if (config.colors && level !== "none") {
47
+ const color = LOG_LEVEL_COLORS[level];
48
+ return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
49
+ }
50
+ return `${timestamp}[${tag}]`;
51
+ }
52
+
53
+ class Logger {
54
+ tag;
55
+ constructor(tag) {
56
+ this.tag = tag;
57
+ }
58
+ debug(...args) {
59
+ if (!shouldLog("debug"))
60
+ return;
61
+ if (config.handler) {
62
+ config.handler.debug(this.tag, ...args);
63
+ } else {
64
+ console.log(formatTag(this.tag, "debug"), ...args);
65
+ }
66
+ }
67
+ info(...args) {
68
+ if (!shouldLog("info"))
69
+ return;
70
+ if (config.handler) {
71
+ config.handler.info(this.tag, ...args);
72
+ } else {
73
+ console.info(formatTag(this.tag, "info"), ...args);
74
+ }
75
+ }
76
+ warn(...args) {
77
+ if (!shouldLog("warn"))
78
+ return;
79
+ if (config.handler) {
80
+ config.handler.warn(this.tag, ...args);
81
+ } else {
82
+ console.warn(formatTag(this.tag, "warn"), ...args);
83
+ }
84
+ }
85
+ error(...args) {
86
+ if (!shouldLog("error"))
87
+ return;
88
+ if (config.handler) {
89
+ config.handler.error(this.tag, ...args);
90
+ } else {
91
+ console.error(formatTag(this.tag, "error"), ...args);
92
+ }
93
+ }
94
+ time(label, fn) {
95
+ if (!shouldLog("debug")) {
96
+ return fn();
97
+ }
98
+ const start = performance.now();
99
+ try {
100
+ return fn();
101
+ } finally {
102
+ const duration = performance.now() - start;
103
+ this.debug(`${label}: ${duration.toFixed(2)}ms`);
104
+ }
105
+ }
106
+ async timeAsync(label, fn) {
107
+ if (!shouldLog("debug")) {
108
+ return fn();
109
+ }
110
+ const start = performance.now();
111
+ try {
112
+ return await fn();
113
+ } finally {
114
+ const duration = performance.now() - start;
115
+ this.debug(`${label}: ${duration.toFixed(2)}ms`);
116
+ }
117
+ }
118
+ child(subTag) {
119
+ return new Logger(`${this.tag}:${subTag}`);
120
+ }
121
+ debugIf(condition, ...args) {
122
+ if (condition)
123
+ this.debug(...args);
124
+ }
125
+ warnIf(condition, ...args) {
126
+ if (condition)
127
+ this.warn(...args);
128
+ }
129
+ errorIf(condition, ...args) {
130
+ if (condition)
131
+ this.error(...args);
132
+ }
133
+ loggedOnce = new Set;
134
+ warnOnce(key, ...args) {
135
+ if (this.loggedOnce.has(key))
136
+ return;
137
+ this.loggedOnce.add(key);
138
+ this.warn(...args);
139
+ }
140
+ debugOnce(key, ...args) {
141
+ if (this.loggedOnce.has(key))
142
+ return;
143
+ this.loggedOnce.add(key);
144
+ this.debug(...args);
145
+ }
146
+ }
147
+ function createLogger(tag) {
148
+ return new Logger(tag);
149
+ }
150
+ var LOG_LEVEL_ORDER, LOG_LEVEL_COLORS, RESET_COLOR = "\x1B[0m", config, logger, log, frameworkLoggers;
151
+ var init_logger = __esm(() => {
152
+ LOG_LEVEL_ORDER = {
153
+ debug: 0,
154
+ info: 1,
155
+ warn: 2,
156
+ error: 3,
157
+ none: 4
158
+ };
159
+ LOG_LEVEL_COLORS = {
160
+ debug: "\x1B[36m",
161
+ info: "\x1B[32m",
162
+ warn: "\x1B[33m",
163
+ error: "\x1B[31m"
164
+ };
165
+ config = {
166
+ level: isProduction() ? "error" : "debug",
167
+ colors: true,
168
+ timestamps: false
169
+ };
170
+ logger = createLogger("Hypen");
171
+ log = {
172
+ debug: (tag, ...args) => {
173
+ if (!shouldLog("debug"))
174
+ return;
175
+ console.log(formatTag(tag, "debug"), ...args);
176
+ },
177
+ info: (tag, ...args) => {
178
+ if (!shouldLog("info"))
179
+ return;
180
+ console.info(formatTag(tag, "info"), ...args);
181
+ },
182
+ warn: (tag, ...args) => {
183
+ if (!shouldLog("warn"))
184
+ return;
185
+ console.warn(formatTag(tag, "warn"), ...args);
186
+ },
187
+ error: (tag, ...args) => {
188
+ if (!shouldLog("error"))
189
+ return;
190
+ console.error(formatTag(tag, "error"), ...args);
191
+ }
192
+ };
193
+ frameworkLoggers = {
194
+ hypen: createLogger("Hypen"),
195
+ engine: createLogger("Engine"),
196
+ router: createLogger("Router"),
197
+ state: createLogger("State"),
198
+ events: createLogger("Events"),
199
+ remote: createLogger("Remote"),
200
+ renderer: createLogger("Renderer"),
201
+ module: createLogger("Module"),
202
+ lifecycle: createLogger("Lifecycle"),
203
+ loader: createLogger("Loader"),
204
+ context: createLogger("Context"),
205
+ discovery: createLogger("Discovery"),
206
+ plugin: createLogger("Plugin"),
207
+ canvas: createLogger("Canvas"),
208
+ debug: createLogger("Debug")
209
+ };
210
+ });
211
+
212
+ // src/plugin.ts
213
+ init_logger();
214
+ import { readFileSync, existsSync } from "fs";
215
+ import { dirname, basename, join, resolve } from "path";
216
+ function findModulePath(hypenPath, patterns) {
217
+ const dir = dirname(hypenPath);
218
+ const baseName = basename(hypenPath, ".hypen");
219
+ const parentDir = dirname(dir);
220
+ const folderName = basename(dir);
221
+ for (const pattern of patterns) {
222
+ let candidatePath = null;
223
+ switch (pattern) {
224
+ case "sibling":
225
+ candidatePath = join(dir, `${baseName}.ts`);
226
+ break;
227
+ case "component":
228
+ if (baseName === "component") {
229
+ candidatePath = join(dir, "component.ts");
230
+ }
231
+ break;
232
+ case "index":
233
+ if (baseName === "index") {
234
+ candidatePath = join(dir, "index.ts");
235
+ }
236
+ break;
237
+ }
238
+ if (candidatePath && existsSync(candidatePath)) {
239
+ return candidatePath;
240
+ }
241
+ }
242
+ return null;
243
+ }
244
+ function getComponentName(hypenPath) {
245
+ const baseName = basename(hypenPath, ".hypen");
246
+ if (baseName === "component" || baseName === "index") {
247
+ return basename(dirname(hypenPath));
248
+ }
249
+ return baseName;
250
+ }
251
+ function parseImports(text) {
252
+ const imports = [];
253
+ const importRegex = /import\s+(?:\{([^}]+)\}|(\w+))\s+from\s+["']([^"']+)["']/g;
254
+ let match;
255
+ while ((match = importRegex.exec(text)) !== null) {
256
+ const [, namedImports, defaultImport, source] = match;
257
+ if (!source)
258
+ continue;
259
+ let names;
260
+ if (namedImports) {
261
+ names = namedImports.split(",").map((n) => n.trim()).filter((n) => n.length > 0);
262
+ } else if (defaultImport) {
263
+ names = [defaultImport];
264
+ } else {
265
+ continue;
266
+ }
267
+ imports.push({ names, source });
268
+ }
269
+ return imports;
270
+ }
271
+ function removeImports(text) {
272
+ return text.replace(/import\s+(?:\{[^}]+\}|\w+)\s+from\s+["'][^"']+["']\s*/g, "");
273
+ }
274
+ function hypenPlugin(options = {}) {
275
+ const { debug = false, patterns = ["sibling", "component", "index"] } = options;
276
+ const log2 = debug ? (...args) => frameworkLoggers.plugin.debug(...args) : () => {};
277
+ return {
278
+ name: "hypen-loader",
279
+ async setup(build) {
280
+ build.onLoad({ filter: /\.hypen$/ }, async (args) => {
281
+ const hypenPath = resolve(args.path);
282
+ log2("Loading:", hypenPath);
283
+ const templateRaw = readFileSync(hypenPath, "utf-8");
284
+ const imports = parseImports(templateRaw);
285
+ const template = removeImports(templateRaw).trim();
286
+ if (imports.length > 0) {
287
+ log2("Found imports:", imports);
288
+ }
289
+ const componentName = getComponentName(hypenPath);
290
+ log2("Component name:", componentName);
291
+ const modulePath = findModulePath(hypenPath, patterns);
292
+ log2("Module path:", modulePath);
293
+ let contents;
294
+ if (modulePath) {
295
+ const relativeModulePath = modulePath.replace(/\.ts$/, ".js");
296
+ contents = `
297
+ import _module from "${relativeModulePath}";
298
+ export const module = _module;
299
+ export const template = ${JSON.stringify(template)};
300
+ export const name = ${JSON.stringify(componentName)};
301
+ export default { module: _module, template: ${JSON.stringify(template)}, name: ${JSON.stringify(componentName)} };
302
+ `;
303
+ } else {
304
+ log2("No module found, creating stateless component");
305
+ contents = `
306
+ import { app } from "@hypen-space/core";
307
+ const _module = app.defineState({}).build();
308
+ export const module = _module;
309
+ export const template = ${JSON.stringify(template)};
310
+ export const name = ${JSON.stringify(componentName)};
311
+ export default { module: _module, template: ${JSON.stringify(template)}, name: ${JSON.stringify(componentName)} };
312
+ `;
313
+ }
314
+ return {
315
+ contents,
316
+ loader: "js"
317
+ };
318
+ });
319
+ }
320
+ };
321
+ }
322
+ var defaultHypenPlugin = hypenPlugin();
323
+ function registerHypenPlugin(options) {
324
+ Bun.plugin(hypenPlugin(options));
325
+ }
326
+ var plugin_default = hypenPlugin;
327
+ export {
328
+ registerHypenPlugin,
329
+ hypenPlugin,
330
+ defaultHypenPlugin,
331
+ plugin_default as default
332
+ };
333
+
334
+ //# debugId=3773FE970CDAA3A764756E2164756E21