@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.
Files changed (64) hide show
  1. package/dist/app.js +24 -3
  2. package/dist/app.js.map +3 -3
  3. package/dist/components/builtin.js +24 -3
  4. package/dist/components/builtin.js.map +3 -3
  5. package/dist/context.js +18 -1
  6. package/dist/context.js.map +2 -2
  7. package/dist/discovery.js +25 -7
  8. package/dist/discovery.js.map +4 -4
  9. package/dist/disposable.js +18 -1
  10. package/dist/disposable.js.map +2 -2
  11. package/dist/engine.browser.js +18 -1
  12. package/dist/engine.browser.js.map +3 -3
  13. package/dist/engine.js +18 -1
  14. package/dist/engine.js.map +3 -3
  15. package/dist/events.js +18 -1
  16. package/dist/events.js.map +2 -2
  17. package/dist/index.browser.js +259 -371
  18. package/dist/index.browser.js.map +8 -9
  19. package/dist/index.js +558 -647
  20. package/dist/index.js.map +12 -13
  21. package/dist/loader.js +18 -1
  22. package/dist/loader.js.map +2 -2
  23. package/dist/plugin.js +18 -1
  24. package/dist/plugin.js.map +2 -2
  25. package/dist/remote/client.js +18 -1
  26. package/dist/remote/client.js.map +3 -3
  27. package/dist/remote/index.js +353 -332
  28. package/dist/remote/index.js.map +8 -8
  29. package/dist/remote/server.js +234 -213
  30. package/dist/remote/server.js.map +7 -7
  31. package/dist/renderer.js +18 -1
  32. package/dist/renderer.js.map +3 -3
  33. package/dist/resolver.js +48 -4
  34. package/dist/resolver.js.map +3 -3
  35. package/dist/router.js +18 -1
  36. package/dist/router.js.map +2 -2
  37. package/dist/state.js +18 -1
  38. package/dist/state.js.map +2 -2
  39. package/package.json +7 -1
  40. package/src/app.ts +14 -2
  41. package/src/discovery.ts +3 -1
  42. package/src/engine.browser.ts +4 -32
  43. package/src/engine.ts +4 -32
  44. package/src/index.browser.ts +6 -4
  45. package/src/index.ts +6 -6
  46. package/src/managed-router.ts +195 -0
  47. package/src/module-registry.ts +76 -0
  48. package/src/remote/client.ts +1 -1
  49. package/src/remote/index.ts +2 -2
  50. package/src/remote/server.ts +1 -1
  51. package/src/remote/types.ts +1 -1
  52. package/src/renderer.ts +1 -1
  53. package/src/resolver.ts +56 -9
  54. package/src/types.ts +38 -0
  55. package/wasm-browser/README.md +7 -1
  56. package/wasm-browser/hypen_engine.d.ts +1 -0
  57. package/wasm-browser/hypen_engine.js +1 -0
  58. package/wasm-browser/hypen_engine_bg.wasm +0 -0
  59. package/wasm-browser/package.json +1 -1
  60. package/wasm-node/README.md +7 -1
  61. package/wasm-node/hypen_engine.d.ts +1 -0
  62. package/wasm-node/hypen_engine.js +1 -0
  63. package/wasm-node/hypen_engine_bg.wasm +0 -0
  64. package/wasm-node/package.json +1 -1
@@ -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) {
@@ -582,17 +400,216 @@ var init_result = __esm(() => {
582
400
  this.attempt = attempt;
583
401
  }
584
402
  };
585
- StateError = class StateError extends HypenError {
586
- path;
587
- constructor(message, path, cause) {
588
- super("STATE_ERROR", message, {
589
- context: { path },
590
- cause: cause instanceof Error ? cause : undefined
591
- });
592
- this.name = "StateError";
593
- 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);
594
594
  }
595
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
+ };
596
613
  });
597
614
 
598
615
  // src/app.ts
@@ -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
- 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);
703
724
  for (const [actionName, handler] of definition.handlers.onAction) {
704
- log3.debug(`Registering action handler: ${actionName} for module ${definition.name}`);
725
+ log2.debug(`Registering action handler: ${actionName} for module ${definition.name}`);
705
726
  this.engine.onAction(actionName, async (action) => {
706
- log3.debug(`Action handler fired: ${actionName}`, action);
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
- log3.debug(`Action handler completed: ${actionName}`);
749
+ log2.debug(`Action handler completed: ${actionName}`);
729
750
  }
730
751
  });
731
752
  }
@@ -780,7 +801,7 @@ class HypenModuleInstance {
780
801
  }
781
802
  }
782
803
  } catch (handlerError) {
783
- log3.error("Error in onError handler:", handlerError);
804
+ log2.error("Error in onError handler:", handlerError);
784
805
  }
