@hypen-space/core 0.3.11 → 0.4.0
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/dist/app.js +24 -3
- package/dist/app.js.map +3 -3
- package/dist/components/builtin.js +24 -3
- package/dist/components/builtin.js.map +3 -3
- package/dist/context.js +18 -1
- package/dist/context.js.map +2 -2
- package/dist/discovery.js +25 -7
- package/dist/discovery.js.map +4 -4
- package/dist/disposable.js +18 -1
- package/dist/disposable.js.map +2 -2
- package/dist/engine.browser.js +18 -1
- package/dist/engine.browser.js.map +3 -3
- package/dist/engine.js +18 -1
- package/dist/engine.js.map +3 -3
- package/dist/events.js +18 -1
- package/dist/events.js.map +2 -2
- package/dist/index.browser.js +259 -371
- package/dist/index.browser.js.map +8 -9
- package/dist/index.js +558 -647
- package/dist/index.js.map +12 -13
- package/dist/loader.js +18 -1
- package/dist/loader.js.map +2 -2
- package/dist/plugin.js +18 -1
- package/dist/plugin.js.map +2 -2
- package/dist/remote/client.js +18 -1
- package/dist/remote/client.js.map +3 -3
- package/dist/remote/index.js +353 -332
- package/dist/remote/index.js.map +8 -8
- package/dist/remote/server.js +234 -213
- package/dist/remote/server.js.map +7 -7
- package/dist/renderer.js +18 -1
- package/dist/renderer.js.map +3 -3
- package/dist/resolver.js +48 -4
- package/dist/resolver.js.map +3 -3
- package/dist/router.js +18 -1
- package/dist/router.js.map +2 -2
- package/dist/state.js +18 -1
- package/dist/state.js.map +2 -2
- package/package.json +7 -1
- package/src/app.ts +14 -2
- package/src/discovery.ts +3 -1
- package/src/engine.browser.ts +4 -32
- package/src/engine.ts +4 -32
- package/src/index.browser.ts +6 -4
- package/src/index.ts +6 -6
- package/src/managed-router.ts +195 -0
- package/src/module-registry.ts +76 -0
- package/src/remote/client.ts +1 -1
- package/src/remote/index.ts +2 -2
- package/src/remote/server.ts +1 -1
- package/src/remote/types.ts +1 -1
- package/src/renderer.ts +1 -1
- package/src/resolver.ts +56 -9
- package/src/types.ts +38 -0
- package/wasm-browser/README.md +7 -1
- package/wasm-browser/hypen_engine.d.ts +1 -0
- package/wasm-browser/hypen_engine.js +1 -0
- package/wasm-browser/hypen_engine_bg.wasm +0 -0
- package/wasm-browser/package.json +1 -1
- package/wasm-node/README.md +7 -1
- package/wasm-node/hypen_engine.d.ts +1 -0
- package/wasm-node/hypen_engine.js +1 -0
- package/wasm-node/hypen_engine_bg.wasm +0 -0
- package/wasm-node/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
1
4
|
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
2
18
|
var __export = (target, all) => {
|
|
3
19
|
for (var name in all)
|
|
4
20
|
__defProp(target, name, {
|
|
@@ -9,205 +25,7 @@ var __export = (target, all) => {
|
|
|
9
25
|
});
|
|
10
26
|
};
|
|
11
27
|
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
|
-
});
|
|
28
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
211
29
|
|
|
212
30
|
// src/state.ts
|
|
213
31
|
function deepClone(obj) {
|
|
@@ -595,57 +413,256 @@ var init_result = __esm(() => {
|
|
|
595
413
|
};
|
|
596
414
|
});
|
|
597
415
|
|
|
598
|
-
// src/
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
HypenModuleInstance: () => HypenModuleInstance,
|
|
603
|
-
HypenAppBuilder: () => HypenAppBuilder,
|
|
604
|
-
HypenApp: () => HypenApp
|
|
605
|
-
});
|
|
606
|
-
|
|
607
|
-
class HypenAppBuilder {
|
|
608
|
-
initialState;
|
|
609
|
-
options;
|
|
610
|
-
createdHandler;
|
|
611
|
-
actionHandlers = new Map;
|
|
612
|
-
destroyedHandler;
|
|
613
|
-
disconnectHandler;
|
|
614
|
-
reconnectHandler;
|
|
615
|
-
expireHandler;
|
|
616
|
-
errorHandler;
|
|
617
|
-
template;
|
|
618
|
-
constructor(initialState, options) {
|
|
619
|
-
this.initialState = initialState;
|
|
620
|
-
this.options = options || {};
|
|
621
|
-
}
|
|
622
|
-
onCreated(fn) {
|
|
623
|
-
this.createdHandler = fn;
|
|
624
|
-
return this;
|
|
625
|
-
}
|
|
626
|
-
onAction(name, fn) {
|
|
627
|
-
this.actionHandlers.set(name, fn);
|
|
628
|
-
return this;
|
|
629
|
-
}
|
|
630
|
-
onDestroyed(fn) {
|
|
631
|
-
this.destroyedHandler = fn;
|
|
632
|
-
return this;
|
|
633
|
-
}
|
|
634
|
-
onDisconnect(fn) {
|
|
635
|
-
this.disconnectHandler = fn;
|
|
636
|
-
return this;
|
|
637
|
-
}
|
|
638
|
-
onReconnect(fn) {
|
|
639
|
-
this.reconnectHandler = fn;
|
|
640
|
-
return this;
|
|
641
|
-
}
|
|
642
|
-
onExpire(fn) {
|
|
643
|
-
this.expireHandler = fn;
|
|
644
|
-
return this;
|
|
416
|
+
// src/logger.ts
|
|
417
|
+
function isProduction() {
|
|
418
|
+
if (typeof process !== "undefined" && process.env) {
|
|
419
|
+
return false;
|
|
645
420
|
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
function setLogLevel(level) {
|
|
424
|
+
config.level = level;
|
|
425
|
+
}
|
|
426
|
+
function getLogLevel() {
|
|
427
|
+
return config.level;
|
|
428
|
+
}
|
|
429
|
+
function configureLogger(options) {
|
|
430
|
+
config = { ...config, ...options };
|
|
431
|
+
}
|
|
432
|
+
function enableLogging() {
|
|
433
|
+
config.level = "debug";
|
|
434
|
+
}
|
|
435
|
+
function disableLogging() {
|
|
436
|
+
config.level = "none";
|
|
437
|
+
}
|
|
438
|
+
function setDebugMode(enabled) {
|
|
439
|
+
config.level = enabled ? "debug" : "error";
|
|
440
|
+
}
|
|
441
|
+
function isDebugMode() {
|
|
442
|
+
return config.level === "debug";
|
|
443
|
+
}
|
|
444
|
+
function shouldLog(level) {
|
|
445
|
+
return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
|
|
446
|
+
}
|
|
447
|
+
function formatTag(tag, level) {
|
|
448
|
+
const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
|
|
449
|
+
if (config.colors && level !== "none") {
|
|
450
|
+
const color = LOG_LEVEL_COLORS[level];
|
|
451
|
+
return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
|
|
452
|
+
}
|
|
453
|
+
return `${timestamp}[${tag}]`;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
class Logger {
|
|
457
|
+
tag;
|
|
458
|
+
constructor(tag) {
|
|
459
|
+
this.tag = tag;
|
|
460
|
+
}
|
|
461
|
+
debug(...args) {
|
|
462
|
+
if (!shouldLog("debug"))
|
|
463
|
+
return;
|
|
464
|
+
if (config.handler) {
|
|
465
|
+
config.handler.debug(this.tag, ...args);
|
|
466
|
+
} else {
|
|
467
|
+
console.log(formatTag(this.tag, "debug"), ...args);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
info(...args) {
|
|
471
|
+
if (!shouldLog("info"))
|
|
472
|
+
return;
|
|
473
|
+
if (config.handler) {
|
|
474
|
+
config.handler.info(this.tag, ...args);
|
|
475
|
+
} else {
|
|
476
|
+
console.info(formatTag(this.tag, "info"), ...args);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
warn(...args) {
|
|
480
|
+
if (!shouldLog("warn"))
|
|
481
|
+
return;
|
|
482
|
+
if (config.handler) {
|
|
483
|
+
config.handler.warn(this.tag, ...args);
|
|
484
|
+
} else {
|
|
485
|
+
console.warn(formatTag(this.tag, "warn"), ...args);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
error(...args) {
|
|
489
|
+
if (!shouldLog("error"))
|
|
490
|
+
return;
|
|
491
|
+
if (config.handler) {
|
|
492
|
+
config.handler.error(this.tag, ...args);
|
|
493
|
+
} else {
|
|
494
|
+
console.error(formatTag(this.tag, "error"), ...args);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
time(label, fn) {
|
|
498
|
+
if (!shouldLog("debug")) {
|
|
499
|
+
return fn();
|
|
500
|
+
}
|
|
501
|
+
const start = performance.now();
|
|
502
|
+
try {
|
|
503
|
+
return fn();
|
|
504
|
+
} finally {
|
|
505
|
+
const duration = performance.now() - start;
|
|
506
|
+
this.debug(`${label}: ${duration.toFixed(2)}ms`);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
async timeAsync(label, fn) {
|
|
510
|
+
if (!shouldLog("debug")) {
|
|
511
|
+
return fn();
|
|
512
|
+
}
|
|
513
|
+
const start = performance.now();
|
|
514
|
+
try {
|
|
515
|
+
return await fn();
|
|
516
|
+
} finally {
|
|
517
|
+
const duration = performance.now() - start;
|
|
518
|
+
this.debug(`${label}: ${duration.toFixed(2)}ms`);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
child(subTag) {
|
|
522
|
+
return new Logger(`${this.tag}:${subTag}`);
|
|
523
|
+
}
|
|
524
|
+
debugIf(condition, ...args) {
|
|
525
|
+
if (condition)
|
|
526
|
+
this.debug(...args);
|
|
527
|
+
}
|
|
528
|
+
warnIf(condition, ...args) {
|
|
529
|
+
if (condition)
|
|
530
|
+
this.warn(...args);
|
|
531
|
+
}
|
|
532
|
+
errorIf(condition, ...args) {
|
|
533
|
+
if (condition)
|
|
534
|
+
this.error(...args);
|
|
535
|
+
}
|
|
536
|
+
loggedOnce = new Set;
|
|
537
|
+
warnOnce(key, ...args) {
|
|
538
|
+
if (this.loggedOnce.has(key))
|
|
539
|
+
return;
|
|
540
|
+
this.loggedOnce.add(key);
|
|
541
|
+
this.warn(...args);
|
|
542
|
+
}
|
|
543
|
+
debugOnce(key, ...args) {
|
|
544
|
+
if (this.loggedOnce.has(key))
|
|
545
|
+
return;
|
|
546
|
+
this.loggedOnce.add(key);
|
|
547
|
+
this.debug(...args);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
function createLogger(tag) {
|
|
551
|
+
return new Logger(tag);
|
|
552
|
+
}
|
|
553
|
+
var LOG_LEVEL_ORDER, LOG_LEVEL_COLORS, RESET_COLOR = "\x1B[0m", config, logger, log, frameworkLoggers;
|
|
554
|
+
var init_logger = __esm(() => {
|
|
555
|
+
LOG_LEVEL_ORDER = {
|
|
556
|
+
debug: 0,
|
|
557
|
+
info: 1,
|
|
558
|
+
warn: 2,
|
|
559
|
+
error: 3,
|
|
560
|
+
none: 4
|
|
561
|
+
};
|
|
562
|
+
LOG_LEVEL_COLORS = {
|
|
563
|
+
debug: "\x1B[36m",
|
|
564
|
+
info: "\x1B[32m",
|
|
565
|
+
warn: "\x1B[33m",
|
|
566
|
+
error: "\x1B[31m"
|
|
567
|
+
};
|
|
568
|
+
config = {
|
|
569
|
+
level: isProduction() ? "error" : "debug",
|
|
570
|
+
colors: true,
|
|
571
|
+
timestamps: false
|
|
572
|
+
};
|
|
573
|
+
logger = createLogger("Hypen");
|
|
574
|
+
log = {
|
|
575
|
+
debug: (tag, ...args) => {
|
|
576
|
+
if (!shouldLog("debug"))
|
|
577
|
+
return;
|
|
578
|
+
console.log(formatTag(tag, "debug"), ...args);
|
|
579
|
+
},
|
|
580
|
+
info: (tag, ...args) => {
|
|
581
|
+
if (!shouldLog("info"))
|
|
582
|
+
return;
|
|
583
|
+
console.info(formatTag(tag, "info"), ...args);
|
|
584
|
+
},
|
|
585
|
+
warn: (tag, ...args) => {
|
|
586
|
+
if (!shouldLog("warn"))
|
|
587
|
+
return;
|
|
588
|
+
console.warn(formatTag(tag, "warn"), ...args);
|
|
589
|
+
},
|
|
590
|
+
error: (tag, ...args) => {
|
|
591
|
+
if (!shouldLog("error"))
|
|
592
|
+
return;
|
|
593
|
+
console.error(formatTag(tag, "error"), ...args);
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
frameworkLoggers = {
|
|
597
|
+
hypen: createLogger("Hypen"),
|
|
598
|
+
engine: createLogger("Engine"),
|
|
599
|
+
router: createLogger("Router"),
|
|
600
|
+
state: createLogger("State"),
|
|
601
|
+
events: createLogger("Events"),
|
|
602
|
+
remote: createLogger("Remote"),
|
|
603
|
+
renderer: createLogger("Renderer"),
|
|
604
|
+
module: createLogger("Module"),
|
|
605
|
+
lifecycle: createLogger("Lifecycle"),
|
|
606
|
+
loader: createLogger("Loader"),
|
|
607
|
+
context: createLogger("Context"),
|
|
608
|
+
discovery: createLogger("Discovery"),
|
|
609
|
+
plugin: createLogger("Plugin"),
|
|
610
|
+
canvas: createLogger("Canvas"),
|
|
611
|
+
debug: createLogger("Debug")
|
|
612
|
+
};
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
// src/app.ts
|
|
616
|
+
var exports_app = {};
|
|
617
|
+
__export(exports_app, {
|
|
618
|
+
app: () => app,
|
|
619
|
+
HypenModuleInstance: () => HypenModuleInstance,
|
|
620
|
+
HypenAppBuilder: () => HypenAppBuilder,
|
|
621
|
+
HypenApp: () => HypenApp
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
class HypenAppBuilder {
|
|
625
|
+
initialState;
|
|
626
|
+
options;
|
|
627
|
+
createdHandler;
|
|
628
|
+
actionHandlers = new Map;
|
|
629
|
+
destroyedHandler;
|
|
630
|
+
disconnectHandler;
|
|
631
|
+
reconnectHandler;
|
|
632
|
+
expireHandler;
|
|
633
|
+
errorHandler;
|
|
634
|
+
template;
|
|
635
|
+
constructor(initialState, options) {
|
|
636
|
+
this.initialState = initialState;
|
|
637
|
+
this.options = options || {};
|
|
638
|
+
}
|
|
639
|
+
onCreated(fn) {
|
|
640
|
+
this.createdHandler = fn;
|
|
641
|
+
return this;
|
|
642
|
+
}
|
|
643
|
+
onAction(name, fn) {
|
|
644
|
+
this.actionHandlers.set(name, fn);
|
|
645
|
+
return this;
|
|
646
|
+
}
|
|
647
|
+
onDestroyed(fn) {
|
|
648
|
+
this.destroyedHandler = fn;
|
|
649
|
+
return this;
|
|
650
|
+
}
|
|
651
|
+
onDisconnect(fn) {
|
|
652
|
+
this.disconnectHandler = fn;
|
|
653
|
+
return this;
|
|
654
|
+
}
|
|
655
|
+
onReconnect(fn) {
|
|
656
|
+
this.reconnectHandler = fn;
|
|
657
|
+
return this;
|
|
658
|
+
}
|
|
659
|
+
onExpire(fn) {
|
|
660
|
+
this.expireHandler = fn;
|
|
661
|
+
return this;
|
|
662
|
+
}
|
|
663
|
+
onError(fn) {
|
|
664
|
+
this.errorHandler = fn;
|
|
665
|
+
return this;
|
|
649
666
|
}
|
|
650
667
|
ui(template) {
|
|
651
668
|
this.template = template;
|
|
@@ -693,17 +710,21 @@ class HypenModuleInstance {
|
|
|
693
710
|
this.definition = definition;
|
|
694
711
|
this.routerContext = routerContext;
|
|
695
712
|
this.globalContext = globalContext;
|
|
713
|
+
const statePrefix = (definition.name || "").toLowerCase();
|
|
696
714
|
this.state = createObservableState(definition.initialState, {
|
|
697
715
|
onChange: (change) => {
|
|
698
716
|
this.engine.notifyStateChange(change.paths, change.newValues);
|
|
699
717
|
this.stateChangeCallbacks.forEach((cb) => cb());
|
|
700
|
-
}
|
|
718
|
+
},
|
|
719
|
+
pathPrefix: statePrefix || undefined
|
|
701
720
|
});
|
|
702
|
-
|
|
721
|
+
const snapshot = getStateSnapshot(this.state);
|
|
722
|
+
const prefixedState = statePrefix ? { [statePrefix]: snapshot } : snapshot;
|
|
723
|
+
this.engine.setModule(definition.name || "AnonymousModule", definition.actions, definition.stateKeys, prefixedState);
|
|
703
724
|
for (const [actionName, handler] of definition.handlers.onAction) {
|
|
704
|
-
|
|
725
|
+
log2.debug(`Registering action handler: ${actionName} for module ${definition.name}`);
|
|
705
726
|
this.engine.onAction(actionName, async (action) => {
|
|
706
|
-
|
|
727
|
+
log2.debug(`Action handler fired: ${actionName}`, action);
|
|
707
728
|
const actionCtx = {
|
|
708
729
|
name: action.name,
|
|
709
730
|
payload: action.payload,
|
|
@@ -725,7 +746,7 @@ class HypenModuleInstance {
|
|
|
725
746
|
throw result.error;
|
|
726
747
|
}
|
|
727
748
|
} else {
|
|
728
|
-
|
|
749
|
+
log2.debug(`Action handler completed: ${actionName}`);
|
|
729
750
|
}
|
|
730
751
|
});
|
|
731
752
|
}
|
|
@@ -735,341 +756,104 @@ class HypenModuleInstance {
|
|
|
735
756
|
if (!this.globalContext) {
|
|
736
757
|
throw new Error("Global context not available");
|
|
737
758
|
}
|
|
738
|
-
const ctx = this.globalContext;
|
|
739
|
-
const api = {
|
|
740
|
-
getModule: (id) => ctx.getModule(id),
|
|
741
|
-
hasModule: (id) => ctx.hasModule(id),
|
|
742
|
-
getModuleIds: () => ctx.getModuleIds(),
|
|
743
|
-
getGlobalState: () => ctx.getGlobalState(),
|
|
744
|
-
emit: (event, payload) => ctx.emit(event, payload),
|
|
745
|
-
on: (event, handler) => ctx.on(event, handler)
|
|
746
|
-
};
|
|
747
|
-
if (ctx.__router) {
|
|
748
|
-
api.__router = ctx.__router;
|
|
749
|
-
}
|
|
750
|
-
if (ctx.__hypenEngine) {
|
|
751
|
-
api.__hypenEngine = ctx.__hypenEngine;
|
|
752
|
-
}
|
|
753
|
-
return api;
|
|
754
|
-
}
|
|
755
|
-
async executeAction(actionName, handler, ctx) {
|
|
756
|
-
try {
|
|
757
|
-
const result = handler(ctx);
|
|
758
|
-
await result;
|
|
759
|
-
return Ok(undefined);
|
|
760
|
-
} catch (e) {
|
|
761
|
-
return Err(new ActionError(actionName, e));
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
async handleError(error, context) {
|
|
765
|
-
const errorCtx = {
|
|
766
|
-
error,
|
|
767
|
-
state: this.state,
|
|
768
|
-
actionName: context.actionName,
|
|
769
|
-
lifecycle: context.lifecycle
|
|
770
|
-
};
|
|
771
|
-
if (this.definition.handlers.onError) {
|
|
772
|
-
try {
|
|
773
|
-
const result = await this.definition.handlers.onError(errorCtx);
|
|
774
|
-
if (result && typeof result === "object") {
|
|
775
|
-
if ("handled" in result && result.handled) {
|
|
776
|
-
return false;
|
|
777
|
-
}
|
|
778
|
-
if ("rethrow" in result && result.rethrow) {
|
|
779
|
-
return true;
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
} catch (handlerError) {
|
|
783
|
-
log4.error("Error in onError handler:", handlerError);
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
if (this.globalContext) {
|
|
787
|
-
const eventContext = context.actionName ? `action:${context.actionName}` : context.lifecycle ? `lifecycle:${context.lifecycle}` : "unknown";
|
|
788
|
-
this.globalContext.emit("error", {
|
|
789
|
-
message: error.message,
|
|
790
|
-
error,
|
|
791
|
-
context: eventContext
|
|
792
|
-
});
|
|
793
|
-
}
|
|
794
|
-
log4.error(`${context.actionName ? `Action "${context.actionName}"` : `Lifecycle "${context.lifecycle}"`} error:`, error);
|
|
795
|
-
return false;
|
|
796
|
-
}
|
|
797
|
-
async callCreatedHandler() {
|
|
798
|
-
if (this.definition.handlers.onCreated) {
|
|
799
|
-
const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
|
|
800
|
-
await this.definition.handlers.onCreated(this.state, context);
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
onStateChange(callback) {
|
|
804
|
-
this.stateChangeCallbacks.push(callback);
|
|
805
|
-
}
|
|
806
|
-
async destroy() {
|
|
807
|
-
if (this.isDestroyed)
|
|
808
|
-
return;
|
|
809
|
-
if (this.definition.handlers.onDestroyed) {
|
|
810
|
-
await this.definition.handlers.onDestroyed(this.state);
|
|
811
|
-
}
|
|
812
|
-
this.isDestroyed = true;
|
|
813
|
-
}
|
|
814
|
-
getState() {
|
|
815
|
-
return getStateSnapshot(this.state);
|
|
816
|
-
}
|
|
817
|
-
getLiveState() {
|
|
818
|
-
return this.state;
|
|
819
|
-
}
|
|
820
|
-
updateState(patch) {
|
|
821
|
-
Object.assign(this.state, patch);
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
var log4, app;
|
|
825
|
-
var init_app = __esm(() => {
|
|
826
|
-
init_result();
|
|
827
|
-
init_state();
|
|
828
|
-
init_logger();
|
|
829
|
-
log4 = createLogger("ModuleInstance");
|
|
830
|
-
app = new HypenApp;
|
|
831
|
-
});
|
|
832
|
-
|
|
833
|
-
// src/engine.ts
|
|
834
|
-
init_logger();
|
|
835
|
-
import { WasmEngine } from "../wasm-node/hypen_engine.js";
|
|
836
|
-
var log2 = frameworkLoggers.engine;
|
|
837
|
-
function unwrapForWasm(value) {
|
|
838
|
-
if (value === null || typeof value !== "object") {
|
|
839
|
-
return value;
|
|
840
|
-
}
|
|
841
|
-
if (typeof value.__getSnapshot === "function") {
|
|
842
|
-
return value.__getSnapshot();
|
|
843
|
-
}
|
|
844
|
-
try {
|
|
845
|
-
return structuredClone(value);
|
|
846
|
-
} catch {
|
|
847
|
-
return JSON.parse(JSON.stringify(value));
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
class Engine {
|
|
852
|
-
wasmEngine = null;
|
|
853
|
-
initialized = false;
|
|
854
|
-
async init() {
|
|
855
|
-
if (this.initialized)
|
|
856
|
-
return;
|
|
857
|
-
this.wasmEngine = new WasmEngine;
|
|
858
|
-
this.initialized = true;
|
|
859
|
-
}
|
|
860
|
-
ensureInitialized() {
|
|
861
|
-
if (!this.wasmEngine) {
|
|
862
|
-
throw new Error("Engine not initialized. Call init() first.");
|
|
863
|
-
}
|
|
864
|
-
return this.wasmEngine;
|
|
865
|
-
}
|
|
866
|
-
setRenderCallback(callback) {
|
|
867
|
-
const engine = this.ensureInitialized();
|
|
868
|
-
engine.setRenderCallback((patches) => {
|
|
869
|
-
callback(patches);
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
setComponentResolver(resolver) {
|
|
873
|
-
const engine = this.ensureInitialized();
|
|
874
|
-
engine.setComponentResolver((componentName, contextPath) => {
|
|
875
|
-
const result = resolver(componentName, contextPath);
|
|
876
|
-
return result;
|
|
877
|
-
});
|
|
878
|
-
}
|
|
879
|
-
renderSource(source) {
|
|
880
|
-
const engine = this.ensureInitialized();
|
|
881
|
-
engine.renderSource(source);
|
|
882
|
-
}
|
|
883
|
-
renderLazyComponent(source) {
|
|
884
|
-
const engine = this.ensureInitialized();
|
|
885
|
-
engine.renderLazyComponent(source);
|
|
886
|
-
}
|
|
887
|
-
renderInto(source, parentNodeId, state) {
|
|
888
|
-
const engine = this.ensureInitialized();
|
|
889
|
-
engine.renderInto(source, parentNodeId, unwrapForWasm(state));
|
|
890
|
-
}
|
|
891
|
-
notifyStateChange(paths, values) {
|
|
892
|
-
const engine = this.ensureInitialized();
|
|
893
|
-
if (paths.length === 0) {
|
|
894
|
-
return;
|
|
895
|
-
}
|
|
896
|
-
engine.updateStateSparse(paths, unwrapForWasm(values));
|
|
897
|
-
log2.debug("State changed (sparse):", paths);
|
|
898
|
-
}
|
|
899
|
-
notifyStateChangeFull(paths, currentState) {
|
|
900
|
-
const engine = this.ensureInitialized();
|
|
901
|
-
engine.updateState(unwrapForWasm(currentState));
|
|
902
|
-
if (paths.length > 0) {
|
|
903
|
-
log2.debug("State changed (full):", paths);
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
updateState(statePatch) {
|
|
907
|
-
const engine = this.ensureInitialized();
|
|
908
|
-
engine.updateState(unwrapForWasm(statePatch));
|
|
909
|
-
}
|
|
910
|
-
dispatchAction(name, payload) {
|
|
911
|
-
const engine = this.ensureInitialized();
|
|
912
|
-
engine.dispatchAction(name, payload ?? null);
|
|
913
|
-
}
|
|
914
|
-
onAction(actionName, handler) {
|
|
915
|
-
const engine = this.ensureInitialized();
|
|
916
|
-
engine.onAction(actionName, (action) => {
|
|
917
|
-
Promise.resolve(handler(action)).catch((err) => log2.error("Action handler error:", err));
|
|
918
|
-
});
|
|
919
|
-
}
|
|
920
|
-
setModule(name, actions, stateKeys, initialState) {
|
|
921
|
-
const engine = this.ensureInitialized();
|
|
922
|
-
engine.setModule(name, actions, stateKeys, initialState);
|
|
923
|
-
}
|
|
924
|
-
getRevision() {
|
|
925
|
-
const engine = this.ensureInitialized();
|
|
926
|
-
return Number(engine.getRevision());
|
|
927
|
-
}
|
|
928
|
-
clearTree() {
|
|
929
|
-
const engine = this.ensureInitialized();
|
|
930
|
-
engine.clearTree();
|
|
931
|
-
}
|
|
932
|
-
debugParseComponent(source) {
|
|
933
|
-
const engine = this.ensureInitialized();
|
|
934
|
-
return engine.debugParseComponent(source);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
// src/engine.browser.ts
|
|
939
|
-
init_logger();
|
|
940
|
-
var log3 = frameworkLoggers.engine;
|
|
941
|
-
var wasmInit = null;
|
|
942
|
-
var WasmEngineClass = null;
|
|
943
|
-
function mapToObject(value) {
|
|
944
|
-
if (value instanceof Map) {
|
|
945
|
-
const obj = {};
|
|
946
|
-
for (const [key, val] of value.entries()) {
|
|
947
|
-
obj[key] = mapToObject(val);
|
|
948
|
-
}
|
|
949
|
-
return obj;
|
|
950
|
-
} else if (Array.isArray(value)) {
|
|
951
|
-
return value.map(mapToObject);
|
|
952
|
-
} else if (value && typeof value === "object" && value.constructor === Object) {
|
|
953
|
-
const obj = {};
|
|
954
|
-
for (const [key, val] of Object.entries(value)) {
|
|
955
|
-
obj[key] = mapToObject(val);
|
|
759
|
+
const ctx = this.globalContext;
|
|
760
|
+
const api = {
|
|
761
|
+
getModule: (id) => ctx.getModule(id),
|
|
762
|
+
hasModule: (id) => ctx.hasModule(id),
|
|
763
|
+
getModuleIds: () => ctx.getModuleIds(),
|
|
764
|
+
getGlobalState: () => ctx.getGlobalState(),
|
|
765
|
+
emit: (event, payload) => ctx.emit(event, payload),
|
|
766
|
+
on: (event, handler) => ctx.on(event, handler)
|
|
767
|
+
};
|
|
768
|
+
if (ctx.__router) {
|
|
769
|
+
api.__router = ctx.__router;
|
|
956
770
|
}
|
|
957
|
-
|
|
771
|
+
if (ctx.__hypenEngine) {
|
|
772
|
+
api.__hypenEngine = ctx.__hypenEngine;
|
|
773
|
+
}
|
|
774
|
+
return api;
|
|
958
775
|
}
|
|
959
|
-
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
class Engine2 {
|
|
963
|
-
wasmEngine = null;
|
|
964
|
-
initialized = false;
|
|
965
|
-
async init(options = {}) {
|
|
966
|
-
if (this.initialized)
|
|
967
|
-
return;
|
|
968
|
-
const cdnBase = "https://unpkg.com/@hypen-space/core@latest/wasm-browser";
|
|
969
|
-
const jsUrl = options.jsUrl ?? `${cdnBase}/hypen_engine.js`;
|
|
970
|
-
const wasmUrl = options.wasmUrl ?? `${cdnBase}/hypen_engine_bg.wasm`;
|
|
776
|
+
async executeAction(actionName, handler, ctx) {
|
|
971
777
|
try {
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
this.initialized = true;
|
|
978
|
-
} catch (error) {
|
|
979
|
-
log3.error("Failed to initialize WASM engine:", error);
|
|
980
|
-
throw error;
|
|
778
|
+
const result = handler(ctx);
|
|
779
|
+
await result;
|
|
780
|
+
return Ok(undefined);
|
|
781
|
+
} catch (e) {
|
|
782
|
+
return Err(new ActionError(actionName, e));
|
|
981
783
|
}
|
|
982
784
|
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
785
|
+
async handleError(error, context) {
|
|
786
|
+
const errorCtx = {
|
|
787
|
+
error,
|
|
788
|
+
state: this.state,
|
|
789
|
+
actionName: context.actionName,
|
|
790
|
+
lifecycle: context.lifecycle
|
|
791
|
+
};
|
|
792
|
+
if (this.definition.handlers.onError) {
|
|
793
|
+
try {
|
|
794
|
+
const result = await this.definition.handlers.onError(errorCtx);
|
|
795
|
+
if (result && typeof result === "object") {
|
|
796
|
+
if ("handled" in result && result.handled) {
|
|
797
|
+
return false;
|
|
798
|
+
}
|
|
799
|
+
if ("rethrow" in result && result.rethrow) {
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
} catch (handlerError) {
|
|
804
|
+
log2.error("Error in onError handler:", handlerError);
|
|
805
|
+
}
|
|
986
806
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
}
|
|
995
|
-
setComponentResolver(resolver) {
|
|
996
|
-
const engine = this.ensureInitialized();
|
|
997
|
-
engine.setComponentResolver((componentName, contextPath) => {
|
|
998
|
-
const result = resolver(componentName, contextPath);
|
|
999
|
-
return result;
|
|
1000
|
-
});
|
|
1001
|
-
}
|
|
1002
|
-
renderSource(source) {
|
|
1003
|
-
const engine = this.ensureInitialized();
|
|
1004
|
-
engine.renderSource(source);
|
|
1005
|
-
}
|
|
1006
|
-
renderLazyComponent(source) {
|
|
1007
|
-
const engine = this.ensureInitialized();
|
|
1008
|
-
engine.renderLazyComponent(source);
|
|
1009
|
-
}
|
|
1010
|
-
renderInto(source, parentNodeId, state) {
|
|
1011
|
-
const engine = this.ensureInitialized();
|
|
1012
|
-
const safeState = JSON.parse(JSON.stringify(state));
|
|
1013
|
-
engine.renderInto(source, parentNodeId, safeState);
|
|
1014
|
-
}
|
|
1015
|
-
notifyStateChange(paths, values) {
|
|
1016
|
-
const engine = this.ensureInitialized();
|
|
1017
|
-
if (paths.length === 0) {
|
|
1018
|
-
return;
|
|
807
|
+
if (this.globalContext) {
|
|
808
|
+
const eventContext = context.actionName ? `action:${context.actionName}` : context.lifecycle ? `lifecycle:${context.lifecycle}` : "unknown";
|
|
809
|
+
this.globalContext.emit("error", {
|
|
810
|
+
message: error.message,
|
|
811
|
+
error,
|
|
812
|
+
context: eventContext
|
|
813
|
+
});
|
|
1019
814
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
log3.debug("State changed (sparse):", paths);
|
|
815
|
+
log2.error(`${context.actionName ? `Action "${context.actionName}"` : `Lifecycle "${context.lifecycle}"`} error:`, error);
|
|
816
|
+
return false;
|
|
1023
817
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (paths.length > 0) {
|
|
1029
|
-
log3.debug("State changed (full):", paths);
|
|
818
|
+
async callCreatedHandler() {
|
|
819
|
+
if (this.definition.handlers.onCreated) {
|
|
820
|
+
const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
|
|
821
|
+
await this.definition.handlers.onCreated(this.state, context);
|
|
1030
822
|
}
|
|
1031
823
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
const plainObject = JSON.parse(JSON.stringify(statePatch));
|
|
1035
|
-
engine.updateState(plainObject);
|
|
1036
|
-
}
|
|
1037
|
-
dispatchAction(name, payload) {
|
|
1038
|
-
const engine = this.ensureInitialized();
|
|
1039
|
-
log3.debug(`Action dispatched: ${name}`);
|
|
1040
|
-
engine.dispatchAction(name, payload ?? null);
|
|
1041
|
-
}
|
|
1042
|
-
onAction(actionName, handler) {
|
|
1043
|
-
const engine = this.ensureInitialized();
|
|
1044
|
-
engine.onAction(actionName, (action) => {
|
|
1045
|
-
const normalizedAction = {
|
|
1046
|
-
...action,
|
|
1047
|
-
payload: action.payload ? mapToObject(action.payload) : action.payload
|
|
1048
|
-
};
|
|
1049
|
-
Promise.resolve(handler(normalizedAction)).catch((err) => log3.error("Action handler error:", err));
|
|
1050
|
-
});
|
|
824
|
+
onStateChange(callback) {
|
|
825
|
+
this.stateChangeCallbacks.push(callback);
|
|
1051
826
|
}
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
827
|
+
async destroy() {
|
|
828
|
+
if (this.isDestroyed)
|
|
829
|
+
return;
|
|
830
|
+
if (this.definition.handlers.onDestroyed) {
|
|
831
|
+
await this.definition.handlers.onDestroyed(this.state);
|
|
832
|
+
}
|
|
833
|
+
this.isDestroyed = true;
|
|
1055
834
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
return engine.getRevision();
|
|
835
|
+
getState() {
|
|
836
|
+
return getStateSnapshot(this.state);
|
|
1059
837
|
}
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
engine.clearTree();
|
|
838
|
+
getLiveState() {
|
|
839
|
+
return this.state;
|
|
1063
840
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
return engine.debugParseComponent(source);
|
|
841
|
+
updateState(patch) {
|
|
842
|
+
Object.assign(this.state, patch);
|
|
1067
843
|
}
|
|
1068
844
|
}
|
|
845
|
+
var log2, app;
|
|
846
|
+
var init_app = __esm(() => {
|
|
847
|
+
init_result();
|
|
848
|
+
init_state();
|
|
849
|
+
init_logger();
|
|
850
|
+
log2 = createLogger("ModuleInstance");
|
|
851
|
+
app = new HypenApp;
|
|
852
|
+
});
|
|
1069
853
|
|
|
1070
854
|
// src/renderer.ts
|
|
1071
855
|
init_logger();
|
|
1072
|
-
var
|
|
856
|
+
var log3 = frameworkLoggers.renderer;
|
|
1073
857
|
|
|
1074
858
|
class BaseRenderer {
|
|
1075
859
|
nodes = new Map;
|
|
@@ -1111,14 +895,14 @@ class BaseRenderer {
|
|
|
1111
895
|
|
|
1112
896
|
class ConsoleRenderer {
|
|
1113
897
|
applyPatches(patches) {
|
|
1114
|
-
|
|
898
|
+
log3.debug("Patches:", patches);
|
|
1115
899
|
}
|
|
1116
900
|
}
|
|
1117
901
|
|
|
1118
902
|
// src/router.ts
|
|
1119
903
|
init_state();
|
|
1120
904
|
init_logger();
|
|
1121
|
-
var
|
|
905
|
+
var log4 = frameworkLoggers.router;
|
|
1122
906
|
|
|
1123
907
|
class HypenRouter {
|
|
1124
908
|
state;
|
|
@@ -1156,7 +940,7 @@ class HypenRouter {
|
|
|
1156
940
|
this.updatePath(newPath, false);
|
|
1157
941
|
});
|
|
1158
942
|
this.isInitialized = true;
|
|
1159
|
-
|
|
943
|
+
log4.debug("Router initialized at:", initialPath);
|
|
1160
944
|
}
|
|
1161
945
|
getPathFromBrowser() {
|
|
1162
946
|
if (typeof window === "undefined")
|
|
@@ -1177,21 +961,21 @@ class HypenRouter {
|
|
|
1177
961
|
return query;
|
|
1178
962
|
}
|
|
1179
963
|
push(path) {
|
|
1180
|
-
|
|
964
|
+
log4.debug("push:", path);
|
|
1181
965
|
this.updatePath(path, true);
|
|
1182
966
|
}
|
|
1183
967
|
replace(path) {
|
|
1184
|
-
|
|
968
|
+
log4.debug("replace:", path);
|
|
1185
969
|
this.updatePath(path, true, true);
|
|
1186
970
|
}
|
|
1187
971
|
back() {
|
|
1188
|
-
|
|
972
|
+
log4.debug("back");
|
|
1189
973
|
if (typeof window !== "undefined") {
|
|
1190
974
|
window.history.back();
|
|
1191
975
|
}
|
|
1192
976
|
}
|
|
1193
977
|
forward() {
|
|
1194
|
-
|
|
978
|
+
log4.debug("forward");
|
|
1195
979
|
if (typeof window !== "undefined") {
|
|
1196
980
|
window.history.forward();
|
|
1197
981
|
}
|
|
@@ -1287,7 +1071,7 @@ class HypenRouter {
|
|
|
1287
1071
|
try {
|
|
1288
1072
|
callback(this.getState());
|
|
1289
1073
|
} catch (error) {
|
|
1290
|
-
|
|
1074
|
+
log4.error("Error in route subscriber:", error);
|
|
1291
1075
|
}
|
|
1292
1076
|
return () => {
|
|
1293
1077
|
this.subscribers.delete(callback);
|
|
@@ -1299,7 +1083,7 @@ class HypenRouter {
|
|
|
1299
1083
|
try {
|
|
1300
1084
|
callback(routeState);
|
|
1301
1085
|
} catch (error) {
|
|
1302
|
-
|
|
1086
|
+
log4.error("Error in route subscriber:", error);
|
|
1303
1087
|
}
|
|
1304
1088
|
});
|
|
1305
1089
|
}
|
|
@@ -1317,7 +1101,7 @@ class HypenRouter {
|
|
|
1317
1101
|
|
|
1318
1102
|
// src/events.ts
|
|
1319
1103
|
init_logger();
|
|
1320
|
-
var
|
|
1104
|
+
var log5 = frameworkLoggers.events;
|
|
1321
1105
|
|
|
1322
1106
|
class TypedEventEmitter {
|
|
1323
1107
|
eventBus = new Map;
|
|
@@ -1330,7 +1114,7 @@ class TypedEventEmitter {
|
|
|
1330
1114
|
try {
|
|
1331
1115
|
handler(payload);
|
|
1332
1116
|
} catch (error) {
|
|
1333
|
-
|
|
1117
|
+
log5.error(`Error in event handler for "${String(event)}":`, error);
|
|
1334
1118
|
}
|
|
1335
1119
|
});
|
|
1336
1120
|
}
|
|
@@ -1383,7 +1167,7 @@ function createEventEmitter() {
|
|
|
1383
1167
|
|
|
1384
1168
|
// src/context.ts
|
|
1385
1169
|
init_logger();
|
|
1386
|
-
var
|
|
1170
|
+
var log6 = frameworkLoggers.context;
|
|
1387
1171
|
|
|
1388
1172
|
class HypenGlobalContext {
|
|
1389
1173
|
modules = new Map;
|
|
@@ -1397,14 +1181,14 @@ class HypenGlobalContext {
|
|
|
1397
1181
|
}
|
|
1398
1182
|
registerModule(id, instance) {
|
|
1399
1183
|
if (this.modules.has(id)) {
|
|
1400
|
-
|
|
1184
|
+
log6.warn(`Module "${id}" is already registered. Overwriting.`);
|
|
1401
1185
|
}
|
|
1402
1186
|
this.modules.set(id, instance);
|
|
1403
|
-
|
|
1187
|
+
log6.debug(`Registered module: ${id}`);
|
|
1404
1188
|
}
|
|
1405
1189
|
unregisterModule(id) {
|
|
1406
1190
|
this.modules.delete(id);
|
|
1407
|
-
|
|
1191
|
+
log6.debug(`Unregistered module: ${id}`);
|
|
1408
1192
|
}
|
|
1409
1193
|
getModule(id) {
|
|
1410
1194
|
const module = this.modules.get(id);
|
|
@@ -1433,14 +1217,14 @@ class HypenGlobalContext {
|
|
|
1433
1217
|
emit(event, payload) {
|
|
1434
1218
|
const handlers = this.legacyEventBus.get(event);
|
|
1435
1219
|
if (!handlers || handlers.size === 0) {
|
|
1436
|
-
|
|
1220
|
+
log6.debug(`Event "${event}" emitted but no listeners`);
|
|
1437
1221
|
} else {
|
|
1438
|
-
|
|
1222
|
+
log6.debug(`Emitting event: ${event}`, payload);
|
|
1439
1223
|
handlers.forEach((handler) => {
|
|
1440
1224
|
try {
|
|
1441
1225
|
handler(payload);
|
|
1442
1226
|
} catch (error) {
|
|
1443
|
-
|
|
1227
|
+
log6.error(`Error in event handler for "${event}":`, error);
|
|
1444
1228
|
}
|
|
1445
1229
|
});
|
|
1446
1230
|
}
|
|
@@ -1454,7 +1238,7 @@ class HypenGlobalContext {
|
|
|
1454
1238
|
}
|
|
1455
1239
|
const handlers = this.legacyEventBus.get(event);
|
|
1456
1240
|
handlers.add(handler);
|
|
1457
|
-
|
|
1241
|
+
log6.debug(`Listening to event: ${event}`);
|
|
1458
1242
|
return () => {
|
|
1459
1243
|
handlers.delete(handler);
|
|
1460
1244
|
if (handlers.size === 0) {
|
|
@@ -1489,7 +1273,7 @@ class HypenGlobalContext {
|
|
|
1489
1273
|
|
|
1490
1274
|
// src/disposable.ts
|
|
1491
1275
|
init_logger();
|
|
1492
|
-
var
|
|
1276
|
+
var log7 = frameworkLoggers.lifecycle;
|
|
1493
1277
|
function isDisposable(obj) {
|
|
1494
1278
|
return obj !== null && typeof obj === "object" && "dispose" in obj && typeof obj.dispose === "function";
|
|
1495
1279
|
}
|
|
@@ -1521,7 +1305,7 @@ class DisposableStack {
|
|
|
1521
1305
|
try {
|
|
1522
1306
|
item.dispose();
|
|
1523
1307
|
} catch (error) {
|
|
1524
|
-
|
|
1308
|
+
log7.error("Error during dispose:", error);
|
|
1525
1309
|
}
|
|
1526
1310
|
}
|
|
1527
1311
|
}
|
|
@@ -1612,7 +1396,7 @@ function compositeDisposable(...disposables) {
|
|
|
1612
1396
|
try {
|
|
1613
1397
|
d.dispose();
|
|
1614
1398
|
} catch (error) {
|
|
1615
|
-
|
|
1399
|
+
log7.error("Error during dispose:", error);
|
|
1616
1400
|
}
|
|
1617
1401
|
}
|
|
1618
1402
|
}
|
|
@@ -1766,7 +1550,7 @@ var RetryPresets = {
|
|
|
1766
1550
|
|
|
1767
1551
|
// src/remote/client.ts
|
|
1768
1552
|
init_logger();
|
|
1769
|
-
var
|
|
1553
|
+
var log8 = frameworkLoggers.remote;
|
|
1770
1554
|
|
|
1771
1555
|
class RemoteEngine {
|
|
1772
1556
|
ws = null;
|
|
@@ -1874,7 +1658,7 @@ class RemoteEngine {
|
|
|
1874
1658
|
}
|
|
1875
1659
|
dispatchAction(action, payload) {
|
|
1876
1660
|
if (this.state !== "connected" || !this.ws) {
|
|
1877
|
-
|
|
1661
|
+
log8.warn("Cannot dispatch action: not connected");
|
|
1878
1662
|
return;
|
|
1879
1663
|
}
|
|
1880
1664
|
const message = {
|
|
@@ -1947,7 +1731,7 @@ class RemoteEngine {
|
|
|
1947
1731
|
break;
|
|
1948
1732
|
}
|
|
1949
1733
|
} catch (e) {
|
|
1950
|
-
|
|
1734
|
+
log8.error("Error handling remote message:", e);
|
|
1951
1735
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
1952
1736
|
this.errorCallbacks.forEach((cb) => cb(error));
|
|
1953
1737
|
}
|
|
@@ -1976,7 +1760,7 @@ class RemoteEngine {
|
|
|
1976
1760
|
}
|
|
1977
1761
|
handlePatch(message) {
|
|
1978
1762
|
if (message.revision <= this.currentRevision) {
|
|
1979
|
-
|
|
1763
|
+
log8.warn(`Out of order patch: expected > ${this.currentRevision}, got ${message.revision}`);
|
|
1980
1764
|
return;
|
|
1981
1765
|
}
|
|
1982
1766
|
this.currentRevision = message.revision;
|
|
@@ -2002,16 +1786,121 @@ class RemoteEngine {
|
|
|
2002
1786
|
maxDelayMs: 30000,
|
|
2003
1787
|
jitter: 0.1,
|
|
2004
1788
|
onRetry: (attempt, error) => {
|
|
2005
|
-
|
|
1789
|
+
log8.debug(`Reconnection attempt ${attempt}/${this.options.maxReconnectAttempts} failed: ${error.message}`);
|
|
2006
1790
|
}
|
|
2007
1791
|
}).catch((error) => {
|
|
2008
|
-
|
|
1792
|
+
log8.error("Max reconnection attempts reached:", error.message);
|
|
2009
1793
|
this.errorCallbacks.forEach((cb) => cb(new ConnectionError(this.url, error, this.options.maxReconnectAttempts)));
|
|
2010
1794
|
});
|
|
2011
1795
|
}, this.options.reconnectInterval);
|
|
2012
1796
|
}
|
|
2013
1797
|
}
|
|
2014
1798
|
|
|
1799
|
+
// src/engine.ts
|
|
1800
|
+
init_logger();
|
|
1801
|
+
import { WasmEngine } from "../wasm-node/hypen_engine.js";
|
|
1802
|
+
var log9 = frameworkLoggers.engine;
|
|
1803
|
+
function unwrapForWasm(value) {
|
|
1804
|
+
if (value === null || typeof value !== "object") {
|
|
1805
|
+
return value;
|
|
1806
|
+
}
|
|
1807
|
+
if (typeof value.__getSnapshot === "function") {
|
|
1808
|
+
return value.__getSnapshot();
|
|
1809
|
+
}
|
|
1810
|
+
try {
|
|
1811
|
+
return structuredClone(value);
|
|
1812
|
+
} catch {
|
|
1813
|
+
return JSON.parse(JSON.stringify(value));
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
class Engine {
|
|
1818
|
+
wasmEngine = null;
|
|
1819
|
+
initialized = false;
|
|
1820
|
+
async init() {
|
|
1821
|
+
if (this.initialized)
|
|
1822
|
+
return;
|
|
1823
|
+
this.wasmEngine = new WasmEngine;
|
|
1824
|
+
this.initialized = true;
|
|
1825
|
+
}
|
|
1826
|
+
ensureInitialized() {
|
|
1827
|
+
if (!this.wasmEngine) {
|
|
1828
|
+
throw new Error("Engine not initialized. Call init() first.");
|
|
1829
|
+
}
|
|
1830
|
+
return this.wasmEngine;
|
|
1831
|
+
}
|
|
1832
|
+
setRenderCallback(callback) {
|
|
1833
|
+
const engine = this.ensureInitialized();
|
|
1834
|
+
engine.setRenderCallback((patches) => {
|
|
1835
|
+
callback(patches);
|
|
1836
|
+
});
|
|
1837
|
+
}
|
|
1838
|
+
setComponentResolver(resolver) {
|
|
1839
|
+
const engine = this.ensureInitialized();
|
|
1840
|
+
engine.setComponentResolver((componentName, contextPath) => {
|
|
1841
|
+
const result = resolver(componentName, contextPath);
|
|
1842
|
+
return result;
|
|
1843
|
+
});
|
|
1844
|
+
}
|
|
1845
|
+
renderSource(source) {
|
|
1846
|
+
const engine = this.ensureInitialized();
|
|
1847
|
+
engine.renderSource(source);
|
|
1848
|
+
}
|
|
1849
|
+
renderLazyComponent(source) {
|
|
1850
|
+
const engine = this.ensureInitialized();
|
|
1851
|
+
engine.renderLazyComponent(source);
|
|
1852
|
+
}
|
|
1853
|
+
renderInto(source, parentNodeId, state) {
|
|
1854
|
+
const engine = this.ensureInitialized();
|
|
1855
|
+
engine.renderInto(source, parentNodeId, unwrapForWasm(state));
|
|
1856
|
+
}
|
|
1857
|
+
notifyStateChange(paths, values) {
|
|
1858
|
+
const engine = this.ensureInitialized();
|
|
1859
|
+
if (paths.length === 0) {
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
engine.updateStateSparse(paths, unwrapForWasm(values));
|
|
1863
|
+
log9.debug("State changed (sparse):", paths);
|
|
1864
|
+
}
|
|
1865
|
+
notifyStateChangeFull(paths, currentState) {
|
|
1866
|
+
const engine = this.ensureInitialized();
|
|
1867
|
+
engine.updateState(unwrapForWasm(currentState));
|
|
1868
|
+
if (paths.length > 0) {
|
|
1869
|
+
log9.debug("State changed (full):", paths);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
updateState(statePatch) {
|
|
1873
|
+
const engine = this.ensureInitialized();
|
|
1874
|
+
engine.updateState(unwrapForWasm(statePatch));
|
|
1875
|
+
}
|
|
1876
|
+
dispatchAction(name, payload) {
|
|
1877
|
+
const engine = this.ensureInitialized();
|
|
1878
|
+
engine.dispatchAction(name, payload ?? null);
|
|
1879
|
+
}
|
|
1880
|
+
onAction(actionName, handler) {
|
|
1881
|
+
const engine = this.ensureInitialized();
|
|
1882
|
+
engine.onAction(actionName, (action) => {
|
|
1883
|
+
Promise.resolve(handler(action)).catch((err) => log9.error("Action handler error:", err));
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
setModule(name, actions, stateKeys, initialState) {
|
|
1887
|
+
const engine = this.ensureInitialized();
|
|
1888
|
+
engine.setModule(name, actions, stateKeys, initialState);
|
|
1889
|
+
}
|
|
1890
|
+
getRevision() {
|
|
1891
|
+
const engine = this.ensureInitialized();
|
|
1892
|
+
return Number(engine.getRevision());
|
|
1893
|
+
}
|
|
1894
|
+
clearTree() {
|
|
1895
|
+
const engine = this.ensureInitialized();
|
|
1896
|
+
engine.clearTree();
|
|
1897
|
+
}
|
|
1898
|
+
debugParseComponent(source) {
|
|
1899
|
+
const engine = this.ensureInitialized();
|
|
1900
|
+
return engine.debugParseComponent(source);
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
|
|
2015
1904
|
// src/remote/server.ts
|
|
2016
1905
|
init_app();
|
|
2017
1906
|
|
|
@@ -2141,7 +2030,7 @@ class SessionManager {
|
|
|
2141
2030
|
|
|
2142
2031
|
// src/remote/server.ts
|
|
2143
2032
|
init_logger();
|
|
2144
|
-
var
|
|
2033
|
+
var log10 = frameworkLoggers.remote;
|
|
2145
2034
|
|
|
2146
2035
|
class RemoteServer {
|
|
2147
2036
|
_module = null;
|
|
@@ -2219,7 +2108,7 @@ class RemoteServer {
|
|
|
2219
2108
|
return new Response("Hypen Remote Server", { status: 200 });
|
|
2220
2109
|
}
|
|
2221
2110
|
});
|
|
2222
|
-
|
|
2111
|
+
log10.info(`Hypen app streaming on ws://${hostname}:${finalPort}`);
|
|
2223
2112
|
return this;
|
|
2224
2113
|
}
|
|
2225
2114
|
stop() {
|
|
@@ -2262,7 +2151,7 @@ class RemoteServer {
|
|
|
2262
2151
|
}
|
|
2263
2152
|
}, 1000);
|
|
2264
2153
|
} catch (error) {
|
|
2265
|
-
|
|
2154
|
+
log10.error("Error handling WebSocket open:", error);
|
|
2266
2155
|
ws.close(1011, "Internal server error");
|
|
2267
2156
|
}
|
|
2268
2157
|
}
|
|
@@ -2433,7 +2322,7 @@ class RemoteServer {
|
|
|
2433
2322
|
break;
|
|
2434
2323
|
}
|
|
2435
2324
|
} catch (error) {
|
|
2436
|
-
|
|
2325
|
+
log10.error("Error handling WebSocket message:", error);
|
|
2437
2326
|
}
|
|
2438
2327
|
}
|
|
2439
2328
|
async handleClose(ws) {
|
|
@@ -2516,7 +2405,7 @@ function serve(options) {
|
|
|
2516
2405
|
init_logger();
|
|
2517
2406
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
2518
2407
|
import { join } from "path";
|
|
2519
|
-
var
|
|
2408
|
+
var log11 = frameworkLoggers.loader;
|
|
2520
2409
|
|
|
2521
2410
|
class ComponentLoader {
|
|
2522
2411
|
components = new Map;
|
|
@@ -2551,16 +2440,16 @@ class ComponentLoader {
|
|
|
2551
2440
|
const templatePath = join(dirPath, "component.hypen");
|
|
2552
2441
|
const template = readFileSync(templatePath, "utf-8");
|
|
2553
2442
|
this.register(name, module, template, dirPath);
|
|
2554
|
-
|
|
2443
|
+
log11.debug(`Loaded component: ${name} from ${dirPath}`);
|
|
2555
2444
|
} catch (error) {
|
|
2556
|
-
|
|
2445
|
+
log11.error(`Failed to load component ${name} from ${dirPath}:`, error);
|
|
2557
2446
|
throw error;
|
|
2558
2447
|
}
|
|
2559
2448
|
}
|
|
2560
2449
|
async loadFromComponentsDir(baseDir) {
|
|
2561
2450
|
try {
|
|
2562
2451
|
if (!existsSync(baseDir)) {
|
|
2563
|
-
|
|
2452
|
+
log11.warn(`Components directory not found: ${baseDir}`);
|
|
2564
2453
|
return;
|
|
2565
2454
|
}
|
|
2566
2455
|
const entries = readdirSync(baseDir, { withFileTypes: true });
|
|
@@ -2573,9 +2462,9 @@ class ComponentLoader {
|
|
|
2573
2462
|
await this.loadFromDirectory(entry.name, componentDir);
|
|
2574
2463
|
}
|
|
2575
2464
|
}
|
|
2576
|
-
|
|
2465
|
+
log11.debug(`Loaded ${this.components.size} components from ${baseDir}`);
|
|
2577
2466
|
} catch (error) {
|
|
2578
|
-
|
|
2467
|
+
log11.error(`Failed to load components from ${baseDir}:`, error);
|
|
2579
2468
|
throw error;
|
|
2580
2469
|
}
|
|
2581
2470
|
}
|
|
@@ -2586,14 +2475,32 @@ var componentLoader = new ComponentLoader;
|
|
|
2586
2475
|
class ComponentResolver {
|
|
2587
2476
|
cache = new Map;
|
|
2588
2477
|
options;
|
|
2478
|
+
moduleRegistry;
|
|
2589
2479
|
constructor(options = {}) {
|
|
2590
2480
|
this.options = {
|
|
2591
2481
|
baseDir: options.baseDir || process.cwd(),
|
|
2592
2482
|
cache: options.cache ?? true,
|
|
2593
|
-
customFetch: options.customFetch || this.defaultFetch.bind(this)
|
|
2483
|
+
customFetch: options.customFetch || this.defaultFetch.bind(this),
|
|
2484
|
+
moduleRegistry: options.moduleRegistry
|
|
2594
2485
|
};
|
|
2486
|
+
this.moduleRegistry = options.moduleRegistry;
|
|
2595
2487
|
}
|
|
2596
2488
|
async resolve(importStmt) {
|
|
2489
|
+
if (this.moduleRegistry) {
|
|
2490
|
+
const names = importStmt.clause.type === "named" ? importStmt.clause.names : [importStmt.clause.name];
|
|
2491
|
+
const allFound = names.every((name) => this.moduleRegistry.has(name));
|
|
2492
|
+
if (allFound) {
|
|
2493
|
+
const result = {};
|
|
2494
|
+
for (const name of names) {
|
|
2495
|
+
const def = this.moduleRegistry.get(name);
|
|
2496
|
+
result[name] = {
|
|
2497
|
+
module: def,
|
|
2498
|
+
template: def?.template || ""
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
return result;
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2597
2504
|
const sourcePath = this.getSourcePath(importStmt.source);
|
|
2598
2505
|
if (this.options.cache && this.cache.has(sourcePath)) {
|
|
2599
2506
|
const cached = this.cache.get(sourcePath);
|
|
@@ -2611,8 +2518,17 @@ class ComponentResolver {
|
|
|
2611
2518
|
return this.extractComponents(importStmt.clause, component);
|
|
2612
2519
|
}
|
|
2613
2520
|
async resolveLocal(path) {
|
|
2614
|
-
|
|
2615
|
-
|
|
2521
|
+
const { resolve, join: join2 } = await import("path");
|
|
2522
|
+
const { readFile } = await import("fs/promises");
|
|
2523
|
+
const basePath = resolve(this.options.baseDir, path);
|
|
2524
|
+
const hypenPath = basePath.endsWith(".hypen") ? basePath : `${basePath}.hypen`;
|
|
2525
|
+
const template = await readFile(hypenPath, "utf-8");
|
|
2526
|
+
const modulePath = hypenPath.replace(/\.hypen$/, ".ts");
|
|
2527
|
+
let module = {};
|
|
2528
|
+
try {
|
|
2529
|
+
module = await import(modulePath);
|
|
2530
|
+
} catch {}
|
|
2531
|
+
return { module, template };
|
|
2616
2532
|
}
|
|
2617
2533
|
async resolveUrl(url) {
|
|
2618
2534
|
try {
|
|
@@ -2680,29 +2596,26 @@ class ComponentResolver {
|
|
|
2680
2596
|
init_logger();
|
|
2681
2597
|
import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, watch } from "fs";
|
|
2682
2598
|
import { join as join2, basename, resolve } from "path";
|
|
2683
|
-
function removeImports(text) {
|
|
2684
|
-
return text.replace(/import\s+(?:\{[^}]+\}|\w+)\s+from\s+["'][^"']+["']\s*/g, "");
|
|
2685
|
-
}
|
|
2686
2599
|
async function discoverComponents(baseDir, options = {}) {
|
|
2687
2600
|
const {
|
|
2688
2601
|
patterns = ["single-file", "folder", "sibling", "index"],
|
|
2689
2602
|
recursive = false,
|
|
2690
2603
|
debug = false
|
|
2691
2604
|
} = options;
|
|
2692
|
-
const
|
|
2605
|
+
const log12 = debug ? (...args) => frameworkLoggers.discovery.debug(...args) : () => {};
|
|
2693
2606
|
const resolvedDir = resolve(baseDir);
|
|
2694
2607
|
const components = [];
|
|
2695
2608
|
const seen = new Set;
|
|
2696
|
-
|
|
2697
|
-
|
|
2609
|
+
log12("Scanning directory:", resolvedDir);
|
|
2610
|
+
log12("Patterns:", patterns);
|
|
2698
2611
|
const addTwoFileComponent = (name, hypenPath, modulePath) => {
|
|
2699
2612
|
if (seen.has(name)) {
|
|
2700
|
-
|
|
2613
|
+
log12(`Skipping duplicate: ${name}`);
|
|
2701
2614
|
return;
|
|
2702
2615
|
}
|
|
2703
2616
|
seen.add(name);
|
|
2704
2617
|
const templateRaw = readFileSync2(hypenPath, "utf-8");
|
|
2705
|
-
const template =
|
|
2618
|
+
const template = templateRaw.trim();
|
|
2706
2619
|
components.push({
|
|
2707
2620
|
name,
|
|
2708
2621
|
hypenPath,
|
|
@@ -2711,11 +2624,11 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2711
2624
|
hasModule: modulePath !== null,
|
|
2712
2625
|
isSingleFile: false
|
|
2713
2626
|
});
|
|
2714
|
-
|
|
2627
|
+
log12(`Found: ${name} (two-file, ${modulePath ? "with module" : "stateless"})`);
|
|
2715
2628
|
};
|
|
2716
2629
|
const addSingleFileComponent = (name, modulePath, template) => {
|
|
2717
2630
|
if (seen.has(name)) {
|
|
2718
|
-
|
|
2631
|
+
log12(`Skipping duplicate: ${name}`);
|
|
2719
2632
|
return;
|
|
2720
2633
|
}
|
|
2721
2634
|
seen.add(name);
|
|
@@ -2727,7 +2640,7 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2727
2640
|
hasModule: true,
|
|
2728
2641
|
isSingleFile: true
|
|
2729
2642
|
});
|
|
2730
|
-
|
|
2643
|
+
log12(`Found: ${name} (single-file with inline template)`);
|
|
2731
2644
|
};
|
|
2732
2645
|
const scanForFolderComponents = (dir) => {
|
|
2733
2646
|
if (!existsSync2(dir))
|
|
@@ -2811,7 +2724,7 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2811
2724
|
addSingleFileComponent(baseName, modulePath, module.template);
|
|
2812
2725
|
}
|
|
2813
2726
|
} catch (e) {
|
|
2814
|
-
|
|
2727
|
+
log12(`Failed to import potential single-file component: ${entry.name}`, e);
|
|
2815
2728
|
}
|
|
2816
2729
|
}
|
|
2817
2730
|
}
|
|
@@ -2825,7 +2738,7 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2825
2738
|
if (patterns.includes("single-file")) {
|
|
2826
2739
|
await scanForSingleFileComponents(resolvedDir);
|
|
2827
2740
|
}
|
|
2828
|
-
|
|
2741
|
+
log12(`Discovered ${components.length} components`);
|
|
2829
2742
|
return components;
|
|
2830
2743
|
}
|
|
2831
2744
|
async function loadDiscoveredComponents(components) {
|
|
@@ -2861,7 +2774,7 @@ function watchComponents(baseDir, options = {}) {
|
|
|
2861
2774
|
debug = false,
|
|
2862
2775
|
...discoveryOptions
|
|
2863
2776
|
} = options;
|
|
2864
|
-
const
|
|
2777
|
+
const log12 = debug ? (...args) => frameworkLoggers.discovery.debug("[watch]", ...args) : () => {};
|
|
2865
2778
|
let currentComponents = new Map;
|
|
2866
2779
|
let debounceTimer = null;
|
|
2867
2780
|
const initialScan = async () => {
|
|
@@ -2874,22 +2787,22 @@ function watchComponents(baseDir, options = {}) {
|
|
|
2874
2787
|
clearTimeout(debounceTimer);
|
|
2875
2788
|
}
|
|
2876
2789
|
debounceTimer = setTimeout(async () => {
|
|
2877
|
-
|
|
2790
|
+
log12("Rescanning...");
|
|
2878
2791
|
const newComponents = await discoverComponents(resolvedDir, discoveryOptions);
|
|
2879
2792
|
const newMap = new Map(newComponents.map((c) => [c.name, c]));
|
|
2880
2793
|
for (const [name, component] of newMap) {
|
|
2881
2794
|
const existing = currentComponents.get(name);
|
|
2882
2795
|
if (!existing) {
|
|
2883
|
-
|
|
2796
|
+
log12("Added:", name);
|
|
2884
2797
|
onAdd?.(component);
|
|
2885
2798
|
} else if (existing.template !== component.template || existing.modulePath !== component.modulePath) {
|
|
2886
|
-
|
|
2799
|
+
log12("Updated:", name);
|
|
2887
2800
|
onUpdate?.(component);
|
|
2888
2801
|
}
|
|
2889
2802
|
}
|
|
2890
2803
|
for (const name of currentComponents.keys()) {
|
|
2891
2804
|
if (!newMap.has(name)) {
|
|
2892
|
-
|
|
2805
|
+
log12("Removed:", name);
|
|
2893
2806
|
onRemove?.(name);
|
|
2894
2807
|
}
|
|
2895
2808
|
}
|
|
@@ -2901,7 +2814,7 @@ function watchComponents(baseDir, options = {}) {
|
|
|
2901
2814
|
if (!filename)
|
|
2902
2815
|
return;
|
|
2903
2816
|
if (filename.endsWith(".hypen") || filename.endsWith(".ts")) {
|
|
2904
|
-
|
|
2817
|
+
log12("File changed:", filename);
|
|
2905
2818
|
rescan();
|
|
2906
2819
|
}
|
|
2907
2820
|
});
|
|
@@ -3024,28 +2937,28 @@ function parseImports(text) {
|
|
|
3024
2937
|
}
|
|
3025
2938
|
return imports;
|
|
3026
2939
|
}
|
|
3027
|
-
function
|
|
2940
|
+
function removeImports(text) {
|
|
3028
2941
|
return text.replace(/import\s+(?:\{[^}]+\}|\w+)\s+from\s+["'][^"']+["']\s*/g, "");
|
|
3029
2942
|
}
|
|
3030
2943
|
function hypenPlugin(options = {}) {
|
|
3031
2944
|
const { debug = false, patterns = ["sibling", "component", "index"] } = options;
|
|
3032
|
-
const
|
|
2945
|
+
const log12 = debug ? (...args) => frameworkLoggers.plugin.debug(...args) : () => {};
|
|
3033
2946
|
return {
|
|
3034
2947
|
name: "hypen-loader",
|
|
3035
2948
|
async setup(build) {
|
|
3036
2949
|
build.onLoad({ filter: /\.hypen$/ }, async (args) => {
|
|
3037
2950
|
const hypenPath = resolve2(args.path);
|
|
3038
|
-
|
|
2951
|
+
log12("Loading:", hypenPath);
|
|
3039
2952
|
const templateRaw = readFileSync3(hypenPath, "utf-8");
|
|
3040
2953
|
const imports = parseImports(templateRaw);
|
|
3041
|
-
const template =
|
|
2954
|
+
const template = removeImports(templateRaw).trim();
|
|
3042
2955
|
if (imports.length > 0) {
|
|
3043
|
-
|
|
2956
|
+
log12("Found imports:", imports);
|
|
3044
2957
|
}
|
|
3045
2958
|
const componentName = getComponentName(hypenPath);
|
|
3046
|
-
|
|
2959
|
+
log12("Component name:", componentName);
|
|
3047
2960
|
const modulePath = findModulePath(hypenPath, patterns);
|
|
3048
|
-
|
|
2961
|
+
log12("Module path:", modulePath);
|
|
3049
2962
|
let contents;
|
|
3050
2963
|
if (modulePath) {
|
|
3051
2964
|
const relativeModulePath = modulePath.replace(/\.ts$/, ".js");
|
|
@@ -3057,7 +2970,7 @@ export const name = ${JSON.stringify(componentName)};
|
|
|
3057
2970
|
export default { module: _module, template: ${JSON.stringify(template)}, name: ${JSON.stringify(componentName)} };
|
|
3058
2971
|
`;
|
|
3059
2972
|
} else {
|
|
3060
|
-
|
|
2973
|
+
log12("No module found, creating stateless component");
|
|
3061
2974
|
contents = `
|
|
3062
2975
|
import { app } from "@hypen-space/core";
|
|
3063
2976
|
const _module = app.defineState({}).build();
|
|
@@ -3084,19 +2997,19 @@ var plugin_default = hypenPlugin;
|
|
|
3084
2997
|
// src/components/builtin.ts
|
|
3085
2998
|
init_app();
|
|
3086
2999
|
init_logger();
|
|
3087
|
-
var
|
|
3000
|
+
var log12 = frameworkLoggers.router;
|
|
3088
3001
|
var Router = app.defineState({
|
|
3089
3002
|
currentPath: "/",
|
|
3090
3003
|
matchedRoute: null,
|
|
3091
3004
|
routeParams: {}
|
|
3092
3005
|
}, { name: "__Router" }).onCreated((state, context) => {
|
|
3093
3006
|
if (!context) {
|
|
3094
|
-
|
|
3007
|
+
log12.error("Requires global context");
|
|
3095
3008
|
return;
|
|
3096
3009
|
}
|
|
3097
3010
|
const router = context.__router;
|
|
3098
3011
|
if (!router) {
|
|
3099
|
-
|
|
3012
|
+
log12.error("Router not found in context");
|
|
3100
3013
|
return;
|
|
3101
3014
|
}
|
|
3102
3015
|
const hypenEngine = context.__hypenEngine;
|
|
@@ -3118,13 +3031,13 @@ var Router = app.defineState({
|
|
|
3118
3031
|
try {
|
|
3119
3032
|
await hypenEngine.renderLazyRoute(routePath, componentName, htmlEl);
|
|
3120
3033
|
} catch (err) {
|
|
3121
|
-
|
|
3034
|
+
log12.error(`Failed to render route ${routePath}:`, err);
|
|
3122
3035
|
}
|
|
3123
3036
|
}
|
|
3124
3037
|
}
|
|
3125
3038
|
}
|
|
3126
3039
|
if (!matchFound) {
|
|
3127
|
-
|
|
3040
|
+
log12.warn(`No route matched path: ${currentPath}. Available routes:`, Array.from(routeElements).map((el) => el.dataset.routePath));
|
|
3128
3041
|
}
|
|
3129
3042
|
};
|
|
3130
3043
|
setTimeout(() => {
|
|
@@ -3143,7 +3056,7 @@ var Link = app.defineState({
|
|
|
3143
3056
|
}, { name: "__Link" }).onAction("navigate", ({ state, context }) => {
|
|
3144
3057
|
const router = context?.__router;
|
|
3145
3058
|
if (!router) {
|
|
3146
|
-
|
|
3059
|
+
log12.error("Link requires router context");
|
|
3147
3060
|
return;
|
|
3148
3061
|
}
|
|
3149
3062
|
const targetPath = state.to;
|
|
@@ -3293,16 +3206,14 @@ export {
|
|
|
3293
3206
|
HypenAppBuilder,
|
|
3294
3207
|
HypenApp,
|
|
3295
3208
|
Err,
|
|
3296
|
-
Engine,
|
|
3297
3209
|
DisposableStack,
|
|
3298
3210
|
DisposableMixin,
|
|
3299
3211
|
ConsoleRenderer,
|
|
3300
3212
|
ConnectionError,
|
|
3301
3213
|
ComponentResolver,
|
|
3302
3214
|
ComponentLoader,
|
|
3303
|
-
Engine2 as BrowserEngine,
|
|
3304
3215
|
BaseRenderer,
|
|
3305
3216
|
ActionError
|
|
3306
3217
|
};
|
|
3307
3218
|
|
|
3308
|
-
//# debugId=
|
|
3219
|
+
//# debugId=C03FB9EC8278859464756E2164756E21
|