@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.
Files changed (47) hide show
  1. package/dist/app.js +7 -3
  2. package/dist/app.js.map +3 -3
  3. package/dist/components/builtin.js +7 -3
  4. package/dist/components/builtin.js.map +3 -3
  5. package/dist/discovery.js +8 -7
  6. package/dist/discovery.js.map +4 -4
  7. package/dist/engine.browser.js.map +2 -2
  8. package/dist/engine.js +3 -7
  9. package/dist/engine.js.map +3 -3
  10. package/dist/index.browser.js +242 -371
  11. package/dist/index.browser.js.map +8 -9
  12. package/dist/index.js +546 -656
  13. package/dist/index.js.map +12 -13
  14. package/dist/remote/client.js.map +1 -1
  15. package/dist/remote/index.js +336 -336
  16. package/dist/remote/index.js.map +8 -8
  17. package/dist/remote/server.js +219 -219
  18. package/dist/remote/server.js.map +7 -7
  19. package/dist/renderer.js.map +1 -1
  20. package/dist/resolver.js +31 -4
  21. package/dist/resolver.js.map +3 -3
  22. package/package.json +13 -1
  23. package/src/app.ts +14 -2
  24. package/src/discovery.ts +15 -12
  25. package/src/engine.browser.ts +4 -32
  26. package/src/engine.ts +8 -44
  27. package/src/index.browser.ts +6 -4
  28. package/src/index.ts +22 -30
  29. package/src/managed-router.ts +195 -0
  30. package/src/module-registry.ts +76 -0
  31. package/src/remote/client.ts +1 -1
  32. package/src/remote/index.ts +2 -2
  33. package/src/remote/server.ts +1 -1
  34. package/src/remote/types.ts +1 -1
  35. package/src/renderer.ts +6 -2
  36. package/src/resolver.ts +56 -9
  37. package/src/types.ts +38 -0
  38. package/wasm-browser/README.md +7 -1
  39. package/wasm-browser/hypen_engine.d.ts +1 -0
  40. package/wasm-browser/hypen_engine.js +1 -0
  41. package/wasm-browser/hypen_engine_bg.wasm +0 -0
  42. package/wasm-browser/package.json +1 -1
  43. package/wasm-node/README.md +7 -1
  44. package/wasm-node/hypen_engine.d.ts +1 -0
  45. package/wasm-node/hypen_engine.js +1 -0
  46. package/wasm-node/hypen_engine_bg.wasm +0 -0
  47. package/wasm-node/package.json +1 -1
@@ -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") {
@@ -599,17 +400,216 @@ var init_result = __esm(() => {
599
400
  this.attempt = attempt;
600
401
  }
601
402
  };
602
- StateError = class StateError extends HypenError {
603
- path;
604
- constructor(message, path, cause) {
605
- super("STATE_ERROR", message, {
606
- context: { path },
607
- cause: cause instanceof Error ? cause : undefined
608
- });
609
- this.name = "StateError";
610
- this.path = path;
403
+ StateError = class StateError extends HypenError {
404
+ path;
405
+ constructor(message, path, cause) {
406
+ super("STATE_ERROR", message, {
407
+ context: { path },
408
+ cause: cause instanceof Error ? cause : undefined
409
+ });
410
+ this.name = "StateError";
411
+ this.path = path;
412
+ }
413
+ };
414
+ });
415
+
416
+ // src/logger.ts
417
+ function isProduction() {
418
+ if (typeof process !== "undefined" && process.env) {
419
+ return false;
420
+ }
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);
611
594
  }
612
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
613
  });
614
614
 
615
615
  // src/app.ts
@@ -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
- this.engine.setModule(definition.name || "AnonymousModule", definition.actions, definition.stateKeys, getStateSnapshot(this.state));
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
- log3.debug(`Registering action handler: ${actionName} for module ${definition.name}`);
725
+ log2.debug(`Registering action handler: ${actionName} for module ${definition.name}`);
722
726
  this.engine.onAction(actionName, async (action) => {
723
- log3.debug(`Action handler fired: ${actionName}`, action);
727
+ log2.debug(`Action handler fired: ${actionName}`, action);
724
728
  const actionCtx = {
725
729
  name: action.name,
726
730
  payload: action.payload,
@@ -742,7 +746,7 @@ class HypenModuleInstance {
742
746
  throw result.error;
743
747
  }
744
748
  } else {
745
- log3.debug(`Action handler completed: ${actionName}`);
749
+ log2.debug(`Action handler completed: ${actionName}`);
746
750
  }
747
751
  });
748
752
  }
@@ -797,7 +801,7 @@ class HypenModuleInstance {
797
801
  }
798
802
  }