785
806
  }
786
807
  if (this.globalContext) {
@@ -791,7 +812,7 @@ class HypenModuleInstance {
791
812
  context: eventContext
792
813
  });
793
814
  }
794
- 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);
795
816
  return false;
796
817
  }
797
818
  async callCreatedHandler() {
@@ -821,123 +842,18 @@ class HypenModuleInstance {
821
842
  Object.assign(this.state, patch);
822
843
  }
823
844
  }
824
- var log3, app;
845
+ var log2, app;
825
846
  var init_app = __esm(() => {
826
847
  init_result();
827
848
  init_state();
828
849
  init_logger();
829
- log3 = createLogger("ModuleInstance");
850
+ log2 = createLogger("ModuleInstance");
830
851
  app = new HypenApp;
831
852
  });
832
853
 
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
854
  // src/disposable.ts
939
855
  init_logger();
940
- var log4 = frameworkLoggers.lifecycle;
856
+ var log3 = frameworkLoggers.lifecycle;
941
857
  function isDisposable(obj) {
942
858
  return obj !== null && typeof obj === "object" && "dispose" in obj && typeof obj.dispose === "function";
943
859
  }
@@ -969,7 +885,7 @@ class DisposableStack {
969
885
  try {
970
886
  item.dispose();
971
887
  } catch (error) {
972
- log4.error("Error during dispose:", error);
888
+ log3.error("Error during dispose:", error);
973
889
  }
974
890
  }
975
891
  }
@@ -1060,7 +976,7 @@ function compositeDisposable(...disposables) {
1060
976
  try {
1061
977
  d.dispose();
1062
978
  } catch (error) {
1063
- log4.error("Error during dispose:", error);
979
+ log3.error("Error during dispose:", error);
1064
980
  }
1065
981
  }
1066
982
  }
@@ -1214,7 +1130,7 @@ var RetryPresets = {
1214
1130
 
1215
1131
  // src/remote/client.ts
1216
1132
  init_logger();
1217
- var log5 = frameworkLoggers.remote;
1133
+ var log4 = frameworkLoggers.remote;
1218
1134
 
1219
1135
  class RemoteEngine {
1220
1136
  ws = null;
@@ -1322,7 +1238,7 @@ class RemoteEngine {
1322
1238
  }
1323
1239
  dispatchAction(action, payload) {
1324
1240
  if (this.state !== "connected" || !this.ws) {
1325
- log5.warn("Cannot dispatch action: not connected");
1241
+ log4.warn("Cannot dispatch action: not connected");
1326
1242
  return;
1327
1243
  }
1328
1244
  const message = {
@@ -1395,7 +1311,7 @@ class RemoteEngine {
1395
1311
  break;
1396
1312
  }
1397
1313
  } catch (e) {
1398
- log5.error("Error handling remote message:", e);
1314
+ log4.error("Error handling remote message:", e);
1399
1315
  const error = e instanceof Error ? e : new Error(String(e));
1400
1316
  this.errorCallbacks.forEach((cb) => cb(error));
1401
1317
  }
@@ -1424,7 +1340,7 @@ class RemoteEngine {
1424
1340
  }
1425
1341
  handlePatch(message) {
1426
1342
  if (message.revision <= this.currentRevision) {
1427
- 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}`);
1428
1344
  return;
1429
1345
  }
1430
1346
  this.currentRevision = message.revision;
@@ -1450,16 +1366,121 @@ class RemoteEngine {
1450
1366
  maxDelayMs: 30000,
1451
1367
  jitter: 0.1,
1452
1368
  onRetry: (attempt, error) => {
1453
- log5.debug(`Reconnection attempt ${attempt}/${this.options.maxReconnectAttempts} failed: ${error.message}`);
1369
+ log4.debug(`Reconnection attempt ${attempt}/${this.options.maxReconnectAttempts} failed: ${error.message}`);
1454
1370
  }
1455
1371
  }).catch((error) => {
1456
- log5.error("Max reconnection attempts reached:", error.message);
1372
+ log4.error("Max reconnection attempts reached:", error.message);
1457
1373
  this.errorCallbacks.forEach((cb) => cb(new ConnectionError(this.url, error, this.options.maxReconnectAttempts)));
1458
1374
  });
1459
1375
  }, this.options.reconnectInterval);
1460
1376
  }
1461
1377
  }
1462
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
+
1463
1484
  // src/remote/server.ts
1464
1485
  init_app();
1465
1486
 
@@ -1966,4 +1987,4 @@ export {
1966
1987
  RemoteEngine
1967
1988
  };
1968
1989
 
1969
- //# debugId=69D6C15931380C3D64756E2164756E21
1990
+ //# debugId=BAD14814BBB641A464756E2164756E21