@hypen-space/core 0.3.12 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +7 -3
- package/dist/app.js.map +3 -3
- package/dist/components/builtin.js +7 -3
- package/dist/components/builtin.js.map +3 -3
- package/dist/discovery.js +8 -7
- package/dist/discovery.js.map +4 -4
- package/dist/engine.browser.js.map +2 -2
- package/dist/engine.js +3 -7
- package/dist/engine.js.map +3 -3
- package/dist/index.browser.js +242 -371
- package/dist/index.browser.js.map +8 -9
- package/dist/index.js +546 -656
- package/dist/index.js.map +12 -13
- package/dist/remote/client.js.map +1 -1
- package/dist/remote/index.js +336 -336
- package/dist/remote/index.js.map +8 -8
- package/dist/remote/server.js +219 -219
- package/dist/remote/server.js.map +7 -7
- package/dist/renderer.js.map +1 -1
- package/dist/resolver.js +31 -4
- package/dist/resolver.js.map +3 -3
- package/package.json +13 -1
- package/src/app.ts +14 -2
- package/src/discovery.ts +15 -12
- package/src/engine.browser.ts +4 -32
- package/src/engine.ts +8 -44
- package/src/index.browser.ts +6 -4
- package/src/index.ts +22 -30
- 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 +6 -2
- 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
|
@@ -27,205 +27,6 @@ var __export = (target, all) => {
|
|
|
27
27
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
28
28
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
29
29
|
|
|
30
|
-
// src/logger.ts
|
|
31
|
-
function isProduction() {
|
|
32
|
-
if (typeof process !== "undefined" && process.env) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
function setLogLevel(level) {
|
|
38
|
-
config.level = level;
|
|
39
|
-
}
|
|
40
|
-
function getLogLevel() {
|
|
41
|
-
return config.level;
|
|
42
|
-
}
|
|
43
|
-
function configureLogger(options) {
|
|
44
|
-
config = { ...config, ...options };
|
|
45
|
-
}
|
|
46
|
-
function enableLogging() {
|
|
47
|
-
config.level = "debug";
|
|
48
|
-
}
|
|
49
|
-
function disableLogging() {
|
|
50
|
-
config.level = "none";
|
|
51
|
-
}
|
|
52
|
-
function setDebugMode(enabled) {
|
|
53
|
-
config.level = enabled ? "debug" : "error";
|
|
54
|
-
}
|
|
55
|
-
function isDebugMode() {
|
|
56
|
-
return config.level === "debug";
|
|
57
|
-
}
|
|
58
|
-
function shouldLog(level) {
|
|
59
|
-
return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[config.level];
|
|
60
|
-
}
|
|
61
|
-
function formatTag(tag, level) {
|
|
62
|
-
const timestamp = config.timestamps ? `${new Date().toISOString()} ` : "";
|
|
63
|
-
if (config.colors && level !== "none") {
|
|
64
|
-
const color = LOG_LEVEL_COLORS[level];
|
|
65
|
-
return `${timestamp}${color}[${tag}]${RESET_COLOR}`;
|
|
66
|
-
}
|
|
67
|
-
return `${timestamp}[${tag}]`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
class Logger {
|
|
71
|
-
tag;
|
|
72
|
-
constructor(tag) {
|
|
73
|
-
this.tag = tag;
|
|
74
|
-
}
|
|
75
|
-
debug(...args) {
|
|
76
|
-
if (!shouldLog("debug"))
|
|
77
|
-
return;
|
|
78
|
-
if (config.handler) {
|
|
79
|
-
config.handler.debug(this.tag, ...args);
|
|
80
|
-
} else {
|
|
81
|
-
console.log(formatTag(this.tag, "debug"), ...args);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
info(...args) {
|
|
85
|
-
if (!shouldLog("info"))
|
|
86
|
-
return;
|
|
87
|
-
if (config.handler) {
|
|
88
|
-
config.handler.info(this.tag, ...args);
|
|
89
|
-
} else {
|
|
90
|
-
console.info(formatTag(this.tag, "info"), ...args);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
warn(...args) {
|
|
94
|
-
if (!shouldLog("warn"))
|
|
95
|
-
return;
|
|
96
|
-
if (config.handler) {
|
|
97
|
-
config.handler.warn(this.tag, ...args);
|
|
98
|
-
} else {
|
|
99
|
-
console.warn(formatTag(this.tag, "warn"), ...args);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
error(...args) {
|
|
103
|
-
if (!shouldLog("error"))
|
|
104
|
-
return;
|
|
105
|
-
if (config.handler) {
|
|
106
|
-
config.handler.error(this.tag, ...args);
|
|
107
|
-
} else {
|
|
108
|
-
console.error(formatTag(this.tag, "error"), ...args);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
time(label, fn) {
|
|
112
|
-
if (!shouldLog("debug")) {
|
|
113
|
-
return fn();
|
|
114
|
-
}
|
|
115
|
-
const start = performance.now();
|
|
116
|
-
try {
|
|
117
|
-
return fn();
|
|
118
|
-
} finally {
|
|
119
|
-
const duration = performance.now() - start;
|
|
120
|
-
this.debug(`${label}: ${duration.toFixed(2)}ms`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
async timeAsync(label, fn) {
|
|
124
|
-
if (!shouldLog("debug")) {
|
|
125
|
-
return fn();
|
|
126
|
-
}
|
|
127
|
-
const start = performance.now();
|
|
128
|
-
try {
|
|
129
|
-
return await fn();
|
|
130
|
-
} finally {
|
|
131
|
-
const duration = performance.now() - start;
|
|
132
|
-
this.debug(`${label}: ${duration.toFixed(2)}ms`);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
child(subTag) {
|
|
136
|
-
return new Logger(`${this.tag}:${subTag}`);
|
|
137
|
-
}
|
|
138
|
-
debugIf(condition, ...args) {
|
|
139
|
-
if (condition)
|
|
140
|
-
this.debug(...args);
|
|
141
|
-
}
|
|
142
|
-
warnIf(condition, ...args) {
|
|
143
|
-
if (condition)
|
|
144
|
-
this.warn(...args);
|
|
145
|
-
}
|
|
146
|
-
errorIf(condition, ...args) {
|
|
147
|
-
if (condition)
|
|
148
|
-
this.error(...args);
|
|
149
|
-
}
|
|
150
|
-
loggedOnce = new Set;
|
|
151
|
-
warnOnce(key, ...args) {
|
|
152
|
-
if (this.loggedOnce.has(key))
|
|
153
|
-
return;
|
|
154
|
-
this.loggedOnce.add(key);
|
|
155
|
-
this.warn(...args);
|
|
156
|
-
}
|
|
157
|
-
debugOnce(key, ...args) {
|
|
158
|
-
if (this.loggedOnce.has(key))
|
|
159
|
-
return;
|
|
160
|
-
this.loggedOnce.add(key);
|
|
161
|
-
this.debug(...args);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
function createLogger(tag) {
|
|
165
|
-
return new Logger(tag);
|
|
166
|
-
}
|
|
167
|
-
var LOG_LEVEL_ORDER, LOG_LEVEL_COLORS, RESET_COLOR = "\x1B[0m", config, logger, log, frameworkLoggers;
|
|
168
|
-
var init_logger = __esm(() => {
|
|
169
|
-
LOG_LEVEL_ORDER = {
|
|
170
|
-
debug: 0,
|
|
171
|
-
info: 1,
|
|
172
|
-
warn: 2,
|
|
173
|
-
error: 3,
|
|
174
|
-
none: 4
|
|
175
|
-
};
|
|
176
|
-
LOG_LEVEL_COLORS = {
|
|
177
|
-
debug: "\x1B[36m",
|
|
178
|
-
info: "\x1B[32m",
|
|
179
|
-
warn: "\x1B[33m",
|
|
180
|
-
error: "\x1B[31m"
|
|
181
|
-
};
|
|
182
|
-
config = {
|
|
183
|
-
level: isProduction() ? "error" : "debug",
|
|
184
|
-
colors: true,
|
|
185
|
-
timestamps: false
|
|
186
|
-
};
|
|
187
|
-
logger = createLogger("Hypen");
|
|
188
|
-
log = {
|
|
189
|
-
debug: (tag, ...args) => {
|
|
190
|
-
if (!shouldLog("debug"))
|
|
191
|
-
return;
|
|
192
|
-
console.log(formatTag(tag, "debug"), ...args);
|
|
193
|
-
},
|
|
194
|
-
info: (tag, ...args) => {
|
|
195
|
-
if (!shouldLog("info"))
|
|
196
|
-
return;
|
|
197
|
-
console.info(formatTag(tag, "info"), ...args);
|
|
198
|
-
},
|
|
199
|
-
warn: (tag, ...args) => {
|
|
200
|
-
if (!shouldLog("warn"))
|
|
201
|
-
return;
|
|
202
|
-
console.warn(formatTag(tag, "warn"), ...args);
|
|
203
|
-
},
|
|
204
|
-
error: (tag, ...args) => {
|
|
205
|
-
if (!shouldLog("error"))
|
|
206
|
-
return;
|
|
207
|
-
console.error(formatTag(tag, "error"), ...args);
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
frameworkLoggers = {
|
|
211
|
-
hypen: createLogger("Hypen"),
|
|
212
|
-
engine: createLogger("Engine"),
|
|
213
|
-
router: createLogger("Router"),
|
|
214
|
-
state: createLogger("State"),
|
|
215
|
-
events: createLogger("Events"),
|
|
216
|
-
remote: createLogger("Remote"),
|
|
217
|
-
renderer: createLogger("Renderer"),
|
|
218
|
-
module: createLogger("Module"),
|
|
219
|
-
lifecycle: createLogger("Lifecycle"),
|
|
220
|
-
loader: createLogger("Loader"),
|
|
221
|
-
context: createLogger("Context"),
|
|
222
|
-
discovery: createLogger("Discovery"),
|
|
223
|
-
plugin: createLogger("Plugin"),
|
|
224
|
-
canvas: createLogger("Canvas"),
|
|
225
|
-
debug: createLogger("Debug")
|
|
226
|
-
};
|
|
227
|
-
});
|
|
228
|
-
|
|
229
30
|
// src/state.ts
|
|
230
31
|
function deepClone(obj) {
|
|
231
32
|
if (obj === null || typeof obj !== "object") {
|
|
@@ -612,60 +413,259 @@ var init_result = __esm(() => {
|
|
|
612
413
|
};
|
|
613
414
|
});
|
|
614
415
|
|
|
615
|
-
// src/
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
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;
|
|
416
|
+
// src/logger.ts
|
|
417
|
+
function isProduction() {
|
|
418
|
+
if (typeof process !== "undefined" && process.env) {
|
|
419
|
+
return false;
|
|
666
420
|
}
|
|
667
|
-
|
|
668
|
-
|
|
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;
|
|
666
|
+
}
|
|
667
|
+
ui(template) {
|
|
668
|
+
this.template = template;
|
|
669
669
|
return this.build();
|
|
670
670
|
}
|
|
671
671
|
build() {
|
|
@@ -710,17 +710,21 @@ class HypenModuleInstance {
|
|
|
710
710
|
this.definition = definition;
|
|
711
711
|
this.routerContext = routerContext;
|
|
712
712
|
this.globalContext = globalContext;
|
|
713
|
+
const statePrefix = (definition.name || "").toLowerCase();
|
|
713
714
|
this.state = createObservableState(definition.initialState, {
|
|
714
715
|
onChange: (change) => {
|
|
715
716
|
this.engine.notifyStateChange(change.paths, change.newValues);
|
|
716
717
|
this.stateChangeCallbacks.forEach((cb) => cb());
|
|
717
|
-
}
|
|
718
|
+
},
|
|
719
|
+
pathPrefix: statePrefix || undefined
|
|
718
720
|
});
|
|
719
|
-
|
|
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);
|
|
720
724
|
for (const [actionName, handler] of definition.handlers.onAction) {
|
|
721
|
-
|
|
725
|
+
log2.debug(`Registering action handler: ${actionName} for module ${definition.name}`);
|
|
722
726
|
this.engine.onAction(actionName, async (action) => {
|
|
723
|
-
|
|
727
|
+
log2.debug(`Action handler fired: ${actionName}`, action);
|
|
724
728
|
const actionCtx = {
|
|
725
729
|
name: action.name,
|
|
726
730
|
payload: action.payload,
|
|
@@ -742,355 +746,114 @@ class HypenModuleInstance {
|
|
|
742
746
|
throw result.error;
|
|
743
747
|
}
|
|
744
748
|
} else {
|
|
745
|
-
|
|
749
|
+
log2.debug(`Action handler completed: ${actionName}`);
|
|
746
750
|
}
|
|
747
751
|
});
|
|
748
752
|
}
|
|
749
753
|
this.callCreatedHandler();
|
|
750
754
|
}
|
|
751
755
|
createGlobalContextAPI() {
|
|
752
|
-
if (!this.globalContext) {
|
|
753
|
-
throw new Error("Global context not available");
|
|
754
|
-
}
|
|
755
|
-
const ctx = this.globalContext;
|
|
756
|
-
const api = {
|
|
757
|
-
getModule: (id) => ctx.getModule(id),
|
|
758
|
-
hasModule: (id) => ctx.hasModule(id),
|
|
759
|
-
getModuleIds: () => ctx.getModuleIds(),
|
|
760
|
-
getGlobalState: () => ctx.getGlobalState(),
|
|
761
|
-
emit: (event, payload) => ctx.emit(event, payload),
|
|
762
|
-
on: (event, handler) => ctx.on(event, handler)
|
|
763
|
-
};
|
|
764
|
-
if (ctx.__router) {
|
|
765
|
-
api.__router = ctx.__router;
|
|
766
|
-
}
|
|
767
|
-
if (ctx.__hypenEngine) {
|
|
768
|
-
api.__hypenEngine = ctx.__hypenEngine;
|
|
769
|
-
}
|
|
770
|
-
return api;
|
|
771
|
-
}
|
|
772
|
-
async executeAction(actionName, handler, ctx) {
|
|
773
|
-
try {
|
|
774
|
-
const result = handler(ctx);
|
|
775
|
-
await result;
|
|
776
|
-
return Ok(undefined);
|
|
777
|
-
} catch (e) {
|
|
778
|
-
return Err(new ActionError(actionName, e));
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
async handleError(error, context) {
|
|
782
|
-
const errorCtx = {
|
|
783
|
-
error,
|
|
784
|
-
state: this.state,
|
|
785
|
-
actionName: context.actionName,
|
|
786
|
-
lifecycle: context.lifecycle
|
|
787
|
-
};
|
|
788
|
-
if (this.definition.handlers.onError) {
|
|
789
|
-
try {
|
|
790
|
-
const result = await this.definition.handlers.onError(errorCtx);
|
|
791
|
-
if (result && typeof result === "object") {
|
|
792
|
-
if ("handled" in result && result.handled) {
|
|
793
|
-
return false;
|
|
794
|
-
}
|
|
795
|
-
if ("rethrow" in result && result.rethrow) {
|
|
796
|
-
return true;
|
|
797
|
-
}
|
|
798
|
-
}
|
|
799
|
-
} catch (handlerError) {
|
|
800
|
-
log4.error("Error in onError handler:", handlerError);
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
if (this.globalContext) {
|
|
804
|
-
const eventContext = context.actionName ? `action:${context.actionName}` : context.lifecycle ? `lifecycle:${context.lifecycle}` : "unknown";
|
|
805
|
-
this.globalContext.emit("error", {
|
|
806
|
-
message: error.message,
|
|
807
|
-
error,
|
|
808
|
-
context: eventContext
|
|
809
|
-
});
|
|
810
|
-
}
|
|
811
|
-
log4.error(`${context.actionName ? `Action "${context.actionName}"` : `Lifecycle "${context.lifecycle}"`} error:`, error);
|
|
812
|
-
return false;
|
|
813
|
-
}
|
|
814
|
-
async callCreatedHandler() {
|
|
815
|
-
if (this.definition.handlers.onCreated) {
|
|
816
|
-
const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
|
|
817
|
-
await this.definition.handlers.onCreated(this.state, context);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
onStateChange(callback) {
|
|
821
|
-
this.stateChangeCallbacks.push(callback);
|
|
822
|
-
}
|
|
823
|
-
async destroy() {
|
|
824
|
-
if (this.isDestroyed)
|
|
825
|
-
return;
|
|
826
|
-
if (this.definition.handlers.onDestroyed) {
|
|
827
|
-
await this.definition.handlers.onDestroyed(this.state);
|
|
828
|
-
}
|
|
829
|
-
this.isDestroyed = true;
|
|
830
|
-
}
|
|
831
|
-
getState() {
|
|
832
|
-
return getStateSnapshot(this.state);
|
|
833
|
-
}
|
|
834
|
-
getLiveState() {
|
|
835
|
-
return this.state;
|
|
836
|
-
}
|
|
837
|
-
updateState(patch) {
|
|
838
|
-
Object.assign(this.state, patch);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
var log4, app;
|
|
842
|
-
var init_app = __esm(() => {
|
|
843
|
-
init_result();
|
|
844
|
-
init_state();
|
|
845
|
-
init_logger();
|
|
846
|
-
log4 = createLogger("ModuleInstance");
|
|
847
|
-
app = new HypenApp;
|
|
848
|
-
});
|
|
849
|
-
|
|
850
|
-
// src/engine.ts
|
|
851
|
-
init_logger();
|
|
852
|
-
var WasmEngineClass = null;
|
|
853
|
-
var log2 = frameworkLoggers.engine;
|
|
854
|
-
function unwrapForWasm(value) {
|
|
855
|
-
if (value === null || typeof value !== "object") {
|
|
856
|
-
return value;
|
|
857
|
-
}
|
|
858
|
-
if (typeof value.__getSnapshot === "function") {
|
|
859
|
-
return value.__getSnapshot();
|
|
860
|
-
}
|
|
861
|
-
try {
|
|
862
|
-
return structuredClone(value);
|
|
863
|
-
} catch {
|
|
864
|
-
return JSON.parse(JSON.stringify(value));
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
class Engine {
|
|
869
|
-
wasmEngine = null;
|
|
870
|
-
initialized = false;
|
|
871
|
-
async init() {
|
|
872
|
-
if (this.initialized)
|
|
873
|
-
return;
|
|
874
|
-
if (!WasmEngineClass) {
|
|
875
|
-
const wasm = await import("../wasm-node/hypen_engine.js");
|
|
876
|
-
WasmEngineClass = wasm.WasmEngine;
|
|
877
|
-
}
|
|
878
|
-
this.wasmEngine = new WasmEngineClass;
|
|
879
|
-
this.initialized = true;
|
|
880
|
-
}
|
|
881
|
-
ensureInitialized() {
|
|
882
|
-
if (!this.wasmEngine) {
|
|
883
|
-
throw new Error("Engine not initialized. Call init() first.");
|
|
884
|
-
}
|
|
885
|
-
return this.wasmEngine;
|
|
886
|
-
}
|
|
887
|
-
setRenderCallback(callback) {
|
|
888
|
-
const engine = this.ensureInitialized();
|
|
889
|
-
engine.setRenderCallback((patches) => {
|
|
890
|
-
callback(patches);
|
|
891
|
-
});
|
|
892
|
-
}
|
|
893
|
-
setComponentResolver(resolver) {
|
|
894
|
-
const engine = this.ensureInitialized();
|
|
895
|
-
engine.setComponentResolver((componentName, contextPath) => {
|
|
896
|
-
const result = resolver(componentName, contextPath);
|
|
897
|
-
return result;
|
|
898
|
-
});
|
|
899
|
-
}
|
|
900
|
-
renderSource(source) {
|
|
901
|
-
const engine = this.ensureInitialized();
|
|
902
|
-
engine.renderSource(source);
|
|
903
|
-
}
|
|
904
|
-
renderLazyComponent(source) {
|
|
905
|
-
const engine = this.ensureInitialized();
|
|
906
|
-
engine.renderLazyComponent(source);
|
|
907
|
-
}
|
|
908
|
-
renderInto(source, parentNodeId, state) {
|
|
909
|
-
const engine = this.ensureInitialized();
|
|
910
|
-
engine.renderInto(source, parentNodeId, unwrapForWasm(state));
|
|
911
|
-
}
|
|
912
|
-
notifyStateChange(paths, values) {
|
|
913
|
-
const engine = this.ensureInitialized();
|
|
914
|
-
if (paths.length === 0) {
|
|
915
|
-
return;
|
|
916
|
-
}
|
|
917
|
-
engine.updateStateSparse(paths, unwrapForWasm(values));
|
|
918
|
-
log2.debug("State changed (sparse):", paths);
|
|
919
|
-
}
|
|
920
|
-
notifyStateChangeFull(paths, currentState) {
|
|
921
|
-
const engine = this.ensureInitialized();
|
|
922
|
-
engine.updateState(unwrapForWasm(currentState));
|
|
923
|
-
if (paths.length > 0) {
|
|
924
|
-
log2.debug("State changed (full):", paths);
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
updateState(statePatch) {
|
|
928
|
-
const engine = this.ensureInitialized();
|
|
929
|
-
engine.updateState(unwrapForWasm(statePatch));
|
|
930
|
-
}
|
|
931
|
-
dispatchAction(name, payload) {
|
|
932
|
-
const engine = this.ensureInitialized();
|
|
933
|
-
engine.dispatchAction(name, payload ?? null);
|
|
934
|
-
}
|
|
935
|
-
onAction(actionName, handler) {
|
|
936
|
-
const engine = this.ensureInitialized();
|
|
937
|
-
engine.onAction(actionName, (action) => {
|
|
938
|
-
Promise.resolve(handler(action)).catch((err) => log2.error("Action handler error:", err));
|
|
939
|
-
});
|
|
940
|
-
}
|
|
941
|
-
setModule(name, actions, stateKeys, initialState) {
|
|
942
|
-
const engine = this.ensureInitialized();
|
|
943
|
-
engine.setModule(name, actions, stateKeys, initialState);
|
|
944
|
-
}
|
|
945
|
-
getRevision() {
|
|
946
|
-
const engine = this.ensureInitialized();
|
|
947
|
-
return Number(engine.getRevision());
|
|
948
|
-
}
|
|
949
|
-
clearTree() {
|
|
950
|
-
const engine = this.ensureInitialized();
|
|
951
|
-
engine.clearTree();
|
|
952
|
-
}
|
|
953
|
-
debugParseComponent(source) {
|
|
954
|
-
const engine = this.ensureInitialized();
|
|
955
|
-
return engine.debugParseComponent(source);
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
// src/engine.browser.ts
|
|
960
|
-
init_logger();
|
|
961
|
-
var log3 = frameworkLoggers.engine;
|
|
962
|
-
var wasmInit = null;
|
|
963
|
-
var WasmEngineClass2 = null;
|
|
964
|
-
function mapToObject(value) {
|
|
965
|
-
if (value instanceof Map) {
|
|
966
|
-
const obj = {};
|
|
967
|
-
for (const [key, val] of value.entries()) {
|
|
968
|
-
obj[key] = mapToObject(val);
|
|
756
|
+
if (!this.globalContext) {
|
|
757
|
+
throw new Error("Global context not available");
|
|
969
758
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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;
|
|
977
770
|
}
|
|
978
|
-
|
|
771
|
+
if (ctx.__hypenEngine) {
|
|
772
|
+
api.__hypenEngine = ctx.__hypenEngine;
|
|
773
|
+
}
|
|
774
|
+
return api;
|
|
979
775
|
}
|
|
980
|
-
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
class Engine2 {
|
|
984
|
-
wasmEngine = null;
|
|
985
|
-
initialized = false;
|
|
986
|
-
async init(options = {}) {
|
|
987
|
-
if (this.initialized)
|
|
988
|
-
return;
|
|
989
|
-
const cdnBase = "https://unpkg.com/@hypen-space/core@latest/wasm-browser";
|
|
990
|
-
const jsUrl = options.jsUrl ?? `${cdnBase}/hypen_engine.js`;
|
|
991
|
-
const wasmUrl = options.wasmUrl ?? `${cdnBase}/hypen_engine_bg.wasm`;
|
|
776
|
+
async executeAction(actionName, handler, ctx) {
|
|
992
777
|
try {
|
|
993
|
-
const
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
this.initialized = true;
|
|
999
|
-
} catch (error) {
|
|
1000
|
-
log3.error("Failed to initialize WASM engine:", error);
|
|
1001
|
-
throw error;
|
|
778
|
+
const result = handler(ctx);
|
|
779
|
+
await result;
|
|
780
|
+
return Ok(undefined);
|
|
781
|
+
} catch (e) {
|
|
782
|
+
return Err(new ActionError(actionName, e));
|
|
1002
783
|
}
|
|
1003
784
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
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
|
+
}
|
|
1007
806
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
}
|
|
1016
|
-
setComponentResolver(resolver) {
|
|
1017
|
-
const engine = this.ensureInitialized();
|
|
1018
|
-
engine.setComponentResolver((componentName, contextPath) => {
|
|
1019
|
-
const result = resolver(componentName, contextPath);
|
|
1020
|
-
return result;
|
|
1021
|
-
});
|
|
1022
|
-
}
|
|
1023
|
-
renderSource(source) {
|
|
1024
|
-
const engine = this.ensureInitialized();
|
|
1025
|
-
engine.renderSource(source);
|
|
1026
|
-
}
|
|
1027
|
-
renderLazyComponent(source) {
|
|
1028
|
-
const engine = this.ensureInitialized();
|
|
1029
|
-
engine.renderLazyComponent(source);
|
|
1030
|
-
}
|
|
1031
|
-
renderInto(source, parentNodeId, state) {
|
|
1032
|
-
const engine = this.ensureInitialized();
|
|
1033
|
-
const safeState = JSON.parse(JSON.stringify(state));
|
|
1034
|
-
engine.renderInto(source, parentNodeId, safeState);
|
|
1035
|
-
}
|
|
1036
|
-
notifyStateChange(paths, values) {
|
|
1037
|
-
const engine = this.ensureInitialized();
|
|
1038
|
-
if (paths.length === 0) {
|
|
1039
|
-
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
|
+
});
|
|
1040
814
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
log3.debug("State changed (sparse):", paths);
|
|
815
|
+
log2.error(`${context.actionName ? `Action "${context.actionName}"` : `Lifecycle "${context.lifecycle}"`} error:`, error);
|
|
816
|
+
return false;
|
|
1044
817
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
if (paths.length > 0) {
|
|
1050
|
-
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);
|
|
1051
822
|
}
|
|
1052
823
|
}
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
const plainObject = JSON.parse(JSON.stringify(statePatch));
|
|
1056
|
-
engine.updateState(plainObject);
|
|
1057
|
-
}
|
|
1058
|
-
dispatchAction(name, payload) {
|
|
1059
|
-
const engine = this.ensureInitialized();
|
|
1060
|
-
log3.debug(`Action dispatched: ${name}`);
|
|
1061
|
-
engine.dispatchAction(name, payload ?? null);
|
|
1062
|
-
}
|
|
1063
|
-
onAction(actionName, handler) {
|
|
1064
|
-
const engine = this.ensureInitialized();
|
|
1065
|
-
engine.onAction(actionName, (action) => {
|
|
1066
|
-
const normalizedAction = {
|
|
1067
|
-
...action,
|
|
1068
|
-
payload: action.payload ? mapToObject(action.payload) : action.payload
|
|
1069
|
-
};
|
|
1070
|
-
Promise.resolve(handler(normalizedAction)).catch((err) => log3.error("Action handler error:", err));
|
|
1071
|
-
});
|
|
824
|
+
onStateChange(callback) {
|
|
825
|
+
this.stateChangeCallbacks.push(callback);
|
|
1072
826
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
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;
|
|
1076
834
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
return engine.getRevision();
|
|
835
|
+
getState() {
|
|
836
|
+
return getStateSnapshot(this.state);
|
|
1080
837
|
}
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
engine.clearTree();
|
|
838
|
+
getLiveState() {
|
|
839
|
+
return this.state;
|
|
1084
840
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
return engine.debugParseComponent(source);
|
|
841
|
+
updateState(patch) {
|
|
842
|
+
Object.assign(this.state, patch);
|
|
1088
843
|
}
|
|
1089
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
|
+
});
|
|
1090
853
|
|
|
1091
854
|
// src/renderer.ts
|
|
1092
855
|
init_logger();
|
|
1093
|
-
var
|
|
856
|
+
var log3 = frameworkLoggers.renderer;
|
|
1094
857
|
|
|
1095
858
|
class BaseRenderer {
|
|
1096
859
|
nodes = new Map;
|
|
@@ -1132,14 +895,14 @@ class BaseRenderer {
|
|
|
1132
895
|
|
|
1133
896
|
class ConsoleRenderer {
|
|
1134
897
|
applyPatches(patches) {
|
|
1135
|
-
|
|
898
|
+
log3.debug("Patches:", patches);
|
|
1136
899
|
}
|
|
1137
900
|
}
|
|
1138
901
|
|
|
1139
902
|
// src/router.ts
|
|
1140
903
|
init_state();
|
|
1141
904
|
init_logger();
|
|
1142
|
-
var
|
|
905
|
+
var log4 = frameworkLoggers.router;
|
|
1143
906
|
|
|
1144
907
|
class HypenRouter {
|
|
1145
908
|
state;
|
|
@@ -1177,7 +940,7 @@ class HypenRouter {
|
|
|
1177
940
|
this.updatePath(newPath, false);
|
|
1178
941
|
});
|
|
1179
942
|
this.isInitialized = true;
|
|
1180
|
-
|
|
943
|
+
log4.debug("Router initialized at:", initialPath);
|
|
1181
944
|
}
|
|
1182
945
|
getPathFromBrowser() {
|
|
1183
946
|
if (typeof window === "undefined")
|
|
@@ -1198,21 +961,21 @@ class HypenRouter {
|
|
|
1198
961
|
return query;
|
|
1199
962
|
}
|
|
1200
963
|
push(path) {
|
|
1201
|
-
|
|
964
|
+
log4.debug("push:", path);
|
|
1202
965
|
this.updatePath(path, true);
|
|
1203
966
|
}
|
|
1204
967
|
replace(path) {
|
|
1205
|
-
|
|
968
|
+
log4.debug("replace:", path);
|
|
1206
969
|
this.updatePath(path, true, true);
|
|
1207
970
|
}
|
|
1208
971
|
back() {
|
|
1209
|
-
|
|
972
|
+
log4.debug("back");
|
|
1210
973
|
if (typeof window !== "undefined") {
|
|
1211
974
|
window.history.back();
|
|
1212
975
|
}
|
|
1213
976
|
}
|
|
1214
977
|
forward() {
|
|
1215
|
-
|
|
978
|
+
log4.debug("forward");
|
|
1216
979
|
if (typeof window !== "undefined") {
|
|
1217
980
|
window.history.forward();
|
|
1218
981
|
}
|
|
@@ -1308,7 +1071,7 @@ class HypenRouter {
|
|
|
1308
1071
|
try {
|
|
1309
1072
|
callback(this.getState());
|
|
1310
1073
|
} catch (error) {
|
|
1311
|
-
|
|
1074
|
+
log4.error("Error in route subscriber:", error);
|
|
1312
1075
|
}
|
|
1313
1076
|
return () => {
|
|
1314
1077
|
this.subscribers.delete(callback);
|
|
@@ -1320,7 +1083,7 @@ class HypenRouter {
|
|
|
1320
1083
|
try {
|
|
1321
1084
|
callback(routeState);
|
|
1322
1085
|
} catch (error) {
|
|
1323
|
-
|
|
1086
|
+
log4.error("Error in route subscriber:", error);
|
|
1324
1087
|
}
|
|
1325
1088
|
});
|
|
1326
1089
|
}
|
|
@@ -1338,7 +1101,7 @@ class HypenRouter {
|
|
|
1338
1101
|
|
|
1339
1102
|
// src/events.ts
|
|
1340
1103
|
init_logger();
|
|
1341
|
-
var
|
|
1104
|
+
var log5 = frameworkLoggers.events;
|
|
1342
1105
|
|
|
1343
1106
|
class TypedEventEmitter {
|
|
1344
1107
|
eventBus = new Map;
|
|
@@ -1351,7 +1114,7 @@ class TypedEventEmitter {
|
|
|
1351
1114
|
try {
|
|
1352
1115
|
handler(payload);
|
|
1353
1116
|
} catch (error) {
|
|
1354
|
-
|
|
1117
|
+
log5.error(`Error in event handler for "${String(event)}":`, error);
|
|
1355
1118
|
}
|
|
1356
1119
|
});
|
|
1357
1120
|
}
|
|
@@ -1404,7 +1167,7 @@ function createEventEmitter() {
|
|
|
1404
1167
|
|
|
1405
1168
|
// src/context.ts
|
|
1406
1169
|
init_logger();
|
|
1407
|
-
var
|
|
1170
|
+
var log6 = frameworkLoggers.context;
|
|
1408
1171
|
|
|
1409
1172
|
class HypenGlobalContext {
|
|
1410
1173
|
modules = new Map;
|
|
@@ -1418,14 +1181,14 @@ class HypenGlobalContext {
|
|
|
1418
1181
|
}
|
|
1419
1182
|
registerModule(id, instance) {
|
|
1420
1183
|
if (this.modules.has(id)) {
|
|
1421
|
-
|
|
1184
|
+
log6.warn(`Module "${id}" is already registered. Overwriting.`);
|
|
1422
1185
|
}
|
|
1423
1186
|
this.modules.set(id, instance);
|
|
1424
|
-
|
|
1187
|
+
log6.debug(`Registered module: ${id}`);
|
|
1425
1188
|
}
|
|
1426
1189
|
unregisterModule(id) {
|
|
1427
1190
|
this.modules.delete(id);
|
|
1428
|
-
|
|
1191
|
+
log6.debug(`Unregistered module: ${id}`);
|
|
1429
1192
|
}
|
|
1430
1193
|
getModule(id) {
|
|
1431
1194
|
const module = this.modules.get(id);
|
|
@@ -1454,14 +1217,14 @@ class HypenGlobalContext {
|
|
|
1454
1217
|
emit(event, payload) {
|
|
1455
1218
|
const handlers = this.legacyEventBus.get(event);
|
|
1456
1219
|
if (!handlers || handlers.size === 0) {
|
|
1457
|
-
|
|
1220
|
+
log6.debug(`Event "${event}" emitted but no listeners`);
|
|
1458
1221
|
} else {
|
|
1459
|
-
|
|
1222
|
+
log6.debug(`Emitting event: ${event}`, payload);
|
|
1460
1223
|
handlers.forEach((handler) => {
|
|
1461
1224
|
try {
|
|
1462
1225
|
handler(payload);
|
|
1463
1226
|
} catch (error) {
|
|
1464
|
-
|
|
1227
|
+
log6.error(`Error in event handler for "${event}":`, error);
|
|
1465
1228
|
}
|
|
1466
1229
|
});
|
|
1467
1230
|
}
|
|
@@ -1475,7 +1238,7 @@ class HypenGlobalContext {
|
|
|
1475
1238
|
}
|
|
1476
1239
|
const handlers = this.legacyEventBus.get(event);
|
|
1477
1240
|
handlers.add(handler);
|
|
1478
|
-
|
|
1241
|
+
log6.debug(`Listening to event: ${event}`);
|
|
1479
1242
|
return () => {
|
|
1480
1243
|
handlers.delete(handler);
|
|
1481
1244
|
if (handlers.size === 0) {
|
|
@@ -1510,7 +1273,7 @@ class HypenGlobalContext {
|
|
|
1510
1273
|
|
|
1511
1274
|
// src/disposable.ts
|
|
1512
1275
|
init_logger();
|
|
1513
|
-
var
|
|
1276
|
+
var log7 = frameworkLoggers.lifecycle;
|
|
1514
1277
|
function isDisposable(obj) {
|
|
1515
1278
|
return obj !== null && typeof obj === "object" && "dispose" in obj && typeof obj.dispose === "function";
|
|
1516
1279
|
}
|
|
@@ -1542,7 +1305,7 @@ class DisposableStack {
|
|
|
1542
1305
|
try {
|
|
1543
1306
|
item.dispose();
|
|
1544
1307
|
} catch (error) {
|
|
1545
|
-
|
|
1308
|
+
log7.error("Error during dispose:", error);
|
|
1546
1309
|
}
|
|
1547
1310
|
}
|
|
1548
1311
|
}
|
|
@@ -1633,7 +1396,7 @@ function compositeDisposable(...disposables) {
|
|
|
1633
1396
|
try {
|
|
1634
1397
|
d.dispose();
|
|
1635
1398
|
} catch (error) {
|
|
1636
|
-
|
|
1399
|
+
log7.error("Error during dispose:", error);
|
|
1637
1400
|
}
|
|
1638
1401
|
}
|
|
1639
1402
|
}
|
|
@@ -1787,7 +1550,7 @@ var RetryPresets = {
|
|
|
1787
1550
|
|
|
1788
1551
|
// src/remote/client.ts
|
|
1789
1552
|
init_logger();
|
|
1790
|
-
var
|
|
1553
|
+
var log8 = frameworkLoggers.remote;
|
|
1791
1554
|
|
|
1792
1555
|
class RemoteEngine {
|
|
1793
1556
|
ws = null;
|
|
@@ -1895,7 +1658,7 @@ class RemoteEngine {
|
|
|
1895
1658
|
}
|
|
1896
1659
|
dispatchAction(action, payload) {
|
|
1897
1660
|
if (this.state !== "connected" || !this.ws) {
|
|
1898
|
-
|
|
1661
|
+
log8.warn("Cannot dispatch action: not connected");
|
|
1899
1662
|
return;
|
|
1900
1663
|
}
|
|
1901
1664
|
const message = {
|
|
@@ -1968,7 +1731,7 @@ class RemoteEngine {
|
|
|
1968
1731
|
break;
|
|
1969
1732
|
}
|
|
1970
1733
|
} catch (e) {
|
|
1971
|
-
|
|
1734
|
+
log8.error("Error handling remote message:", e);
|
|
1972
1735
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
1973
1736
|
this.errorCallbacks.forEach((cb) => cb(error));
|
|
1974
1737
|
}
|
|
@@ -1997,7 +1760,7 @@ class RemoteEngine {
|
|
|
1997
1760
|
}
|
|
1998
1761
|
handlePatch(message) {
|
|
1999
1762
|
if (message.revision <= this.currentRevision) {
|
|
2000
|
-
|
|
1763
|
+
log8.warn(`Out of order patch: expected > ${this.currentRevision}, got ${message.revision}`);
|
|
2001
1764
|
return;
|
|
2002
1765
|
}
|
|
2003
1766
|
this.currentRevision = message.revision;
|
|
@@ -2023,16 +1786,121 @@ class RemoteEngine {
|
|
|
2023
1786
|
maxDelayMs: 30000,
|
|
2024
1787
|
jitter: 0.1,
|
|
2025
1788
|
onRetry: (attempt, error) => {
|
|
2026
|
-
|
|
1789
|
+
log8.debug(`Reconnection attempt ${attempt}/${this.options.maxReconnectAttempts} failed: ${error.message}`);
|
|
2027
1790
|
}
|
|
2028
1791
|
}).catch((error) => {
|
|
2029
|
-
|
|
1792
|
+
log8.error("Max reconnection attempts reached:", error.message);
|
|
2030
1793
|
this.errorCallbacks.forEach((cb) => cb(new ConnectionError(this.url, error, this.options.maxReconnectAttempts)));
|
|
2031
1794
|
});
|
|
2032
1795
|
}, this.options.reconnectInterval);
|
|
2033
1796
|
}
|
|
2034
1797
|
}
|
|
2035
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
|
+
|
|
2036
1904
|
// src/remote/server.ts
|
|
2037
1905
|
init_app();
|
|
2038
1906
|
|
|
@@ -2162,7 +2030,7 @@ class SessionManager {
|
|
|
2162
2030
|
|
|
2163
2031
|
// src/remote/server.ts
|
|
2164
2032
|
init_logger();
|
|
2165
|
-
var
|
|
2033
|
+
var log10 = frameworkLoggers.remote;
|
|
2166
2034
|
|
|
2167
2035
|
class RemoteServer {
|
|
2168
2036
|
_module = null;
|
|
@@ -2240,7 +2108,7 @@ class RemoteServer {
|
|
|
2240
2108
|
return new Response("Hypen Remote Server", { status: 200 });
|
|
2241
2109
|
}
|
|
2242
2110
|
});
|
|
2243
|
-
|
|
2111
|
+
log10.info(`Hypen app streaming on ws://${hostname}:${finalPort}`);
|
|
2244
2112
|
return this;
|
|
2245
2113
|
}
|
|
2246
2114
|
stop() {
|
|
@@ -2283,7 +2151,7 @@ class RemoteServer {
|
|
|
2283
2151
|
}
|
|
2284
2152
|
}, 1000);
|
|
2285
2153
|
} catch (error) {
|
|
2286
|
-
|
|
2154
|
+
log10.error("Error handling WebSocket open:", error);
|
|
2287
2155
|
ws.close(1011, "Internal server error");
|
|
2288
2156
|
}
|
|
2289
2157
|
}
|
|
@@ -2454,7 +2322,7 @@ class RemoteServer {
|
|
|
2454
2322
|
break;
|
|
2455
2323
|
}
|
|
2456
2324
|
} catch (error) {
|
|
2457
|
-
|
|
2325
|
+
log10.error("Error handling WebSocket message:", error);
|
|
2458
2326
|
}
|
|
2459
2327
|
}
|
|
2460
2328
|
async handleClose(ws) {
|
|
@@ -2537,7 +2405,7 @@ function serve(options) {
|
|
|
2537
2405
|
init_logger();
|
|
2538
2406
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
2539
2407
|
import { join } from "path";
|
|
2540
|
-
var
|
|
2408
|
+
var log11 = frameworkLoggers.loader;
|
|
2541
2409
|
|
|
2542
2410
|
class ComponentLoader {
|
|
2543
2411
|
components = new Map;
|
|
@@ -2572,16 +2440,16 @@ class ComponentLoader {
|
|
|
2572
2440
|
const templatePath = join(dirPath, "component.hypen");
|
|
2573
2441
|
const template = readFileSync(templatePath, "utf-8");
|
|
2574
2442
|
this.register(name, module, template, dirPath);
|
|
2575
|
-
|
|
2443
|
+
log11.debug(`Loaded component: ${name} from ${dirPath}`);
|
|
2576
2444
|
} catch (error) {
|
|
2577
|
-
|
|
2445
|
+
log11.error(`Failed to load component ${name} from ${dirPath}:`, error);
|
|
2578
2446
|
throw error;
|
|
2579
2447
|
}
|
|
2580
2448
|
}
|
|
2581
2449
|
async loadFromComponentsDir(baseDir) {
|
|
2582
2450
|
try {
|
|
2583
2451
|
if (!existsSync(baseDir)) {
|
|
2584
|
-
|
|
2452
|
+
log11.warn(`Components directory not found: ${baseDir}`);
|
|
2585
2453
|
return;
|
|
2586
2454
|
}
|
|
2587
2455
|
const entries = readdirSync(baseDir, { withFileTypes: true });
|
|
@@ -2594,9 +2462,9 @@ class ComponentLoader {
|
|
|
2594
2462
|
await this.loadFromDirectory(entry.name, componentDir);
|
|
2595
2463
|
}
|
|
2596
2464
|
}
|
|
2597
|
-
|
|
2465
|
+
log11.debug(`Loaded ${this.components.size} components from ${baseDir}`);
|
|
2598
2466
|
} catch (error) {
|
|
2599
|
-
|
|
2467
|
+
log11.error(`Failed to load components from ${baseDir}:`, error);
|
|
2600
2468
|
throw error;
|
|
2601
2469
|
}
|
|
2602
2470
|
}
|
|
@@ -2607,14 +2475,32 @@ var componentLoader = new ComponentLoader;
|
|
|
2607
2475
|
class ComponentResolver {
|
|
2608
2476
|
cache = new Map;
|
|
2609
2477
|
options;
|
|
2478
|
+
moduleRegistry;
|
|
2610
2479
|
constructor(options = {}) {
|
|
2611
2480
|
this.options = {
|
|
2612
2481
|
baseDir: options.baseDir || process.cwd(),
|
|
2613
2482
|
cache: options.cache ?? true,
|
|
2614
|
-
customFetch: options.customFetch || this.defaultFetch.bind(this)
|
|
2483
|
+
customFetch: options.customFetch || this.defaultFetch.bind(this),
|
|
2484
|
+
moduleRegistry: options.moduleRegistry
|
|
2615
2485
|
};
|
|
2486
|
+
this.moduleRegistry = options.moduleRegistry;
|
|
2616
2487
|
}
|
|
2617
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
|
+
}
|
|
2618
2504
|
const sourcePath = this.getSourcePath(importStmt.source);
|
|
2619
2505
|
if (this.options.cache && this.cache.has(sourcePath)) {
|
|
2620
2506
|
const cached = this.cache.get(sourcePath);
|
|
@@ -2632,8 +2518,17 @@ class ComponentResolver {
|
|
|
2632
2518
|
return this.extractComponents(importStmt.clause, component);
|
|
2633
2519
|
}
|
|
2634
2520
|
async resolveLocal(path) {
|
|
2635
|
-
|
|
2636
|
-
|
|
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 };
|
|
2637
2532
|
}
|
|
2638
2533
|
async resolveUrl(url) {
|
|
2639
2534
|
try {
|
|
@@ -2701,29 +2596,26 @@ class ComponentResolver {
|
|
|
2701
2596
|
init_logger();
|
|
2702
2597
|
import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, watch } from "fs";
|
|
2703
2598
|
import { join as join2, basename, resolve } from "path";
|
|
2704
|
-
function removeImports(text) {
|
|
2705
|
-
return text.replace(/import\s+(?:\{[^}]+\}|\w+)\s+from\s+["'][^"']+["']\s*/g, "");
|
|
2706
|
-
}
|
|
2707
2599
|
async function discoverComponents(baseDir, options = {}) {
|
|
2708
2600
|
const {
|
|
2709
2601
|
patterns = ["single-file", "folder", "sibling", "index"],
|
|
2710
2602
|
recursive = false,
|
|
2711
2603
|
debug = false
|
|
2712
2604
|
} = options;
|
|
2713
|
-
const
|
|
2605
|
+
const log12 = debug ? (...args) => frameworkLoggers.discovery.debug(...args) : () => {};
|
|
2714
2606
|
const resolvedDir = resolve(baseDir);
|
|
2715
2607
|
const components = [];
|
|
2716
2608
|
const seen = new Set;
|
|
2717
|
-
|
|
2718
|
-
|
|
2609
|
+
log12("Scanning directory:", resolvedDir);
|
|
2610
|
+
log12("Patterns:", patterns);
|
|
2719
2611
|
const addTwoFileComponent = (name, hypenPath, modulePath) => {
|
|
2720
2612
|
if (seen.has(name)) {
|
|
2721
|
-
|
|
2613
|
+
log12(`Skipping duplicate: ${name}`);
|
|
2722
2614
|
return;
|
|
2723
2615
|
}
|
|
2724
2616
|
seen.add(name);
|
|
2725
2617
|
const templateRaw = readFileSync2(hypenPath, "utf-8");
|
|
2726
|
-
const template =
|
|
2618
|
+
const template = templateRaw.trim();
|
|
2727
2619
|
components.push({
|
|
2728
2620
|
name,
|
|
2729
2621
|
hypenPath,
|
|
@@ -2732,11 +2624,11 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2732
2624
|
hasModule: modulePath !== null,
|
|
2733
2625
|
isSingleFile: false
|
|
2734
2626
|
});
|
|
2735
|
-
|
|
2627
|
+
log12(`Found: ${name} (two-file, ${modulePath ? "with module" : "stateless"})`);
|
|
2736
2628
|
};
|
|
2737
2629
|
const addSingleFileComponent = (name, modulePath, template) => {
|
|
2738
2630
|
if (seen.has(name)) {
|
|
2739
|
-
|
|
2631
|
+
log12(`Skipping duplicate: ${name}`);
|
|
2740
2632
|
return;
|
|
2741
2633
|
}
|
|
2742
2634
|
seen.add(name);
|
|
@@ -2748,7 +2640,7 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2748
2640
|
hasModule: true,
|
|
2749
2641
|
isSingleFile: true
|
|
2750
2642
|
});
|
|
2751
|
-
|
|
2643
|
+
log12(`Found: ${name} (single-file with inline template)`);
|
|
2752
2644
|
};
|
|
2753
2645
|
const scanForFolderComponents = (dir) => {
|
|
2754
2646
|
if (!existsSync2(dir))
|
|
@@ -2832,7 +2724,7 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2832
2724
|
addSingleFileComponent(baseName, modulePath, module.template);
|
|
2833
2725
|
}
|
|
2834
2726
|
} catch (e) {
|
|
2835
|
-
|
|
2727
|
+
log12(`Failed to import potential single-file component: ${entry.name}`, e);
|
|
2836
2728
|
}
|
|
2837
2729
|
}
|
|
2838
2730
|
}
|
|
@@ -2846,7 +2738,7 @@ async function discoverComponents(baseDir, options = {}) {
|
|
|
2846
2738
|
if (patterns.includes("single-file")) {
|
|
2847
2739
|
await scanForSingleFileComponents(resolvedDir);
|
|
2848
2740
|
}
|
|
2849
|
-
|
|
2741
|
+
log12(`Discovered ${components.length} components`);
|
|
2850
2742
|
return components;
|
|
2851
2743
|
}
|
|
2852
2744
|
async function loadDiscoveredComponents(components) {
|
|
@@ -2882,7 +2774,7 @@ function watchComponents(baseDir, options = {}) {
|
|
|
2882
2774
|
debug = false,
|
|
2883
2775
|
...discoveryOptions
|
|
2884
2776
|
} = options;
|
|
2885
|
-
const
|
|
2777
|
+
const log12 = debug ? (...args) => frameworkLoggers.discovery.debug("[watch]", ...args) : () => {};
|
|
2886
2778
|
let currentComponents = new Map;
|
|
2887
2779
|
let debounceTimer = null;
|
|
2888
2780
|
const initialScan = async () => {
|
|
@@ -2895,22 +2787,22 @@ function watchComponents(baseDir, options = {}) {
|
|
|
2895
2787
|
clearTimeout(debounceTimer);
|
|
2896
2788
|
}
|
|
2897
2789
|
debounceTimer = setTimeout(async () => {
|
|
2898
|
-
|
|
2790
|
+
log12("Rescanning...");
|
|
2899
2791
|
const newComponents = await discoverComponents(resolvedDir, discoveryOptions);
|
|
2900
2792
|
const newMap = new Map(newComponents.map((c) => [c.name, c]));
|
|
2901
2793
|
for (const [name, component] of newMap) {
|
|
2902
2794
|
const existing = currentComponents.get(name);
|
|
2903
2795
|
if (!existing) {
|
|
2904
|
-
|
|
2796
|
+
log12("Added:", name);
|
|
2905
2797
|
onAdd?.(component);
|
|
2906
2798
|
} else if (existing.template !== component.template || existing.modulePath !== component.modulePath) {
|
|
2907
|
-
|
|
2799
|
+
log12("Updated:", name);
|
|
2908
2800
|
onUpdate?.(component);
|
|
2909
2801
|
}
|
|
2910
2802
|
}
|
|
2911
2803
|
for (const name of currentComponents.keys()) {
|
|
2912
2804
|
if (!newMap.has(name)) {
|
|
2913
|
-
|
|
2805
|
+
log12("Removed:", name);
|
|
2914
2806
|
onRemove?.(name);
|
|
2915
2807
|
}
|
|
2916
2808
|
}
|
|
@@ -2922,7 +2814,7 @@ function watchComponents(baseDir, options = {}) {
|
|
|
2922
2814
|
if (!filename)
|
|
2923
2815
|
return;
|
|
2924
2816
|
if (filename.endsWith(".hypen") || filename.endsWith(".ts")) {
|
|
2925
|
-
|
|
2817
|
+
log12("File changed:", filename);
|
|
2926
2818
|
rescan();
|
|
2927
2819
|
}
|
|
2928
2820
|
});
|
|
@@ -3045,28 +2937,28 @@ function parseImports(text) {
|
|
|
3045
2937
|
}
|
|
3046
2938
|
return imports;
|
|
3047
2939
|
}
|
|
3048
|
-
function
|
|
2940
|
+
function removeImports(text) {
|
|
3049
2941
|
return text.replace(/import\s+(?:\{[^}]+\}|\w+)\s+from\s+["'][^"']+["']\s*/g, "");
|
|
3050
2942
|
}
|
|
3051
2943
|
function hypenPlugin(options = {}) {
|
|
3052
2944
|
const { debug = false, patterns = ["sibling", "component", "index"] } = options;
|
|
3053
|
-
const
|
|
2945
|
+
const log12 = debug ? (...args) => frameworkLoggers.plugin.debug(...args) : () => {};
|
|
3054
2946
|
return {
|
|
3055
2947
|
name: "hypen-loader",
|
|
3056
2948
|
async setup(build) {
|
|
3057
2949
|
build.onLoad({ filter: /\.hypen$/ }, async (args) => {
|
|
3058
2950
|
const hypenPath = resolve2(args.path);
|
|
3059
|
-
|
|
2951
|
+
log12("Loading:", hypenPath);
|
|
3060
2952
|
const templateRaw = readFileSync3(hypenPath, "utf-8");
|
|
3061
2953
|
const imports = parseImports(templateRaw);
|
|
3062
|
-
const template =
|
|
2954
|
+
const template = removeImports(templateRaw).trim();
|
|
3063
2955
|
if (imports.length > 0) {
|
|
3064
|
-
|
|
2956
|
+
log12("Found imports:", imports);
|
|
3065
2957
|
}
|
|
3066
2958
|
const componentName = getComponentName(hypenPath);
|
|
3067
|
-
|
|
2959
|
+
log12("Component name:", componentName);
|
|
3068
2960
|
const modulePath = findModulePath(hypenPath, patterns);
|
|
3069
|
-
|
|
2961
|
+
log12("Module path:", modulePath);
|
|
3070
2962
|
let contents;
|
|
3071
2963
|
if (modulePath) {
|
|
3072
2964
|
const relativeModulePath = modulePath.replace(/\.ts$/, ".js");
|
|
@@ -3078,7 +2970,7 @@ export const name = ${JSON.stringify(componentName)};
|
|
|
3078
2970
|
export default { module: _module, template: ${JSON.stringify(template)}, name: ${JSON.stringify(componentName)} };
|
|
3079
2971
|
`;
|
|
3080
2972
|
} else {
|
|
3081
|
-
|
|
2973
|
+
log12("No module found, creating stateless component");
|
|
3082
2974
|
contents = `
|
|
3083
2975
|
import { app } from "@hypen-space/core";
|
|
3084
2976
|
const _module = app.defineState({}).build();
|
|
@@ -3105,19 +2997,19 @@ var plugin_default = hypenPlugin;
|
|
|
3105
2997
|
// src/components/builtin.ts
|
|
3106
2998
|
init_app();
|
|
3107
2999
|
init_logger();
|
|
3108
|
-
var
|
|
3000
|
+
var log12 = frameworkLoggers.router;
|
|
3109
3001
|
var Router = app.defineState({
|
|
3110
3002
|
currentPath: "/",
|
|
3111
3003
|
matchedRoute: null,
|
|
3112
3004
|
routeParams: {}
|
|
3113
3005
|
}, { name: "__Router" }).onCreated((state, context) => {
|
|
3114
3006
|
if (!context) {
|
|
3115
|
-
|
|
3007
|
+
log12.error("Requires global context");
|
|
3116
3008
|
return;
|
|
3117
3009
|
}
|
|
3118
3010
|
const router = context.__router;
|
|
3119
3011
|
if (!router) {
|
|
3120
|
-
|
|
3012
|
+
log12.error("Router not found in context");
|
|
3121
3013
|
return;
|
|
3122
3014
|
}
|
|
3123
3015
|
const hypenEngine = context.__hypenEngine;
|
|
@@ -3139,13 +3031,13 @@ var Router = app.defineState({
|
|
|
3139
3031
|
try {
|
|
3140
3032
|
await hypenEngine.renderLazyRoute(routePath, componentName, htmlEl);
|
|
3141
3033
|
} catch (err) {
|
|
3142
|
-
|
|
3034
|
+
log12.error(`Failed to render route ${routePath}:`, err);
|
|
3143
3035
|
}
|
|
3144
3036
|
}
|
|
3145
3037
|
}
|
|
3146
3038
|
}
|
|
3147
3039
|
if (!matchFound) {
|
|
3148
|
-
|
|
3040
|
+
log12.warn(`No route matched path: ${currentPath}. Available routes:`, Array.from(routeElements).map((el) => el.dataset.routePath));
|
|
3149
3041
|
}
|
|
3150
3042
|
};
|
|
3151
3043
|
setTimeout(() => {
|
|
@@ -3164,7 +3056,7 @@ var Link = app.defineState({
|
|
|
3164
3056
|
}, { name: "__Link" }).onAction("navigate", ({ state, context }) => {
|
|
3165
3057
|
const router = context?.__router;
|
|
3166
3058
|
if (!router) {
|
|
3167
|
-
|
|
3059
|
+
log12.error("Link requires router context");
|
|
3168
3060
|
return;
|
|
3169
3061
|
}
|
|
3170
3062
|
const targetPath = state.to;
|
|
@@ -3314,16 +3206,14 @@ export {
|
|
|
3314
3206
|
HypenAppBuilder,
|
|
3315
3207
|
HypenApp,
|
|
3316
3208
|
Err,
|
|
3317
|
-
Engine,
|
|
3318
3209
|
DisposableStack,
|
|
3319
3210
|
DisposableMixin,
|
|
3320
3211
|
ConsoleRenderer,
|
|
3321
3212
|
ConnectionError,
|
|
3322
3213
|
ComponentResolver,
|
|
3323
3214
|
ComponentLoader,
|
|
3324
|
-
Engine2 as BrowserEngine,
|
|
3325
3215
|
BaseRenderer,
|
|
3326
3216
|
ActionError
|
|
3327
3217
|
};
|
|
3328
3218
|
|
|
3329
|
-
//# debugId=
|
|
3219
|
+
//# debugId=C03FB9EC8278859464756E2164756E21
|