799
803
  } catch (handlerError) {
800
- log3.error("Error in onError handler:", handlerError);
804
+ log2.error("Error in onError handler:", handlerError);
801
805
  }
802
806
  }
803
807
  if (this.globalContext) {
@@ -808,7 +812,7 @@ class HypenModuleInstance {
808
812
  context: eventContext
809
813
  });
810
814
  }
811
- log3.error(`${context.actionName ? `Action "${context.actionName}"` : `Lifecycle "${context.lifecycle}"`} error:`, error);
815
+ log2.error(`${context.actionName ? `Action "${context.actionName}"` : `Lifecycle "${context.lifecycle}"`} error:`, error);
812
816
  return false;
813
817
  }
814
818
  async callCreatedHandler() {
@@ -838,127 +842,18 @@ class HypenModuleInstance {
838
842
  Object.assign(this.state, patch);
839
843
  }
840
844
  }
841
- var log3, app;
845
+ var log2, app;
842
846
  var init_app = __esm(() => {
843
847
  init_result();
844
848
  init_state();
845
849
  init_logger();
846
- log3 = createLogger("ModuleInstance");
850
+ log2 = createLogger("ModuleInstance");
847
851
  app = new HypenApp;
848
852
  });
849
853
 
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
854
  // src/disposable.ts
960
855
  init_logger();
961
- var log4 = frameworkLoggers.lifecycle;
856
+ var log3 = frameworkLoggers.lifecycle;
962
857
  function isDisposable(obj) {
963
858
  return obj !== null && typeof obj === "object" && "dispose" in obj && typeof obj.dispose === "function";
964
859
  }
@@ -990,7 +885,7 @@ class DisposableStack {
990
885
  try {
991
886
  item.dispose();
992
887
  } catch (error) {
993
- log4.error("Error during dispose:", error);
888
+ log3.error("Error during dispose:", error);
994
889
  }
995
890
  }
996
891
  }
@@ -1081,7 +976,7 @@ function compositeDisposable(...disposables) {
1081
976
  try {
1082
977
  d.dispose();
1083
978
  } catch (error) {
1084
- log4.error("Error during dispose:", error);
979
+ log3.error("Error during dispose:", error);
1085
980
  }
1086
981
  }
1087
982
  }
@@ -1235,7 +1130,7 @@ var RetryPresets = {
1235
1130
 
1236
1131
  // src/remote/client.ts
1237
1132
  init_logger();
1238
- var log5 = frameworkLoggers.remote;
1133
+ var log4 = frameworkLoggers.remote;
1239
1134
 
1240
1135
  class RemoteEngine {
1241
1136
  ws = null;
@@ -1343,7 +1238,7 @@ class RemoteEngine {
1343
1238
  }
1344
1239
  dispatchAction(action, payload) {
1345
1240
  if (this.state !== "connected" || !this.ws) {
1346
- log5.warn("Cannot dispatch action: not connected");
1241
+ log4.warn("Cannot dispatch action: not connected");
1347
1242
  return;
1348
1243
  }
1349
1244
  const message = {
@@ -1416,7 +1311,7 @@ class RemoteEngine {
1416
1311
  break;
1417
1312
  }
1418
1313
  } catch (e) {
1419
- log5.error("Error handling remote message:", e);
1314
+ log4.error("Error handling remote message:", e);
1420
1315
  const error = e instanceof Error ? e : new Error(String(e));
1421
1316
  this.errorCallbacks.forEach((cb) => cb(error));
1422
1317
  }
@@ -1445,7 +1340,7 @@ class RemoteEngine {
1445
1340
  }
1446
1341
  handlePatch(message) {
1447
1342
  if (message.revision <= this.currentRevision) {
1448
- log5.warn(`Out of order patch: expected > ${this.currentRevision}, got ${message.revision}`);
1343
+ log4.warn(`Out of order patch: expected > ${this.currentRevision}, got ${message.revision}`);
1449
1344
  return;
1450
1345
  }
1451
1346
  this.currentRevision = message.revision;
@@ -1471,16 +1366,121 @@ class RemoteEngine {
1471
1366
  maxDelayMs: 30000,
1472
1367
  jitter: 0.1,
1473
1368
  onRetry: (attempt, error) => {
1474
- log5.debug(`Reconnection attempt ${attempt}/${this.options.maxReconnectAttempts} failed: ${error.message}`);
1369
+ log4.debug(`Reconnection attempt ${attempt}/${this.options.maxReconnectAttempts} failed: ${error.message}`);
1475
1370
  }
1476
1371
  }).catch((error) => {
1477
- log5.error("Max reconnection attempts reached:", error.message);
1372
+ log4.error("Max reconnection attempts reached:", error.message);
1478
1373
  this.errorCallbacks.forEach((cb) => cb(new ConnectionError(this.url, error, this.options.maxReconnectAttempts)));
1479
1374
  });
1480
1375
  }, this.options.reconnectInterval);
1481
1376
  }
1482
1377
  }
1483
1378
 
1379
+ // src/engine.ts
1380
+ init_logger();
1381
+ import { WasmEngine } from "../wasm-node/hypen_engine.js";
1382
+ var log5 = frameworkLoggers.engine;
1383
+ function unwrapForWasm(value) {
1384
+ if (value === null || typeof value !== "object") {
1385
+ return value;
1386
+ }
1387
+ if (typeof value.__getSnapshot === "function") {
1388
+ return value.__getSnapshot();
1389
+ }
1390
+ try {
1391
+ return structuredClone(value);
1392
+ } catch {
1393
+ return JSON.parse(JSON.stringify(value));
1394
+ }
1395
+ }
1396
+
1397
+ class Engine {
1398
+ wasmEngine = null;
1399
+ initialized = false;
1400
+ async init() {
1401
+ if (this.initialized)
1402
+ return;
1403
+ this.wasmEngine = new WasmEngine;
1404
+ this.initialized = true;
1405
+ }
1406
+ ensureInitialized() {
1407
+ if (!this.wasmEngine) {
1408
+ throw new Error("Engine not initialized. Call init() first.");
1409
+ }
1410
+ return this.wasmEngine;
1411
+ }
1412
+ setRenderCallback(callback) {
1413
+ const engine = this.ensureInitialized();
1414
+ engine.setRenderCallback((patches) => {
1415
+ callback(patches);
1416
+ });
1417
+ }
1418
+ setComponentResolver(resolver) {
1419
+ const engine = this.ensureInitialized();
1420
+ engine.setComponentResolver((componentName, contextPath) => {
1421
+ const result = resolver(componentName, contextPath);
1422
+ return result;
1423
+ });
1424
+ }
1425
+ renderSource(source) {
1426
+ const engine = this.ensureInitialized();
1427
+ engine.renderSource(source);
1428
+ }
1429
+ renderLazyComponent(source) {
1430
+ const engine = this.ensureInitialized();
1431
+ engine.renderLazyComponent(source);
1432
+ }
1433
+ renderInto(source, parentNodeId, state) {
1434
+ const engine = this.ensureInitialized();
1435
+ engine.renderInto(source, parentNodeId, unwrapForWasm(state));
1436
+ }
1437
+ notifyStateChange(paths, values) {
1438
+ const engine = this.ensureInitialized();
1439
+ if (paths.length === 0) {
1440
+ return;
1441
+ }
1442
+ engine.updateStateSparse(paths, unwrapForWasm(values));
1443
+ log5.debug("State changed (sparse):", paths);
1444
+ }
1445
+ notifyStateChangeFull(paths, currentState) {
1446
+ const engine = this.ensureInitialized();
1447
+ engine.updateState(unwrapForWasm(currentState));
1448
+ if (paths.length > 0) {
1449
+ log5.debug("State changed (full):", paths);
1450
+ }
1451
+ }
1452
+ updateState(statePatch) {
1453
+ const engine = this.ensureInitialized();
1454
+ engine.updateState(unwrapForWasm(statePatch));
1455
+ }
1456
+ dispatchAction(name, payload) {
1457
+ const engine = this.ensureInitialized();
1458
+ engine.dispatchAction(name, payload ?? null);
1459
+ }
1460
+ onAction(actionName, handler) {
1461
+ const engine = this.ensureInitialized();
1462
+ engine.onAction(actionName, (action) => {
1463
+ Promise.resolve(handler(action)).catch((err) => log5.error("Action handler error:", err));
1464
+ });
1465
+ }
1466
+ setModule(name, actions, stateKeys, initialState) {
1467
+ const engine = this.ensureInitialized();
1468
+ engine.setModule(name, actions, stateKeys, initialState);
1469
+ }
1470
+ getRevision() {
1471
+ const engine = this.ensureInitialized();
1472
+ return Number(engine.getRevision());
1473
+ }
1474
+ clearTree() {
1475
+ const engine = this.ensureInitialized();
1476
+ engine.clearTree();
1477
+ }
1478
+ debugParseComponent(source) {
1479
+ const engine = this.ensureInitialized();
1480
+ return engine.debugParseComponent(source);
1481
+ }
1482
+ }
1483
+
1484
1484
  // src/remote/server.ts
1485
1485
  init_app();
1486
1486
 
@@ -1987,4 +1987,4 @@ export {
1987
1987
  RemoteEngine
1988
1988
  };
1989
1989
 
1990
- //# debugId=C53D35A16364877D64756E2164756E21
1990
+ //# debugId=BAD14814BBB641A464756E2164756E21