@hypen-space/core 0.4.13 → 0.4.15

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 (45) hide show
  1. package/dist/app.js +8 -82
  2. package/dist/app.js.map +2 -2
  3. package/dist/components/builtin.js +8 -82
  4. package/dist/components/builtin.js.map +2 -2
  5. package/dist/context.js +8 -3
  6. package/dist/context.js.map +2 -2
  7. package/dist/discovery.js +249 -249
  8. package/dist/discovery.js.map +4 -4
  9. package/dist/disposable.js +8 -3
  10. package/dist/disposable.js.map +2 -2
  11. package/dist/engine.browser.js +167 -131
  12. package/dist/engine.browser.js.map +2 -2
  13. package/dist/engine.js +1 -1
  14. package/dist/engine.js.map +1 -1
  15. package/dist/events.js +8 -3
  16. package/dist/events.js.map +2 -2
  17. package/dist/index.browser.js +278 -154
  18. package/dist/index.browser.js.map +6 -5
  19. package/dist/index.js +426 -433
  20. package/dist/index.js.map +9 -9
  21. package/dist/loader.js +1 -1
  22. package/dist/loader.js.map +1 -1
  23. package/dist/logger.js +8 -3
  24. package/dist/logger.js.map +2 -2
  25. package/dist/plugin.js +350 -5
  26. package/dist/plugin.js.map +4 -3
  27. package/dist/remote/client.js +8 -93
  28. package/dist/remote/client.js.map +2 -2
  29. package/dist/remote/index.js +480 -341
  30. package/dist/remote/index.js.map +6 -5
  31. package/dist/remote/server.js +480 -330
  32. package/dist/remote/server.js.map +6 -5
  33. package/dist/renderer.js +8 -3
  34. package/dist/renderer.js.map +2 -2
  35. package/dist/resolver.js +350 -5
  36. package/dist/resolver.js.map +4 -3
  37. package/dist/router.js +8 -3
  38. package/dist/router.js.map +2 -2
  39. package/dist/state.js +8 -3
  40. package/dist/state.js.map +2 -2
  41. package/package.json +1 -1
  42. package/wasm-browser/hypen_engine_bg.wasm +0 -0
  43. package/wasm-browser/package.json +1 -1
  44. package/wasm-node/hypen_engine_bg.wasm +0 -0
  45. package/wasm-node/package.json +1 -1
package/dist/index.js CHANGED
@@ -27,6 +27,176 @@ 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/result.ts
31
+ function Ok(value) {
32
+ return { ok: true, value };
33
+ }
34
+ function Err(error) {
35
+ return { ok: false, error };
36
+ }
37
+ function isOk(result) {
38
+ return result.ok;
39
+ }
40
+ function isErr(result) {
41
+ return !result.ok;
42
+ }
43
+ async function fromPromise(promise, mapError) {
44
+ try {
45
+ const value = await promise;
46
+ return Ok(value);
47
+ } catch (e) {
48
+ if (mapError) {
49
+ return Err(mapError(e));
50
+ }
51
+ return Err(e);
52
+ }
53
+ }
54
+ function fromTry(fn, mapError) {
55
+ try {
56
+ return Ok(fn());
57
+ } catch (e) {
58
+ if (mapError) {
59
+ return Err(mapError(e));
60
+ }
61
+ return Err(e);
62
+ }
63
+ }
64
+ function map(result, fn) {
65
+ if (result.ok) {
66
+ return Ok(fn(result.value));
67
+ }
68
+ return result;
69
+ }
70
+ function mapErr(result, fn) {
71
+ if (!result.ok) {
72
+ return Err(fn(result.error));
73
+ }
74
+ return result;
75
+ }
76
+ function flatMap(result, fn) {
77
+ if (result.ok) {
78
+ return fn(result.value);
79
+ }
80
+ return result;
81
+ }
82
+ function unwrap(result) {
83
+ if (result.ok) {
84
+ return result.value;
85
+ }
86
+ throw result.error;
87
+ }
88
+ function unwrapOr(result, defaultValue) {
89
+ if (result.ok) {
90
+ return result.value;
91
+ }
92
+ return defaultValue;
93
+ }
94
+ function unwrapOrElse(result, fn) {
95
+ if (result.ok) {
96
+ return result.value;
97
+ }
98
+ return fn(result.error);
99
+ }
100
+ function match(result, handlers) {
101
+ if (result.ok) {
102
+ return handlers.ok(result.value);
103
+ }
104
+ return handlers.err(result.error);
105
+ }
106
+ function all(results) {
107
+ const values = [];
108
+ for (const result of results) {
109
+ if (!result.ok) {
110
+ return result;
111
+ }
112
+ values.push(result.value);
113
+ }
114
+ return Ok(values);
115
+ }
116
+ function classifyEngineError(err) {
117
+ const message = err instanceof Error ? err.message : String(err);
118
+ if (message.startsWith("Parse error:")) {
119
+ return new ParseError(message);
120
+ }
121
+ if (message.startsWith("Invalid state:") || message.startsWith("Invalid state patch:")) {
122
+ return new StateError(message);
123
+ }
124
+ if (message.startsWith("Parent node not found:")) {
125
+ return new RenderError(message);
126
+ }
127
+ return new RenderError(message);
128
+ }
129
+ var HypenError, ActionError, ConnectionError, StateError, ParseError, RenderError;
130
+ var init_result = __esm(() => {
131
+ HypenError = class HypenError extends Error {
132
+ code;
133
+ context;
134
+ cause;
135
+ constructor(code, message, options) {
136
+ super(message);
137
+ this.name = "HypenError";
138
+ this.code = code;
139
+ this.context = options?.context;
140
+ this.cause = options?.cause;
141
+ Object.setPrototypeOf(this, new.target.prototype);
142
+ }
143
+ };
144
+ ActionError = class ActionError extends HypenError {
145
+ actionName;
146
+ constructor(actionName, cause) {
147
+ super("ACTION_ERROR", `Action handler "${actionName}" failed: ${cause instanceof Error ? cause.message : String(cause)}`, {
148
+ context: { actionName },
149
+ cause: cause instanceof Error ? cause : undefined
150
+ });
151
+ this.name = "ActionError";
152
+ this.actionName = actionName;
153
+ }
154
+ };
155
+ ConnectionError = class ConnectionError extends HypenError {
156
+ url;
157
+ attempt;
158
+ constructor(url, cause, attempt) {
159
+ super("CONNECTION_ERROR", `Connection to "${url}" failed${attempt ? ` (attempt ${attempt})` : ""}: ${cause instanceof Error ? cause.message : String(cause)}`, {
160
+ context: { url, attempt },
161
+ cause: cause instanceof Error ? cause : undefined
162
+ });
163
+ this.name = "ConnectionError";
164
+ this.url = url;
165
+ this.attempt = attempt;
166
+ }
167
+ };
168
+ StateError = class StateError extends HypenError {
169
+ path;
170
+ constructor(message, path, cause) {
171
+ super("STATE_ERROR", message, {
172
+ context: { path },
173
+ cause: cause instanceof Error ? cause : undefined
174
+ });
175
+ this.name = "StateError";
176
+ this.path = path;
177
+ }
178
+ };
179
+ ParseError = class ParseError extends HypenError {
180
+ source;
181
+ constructor(message, source, cause) {
182
+ super("PARSE_ERROR", message, {
183
+ context: { source },
184
+ cause: cause instanceof Error ? cause : undefined
185
+ });
186
+ this.name = "ParseError";
187
+ this.source = source;
188
+ }
189
+ };
190
+ RenderError = class RenderError extends HypenError {
191
+ constructor(message, cause) {
192
+ super("RENDER_ERROR", message, {
193
+ cause: cause instanceof Error ? cause : undefined
194
+ });
195
+ this.name = "RenderError";
196
+ }
197
+ };
198
+ });
199
+
30
200
  // src/state.ts
31
201
  function deepClone(obj) {
32
202
  if (obj === null || typeof obj !== "object") {
@@ -474,217 +644,47 @@ var init_logger = __esm(() => {
474
644
  };
475
645
  });
476
646
 
477
- // src/result.ts
478
- function Ok(value) {
479
- return { ok: true, value };
480
- }
481
- function Err(error) {
482
- return { ok: false, error };
483
- }
484
- function isOk(result) {
485
- return result.ok;
486
- }
487
- function isErr(result) {
488
- return !result.ok;
489
- }
490
- async function fromPromise(promise, mapError) {
491
- try {
492
- const value = await promise;
493
- return Ok(value);
494
- } catch (e) {
495
- if (mapError) {
496
- return Err(mapError(e));
497
- }
498
- return Err(e);
647
+ // src/app.ts
648
+ var exports_app = {};
649
+ __export(exports_app, {
650
+ app: () => app,
651
+ HypenModuleInstance: () => HypenModuleInstance,
652
+ HypenAppBuilder: () => HypenAppBuilder,
653
+ HypenApp: () => HypenApp
654
+ });
655
+
656
+ class HypenAppBuilder {
657
+ initialState;
658
+ options;
659
+ createdHandler;
660
+ actionHandlers = new Map;
661
+ destroyedHandler;
662
+ disconnectHandler;
663
+ reconnectHandler;
664
+ expireHandler;
665
+ errorHandler;
666
+ template;
667
+ _registry;
668
+ constructor(initialState, options, registry) {
669
+ this.initialState = initialState;
670
+ this.options = options || {};
671
+ this._registry = registry;
499
672
  }
500
- }
501
- function fromTry(fn, mapError) {
502
- try {
503
- return Ok(fn());
504
- } catch (e) {
505
- if (mapError) {
506
- return Err(mapError(e));
507
- }
508
- return Err(e);
673
+ onCreated(fn) {
674
+ this.createdHandler = fn;
675
+ return this;
509
676
  }
510
- }
511
- function map(result, fn) {
512
- if (result.ok) {
513
- return Ok(fn(result.value));
677
+ onAction(name, fn) {
678
+ this.actionHandlers.set(name, fn);
679
+ return this;
514
680
  }
515
- return result;
516
- }
517
- function mapErr(result, fn) {
518
- if (!result.ok) {
519
- return Err(fn(result.error));
681
+ onDestroyed(fn) {
682
+ this.destroyedHandler = fn;
683
+ return this;
520
684
  }
521
- return result;
522
- }
523
- function flatMap(result, fn) {
524
- if (result.ok) {
525
- return fn(result.value);
526
- }
527
- return result;
528
- }
529
- function unwrap(result) {
530
- if (result.ok) {
531
- return result.value;
532
- }
533
- throw result.error;
534
- }
535
- function unwrapOr(result, defaultValue) {
536
- if (result.ok) {
537
- return result.value;
538
- }
539
- return defaultValue;
540
- }
541
- function unwrapOrElse(result, fn) {
542
- if (result.ok) {
543
- return result.value;
544
- }
545
- return fn(result.error);
546
- }
547
- function match(result, handlers) {
548
- if (result.ok) {
549
- return handlers.ok(result.value);
550
- }
551
- return handlers.err(result.error);
552
- }
553
- function all(results) {
554
- const values = [];
555
- for (const result of results) {
556
- if (!result.ok) {
557
- return result;
558
- }
559
- values.push(result.value);
560
- }
561
- return Ok(values);
562
- }
563
- function classifyEngineError(err) {
564
- const message = err instanceof Error ? err.message : String(err);
565
- if (message.startsWith("Parse error:")) {
566
- return new ParseError(message);
567
- }
568
- if (message.startsWith("Invalid state:") || message.startsWith("Invalid state patch:")) {
569
- return new StateError(message);
570
- }
571
- if (message.startsWith("Parent node not found:")) {
572
- return new RenderError(message);
573
- }
574
- return new RenderError(message);
575
- }
576
- var HypenError, ActionError, ConnectionError, StateError, ParseError, RenderError;
577
- var init_result = __esm(() => {
578
- HypenError = class HypenError extends Error {
579
- code;
580
- context;
581
- cause;
582
- constructor(code, message, options) {
583
- super(message);
584
- this.name = "HypenError";
585
- this.code = code;
586
- this.context = options?.context;
587
- this.cause = options?.cause;
588
- Object.setPrototypeOf(this, new.target.prototype);
589
- }
590
- };
591
- ActionError = class ActionError extends HypenError {
592
- actionName;
593
- constructor(actionName, cause) {
594
- super("ACTION_ERROR", `Action handler "${actionName}" failed: ${cause instanceof Error ? cause.message : String(cause)}`, {
595
- context: { actionName },
596
- cause: cause instanceof Error ? cause : undefined
597
- });
598
- this.name = "ActionError";
599
- this.actionName = actionName;
600
- }
601
- };
602
- ConnectionError = class ConnectionError extends HypenError {
603
- url;
604
- attempt;
605
- constructor(url, cause, attempt) {
606
- super("CONNECTION_ERROR", `Connection to "${url}" failed${attempt ? ` (attempt ${attempt})` : ""}: ${cause instanceof Error ? cause.message : String(cause)}`, {
607
- context: { url, attempt },
608
- cause: cause instanceof Error ? cause : undefined
609
- });
610
- this.name = "ConnectionError";
611
- this.url = url;
612
- this.attempt = attempt;
613
- }
614
- };
615
- StateError = class StateError extends HypenError {
616
- path;
617
- constructor(message, path, cause) {
618
- super("STATE_ERROR", message, {
619
- context: { path },
620
- cause: cause instanceof Error ? cause : undefined
621
- });
622
- this.name = "StateError";
623
- this.path = path;
624
- }
625
- };
626
- ParseError = class ParseError extends HypenError {
627
- source;
628
- constructor(message, source, cause) {
629
- super("PARSE_ERROR", message, {
630
- context: { source },
631
- cause: cause instanceof Error ? cause : undefined
632
- });
633
- this.name = "ParseError";
634
- this.source = source;
635
- }
636
- };
637
- RenderError = class RenderError extends HypenError {
638
- constructor(message, cause) {
639
- super("RENDER_ERROR", message, {
640
- cause: cause instanceof Error ? cause : undefined
641
- });
642
- this.name = "RenderError";
643
- }
644
- };
645
- });
646
-
647
- // src/app.ts
648
- var exports_app = {};
649
- __export(exports_app, {
650
- app: () => app,
651
- HypenModuleInstance: () => HypenModuleInstance,
652
- HypenAppBuilder: () => HypenAppBuilder,
653
- HypenApp: () => HypenApp
654
- });
655
-
656
- class HypenAppBuilder {
657
- initialState;
658
- options;
659
- createdHandler;
660
- actionHandlers = new Map;
661
- destroyedHandler;
662
- disconnectHandler;
663
- reconnectHandler;
664
- expireHandler;
665
- errorHandler;
666
- template;
667
- _registry;
668
- constructor(initialState, options, registry) {
669
- this.initialState = initialState;
670
- this.options = options || {};
671
- this._registry = registry;
672
- }
673
- onCreated(fn) {
674
- this.createdHandler = fn;
675
- return this;
676
- }
677
- onAction(name, fn) {
678
- this.actionHandlers.set(name, fn);
679
- return this;
680
- }
681
- onDestroyed(fn) {
682
- this.destroyedHandler = fn;
683
- return this;
684
- }
685
- onDisconnect(fn) {
686
- this.disconnectHandler = fn;
687
- return this;
685
+ onDisconnect(fn) {
686
+ this.disconnectHandler = fn;
687
+ return this;
688
688
  }
689
689
  onReconnect(fn) {
690
690
  this.reconnectHandler = fn;
@@ -944,6 +944,60 @@ var init_app = __esm(() => {
944
944
  app = new HypenApp;
945
945
  });
946
946
 
947
+ // src/index.ts
948
+ init_app();
949
+
950
+ // src/hypen.ts
951
+ function createBindingProxy(root) {
952
+ const handler = {
953
+ get(_, prop) {
954
+ if (prop === Symbol.toPrimitive || prop === "toString" || prop === "valueOf") {
955
+ return () => `\${${root}}`;
956
+ }
957
+ if (typeof prop === "symbol") {
958
+ return;
959
+ }
960
+ if (prop === "toJSON") {
961
+ return () => `\${${root}}`;
962
+ }
963
+ return createBindingProxy(`${root}.${prop}`);
964
+ },
965
+ has() {
966
+ return true;
967
+ },
968
+ ownKeys() {
969
+ return [];
970
+ },
971
+ getOwnPropertyDescriptor() {
972
+ return {
973
+ configurable: true,
974
+ enumerable: true
975
+ };
976
+ }
977
+ };
978
+ return new Proxy({}, handler);
979
+ }
980
+ var state = createBindingProxy("state");
981
+ var item = createBindingProxy("item");
982
+ var index = {
983
+ [Symbol.toPrimitive]: () => "${index}",
984
+ toString: () => "${index}",
985
+ valueOf: () => "${index}",
986
+ toJSON: () => "${index}"
987
+ };
988
+ function hypen(strings, ...expressions) {
989
+ let result = strings[0];
990
+ for (let i = 0;i < expressions.length; i++) {
991
+ const expr = expressions[i];
992
+ result += String(expr);
993
+ result += strings[i + 1];
994
+ }
995
+ return result.trim();
996
+ }
997
+
998
+ // src/index.ts
999
+ init_state();
1000
+
947
1001
  // src/renderer.ts
948
1002
  init_logger();
949
1003
  var log3 = frameworkLoggers.renderer;
@@ -995,7 +1049,6 @@ class ConsoleRenderer {
995
1049
  console.groupEnd();
996
1050
  }
997
1051
  }
998
-
999
1052
  // src/router.ts
1000
1053
  init_state();
1001
1054
  init_logger();
@@ -1195,7 +1248,6 @@ class HypenRouter {
1195
1248
  return `${path}?${queryString}`;
1196
1249
  }
1197
1250
  }
1198
-
1199
1251
  // src/events.ts
1200
1252
  init_logger();
1201
1253
  var log5 = frameworkLoggers.events;
@@ -1261,7 +1313,6 @@ class TypedEventEmitter {
1261
1313
  function createEventEmitter() {
1262
1314
  return new TypedEventEmitter;
1263
1315
  }
1264
-
1265
1316
  // src/context.ts
1266
1317
  init_logger();
1267
1318
  var log6 = frameworkLoggers.context;
@@ -1305,11 +1356,11 @@ class HypenGlobalContext {
1305
1356
  return Array.from(this.modules.keys());
1306
1357
  }
1307
1358
  getGlobalState() {
1308
- const state = {};
1359
+ const state2 = {};
1309
1360
  this.modules.forEach((module, id) => {
1310
- state[id] = module.getState();
1361
+ state2[id] = module.getState();
1311
1362
  });
1312
- return state;
1363
+ return state2;
1313
1364
  }
1314
1365
  emit(event, payload) {
1315
1366
  const handlers = this.legacyEventBus.get(event);
@@ -1367,6 +1418,8 @@ class HypenGlobalContext {
1367
1418
  };
1368
1419
  }
1369
1420
  }
1421
+ // src/remote/client.ts
1422
+ init_result();
1370
1423
 
1371
1424
  // src/disposable.ts
1372
1425
  init_logger();
@@ -1398,9 +1451,9 @@ class DisposableStack {
1398
1451
  return;
1399
1452
  this.disposed = true;
1400
1453
  while (this.stack.length > 0) {
1401
- const item = this.stack.pop();
1454
+ const item2 = this.stack.pop();
1402
1455
  try {
1403
- item.dispose();
1456
+ item2.dispose();
1404
1457
  } catch (error) {
1405
1458
  log7.error("Error during dispose:", error);
1406
1459
  }
@@ -1516,9 +1569,6 @@ function usingSync(resource, fn) {
1516
1569
  }
1517
1570
  }
1518
1571
 
1519
- // src/remote/client.ts
1520
- init_result();
1521
-
1522
1572
  // src/retry.ts
1523
1573
  init_result();
1524
1574
  var DEFAULT_OPTIONS = {
@@ -1892,33 +1942,155 @@ class RemoteEngine {
1892
1942
  }, this.options.reconnectInterval);
1893
1943
  }
1894
1944
  }
1895
-
1896
- // src/resolver.ts
1897
- class ComponentResolver {
1898
- cache = new Map;
1899
- options;
1900
- moduleRegistry;
1901
- constructor(options = {}) {
1902
- this.options = {
1903
- baseDir: options.baseDir || process.cwd(),
1904
- cache: options.cache ?? true,
1905
- customFetch: options.customFetch || this.defaultFetch.bind(this),
1906
- moduleRegistry: options.moduleRegistry
1945
+ // src/remote/session.ts
1946
+ class SessionManager {
1947
+ activeSessions = new Map;
1948
+ pendingSessions = new Map;
1949
+ sessionConnections = new Map;
1950
+ config;
1951
+ constructor(config2 = {}) {
1952
+ this.config = {
1953
+ ttl: config2.ttl ?? 3600,
1954
+ concurrent: config2.concurrent ?? "kick-old",
1955
+ generateId: config2.generateId ?? (() => crypto.randomUUID())
1907
1956
  };
1908
- this.moduleRegistry = options.moduleRegistry;
1909
1957
  }
1910
- async resolve(importStmt) {
1911
- if (this.moduleRegistry) {
1912
- const names = importStmt.clause.type === "named" ? importStmt.clause.names : [importStmt.clause.name];
1913
- const allFound = names.every((name) => this.moduleRegistry.has(name));
1914
- if (allFound) {
1915
- const result = {};
1916
- for (const name of names) {
1917
- const def = this.moduleRegistry.get(name);
1918
- result[name] = {
1919
- module: def,
1920
- template: def?.template || ""
1921
- };
1958
+ getTtl() {
1959
+ return this.config.ttl;
1960
+ }
1961
+ getConcurrentPolicy() {
1962
+ return this.config.concurrent;
1963
+ }
1964
+ createSession(props) {
1965
+ const now = new Date;
1966
+ const session = {
1967
+ id: this.config.generateId(),
1968
+ ttl: this.config.ttl,
1969
+ createdAt: now,
1970
+ lastConnectedAt: now,
1971
+ props
1972
+ };
1973
+ this.activeSessions.set(session.id, session);
1974
+ return session;
1975
+ }
1976
+ getActiveSession(id) {
1977
+ return this.activeSessions.get(id) ?? null;
1978
+ }
1979
+ getPendingSession(id) {
1980
+ return this.pendingSessions.get(id) ?? null;
1981
+ }
1982
+ hasSession(id) {
1983
+ return this.activeSessions.has(id) || this.pendingSessions.has(id);
1984
+ }
1985
+ suspendSession(sessionId, savedState, onExpire) {
1986
+ const session = this.activeSessions.get(sessionId);
1987
+ if (!session)
1988
+ return;
1989
+ this.activeSessions.delete(sessionId);
1990
+ const expiryTimer = setTimeout(async () => {
1991
+ const pending = this.pendingSessions.get(sessionId);
1992
+ if (pending) {
1993
+ this.pendingSessions.delete(sessionId);
1994
+ await onExpire(pending.session);
1995
+ }
1996
+ }, session.ttl * 1000);
1997
+ this.pendingSessions.set(sessionId, {
1998
+ session,
1999
+ savedState,
2000
+ expiryTimer
2001
+ });
2002
+ }
2003
+ resumeSession(sessionId) {
2004
+ const pending = this.pendingSessions.get(sessionId);
2005
+ if (!pending)
2006
+ return null;
2007
+ clearTimeout(pending.expiryTimer);
2008
+ this.pendingSessions.delete(sessionId);
2009
+ pending.session.lastConnectedAt = new Date;
2010
+ this.activeSessions.set(sessionId, pending.session);
2011
+ return {
2012
+ session: pending.session,
2013
+ savedState: pending.savedState
2014
+ };
2015
+ }
2016
+ destroySession(sessionId) {
2017
+ this.activeSessions.delete(sessionId);
2018
+ const pending = this.pendingSessions.get(sessionId);
2019
+ if (pending) {
2020
+ clearTimeout(pending.expiryTimer);
2021
+ this.pendingSessions.delete(sessionId);
2022
+ }
2023
+ this.sessionConnections.delete(sessionId);
2024
+ }
2025
+ trackConnection(sessionId, ws) {
2026
+ let connections = this.sessionConnections.get(sessionId);
2027
+ if (!connections) {
2028
+ connections = new Set;
2029
+ this.sessionConnections.set(sessionId, connections);
2030
+ }
2031
+ connections.add(ws);
2032
+ }
2033
+ untrackConnection(sessionId, ws) {
2034
+ const connections = this.sessionConnections.get(sessionId);
2035
+ if (connections) {
2036
+ connections.delete(ws);
2037
+ if (connections.size === 0) {
2038
+ this.sessionConnections.delete(sessionId);
2039
+ }
2040
+ }
2041
+ }
2042
+ getConnections(sessionId) {
2043
+ return this.sessionConnections.get(sessionId);
2044
+ }
2045
+ getConnectionCount(sessionId) {
2046
+ return this.sessionConnections.get(sessionId)?.size ?? 0;
2047
+ }
2048
+ getStats() {
2049
+ let totalConnections = 0;
2050
+ for (const connections of this.sessionConnections.values()) {
2051
+ totalConnections += connections.size;
2052
+ }
2053
+ return {
2054
+ activeSessions: this.activeSessions.size,
2055
+ pendingSessions: this.pendingSessions.size,
2056
+ totalConnections
2057
+ };
2058
+ }
2059
+ destroy() {
2060
+ for (const pending of this.pendingSessions.values()) {
2061
+ clearTimeout(pending.expiryTimer);
2062
+ }
2063
+ this.activeSessions.clear();
2064
+ this.pendingSessions.clear();
2065
+ this.sessionConnections.clear();
2066
+ }
2067
+ }
2068
+ // src/resolver.ts
2069
+ class ComponentResolver {
2070
+ cache = new Map;
2071
+ options;
2072
+ moduleRegistry;
2073
+ constructor(options = {}) {
2074
+ this.options = {
2075
+ baseDir: options.baseDir || process.cwd(),
2076
+ cache: options.cache ?? true,
2077
+ customFetch: options.customFetch || this.defaultFetch.bind(this),
2078
+ moduleRegistry: options.moduleRegistry
2079
+ };
2080
+ this.moduleRegistry = options.moduleRegistry;
2081
+ }
2082
+ async resolve(importStmt) {
2083
+ if (this.moduleRegistry) {
2084
+ const names = importStmt.clause.type === "named" ? importStmt.clause.names : [importStmt.clause.name];
2085
+ const allFound = names.every((name) => this.moduleRegistry.has(name));
2086
+ if (allFound) {
2087
+ const result = {};
2088
+ for (const name of names) {
2089
+ const def = this.moduleRegistry.get(name);
2090
+ result[name] = {
2091
+ module: def,
2092
+ template: def?.template || ""
2093
+ };
1922
2094
  }
1923
2095
  return result;
1924
2096
  }
@@ -2013,7 +2185,6 @@ class ComponentResolver {
2013
2185
  return imports;
2014
2186
  }
2015
2187
  }
2016
-
2017
2188
  // src/components/builtin.ts
2018
2189
  init_app();
2019
2190
  init_logger();
@@ -2022,7 +2193,7 @@ var Router = app.defineState({
2022
2193
  currentPath: "/",
2023
2194
  matchedRoute: null,
2024
2195
  routeParams: {}
2025
- }, { name: "__Router" }).onCreated((state, context) => {
2196
+ }, { name: "__Router" }).onCreated((state2, context) => {
2026
2197
  if (!context) {
2027
2198
  log9.error("Requires global context");
2028
2199
  return;
@@ -2036,8 +2207,8 @@ var Router = app.defineState({
2036
2207
  const updateRouteVisibility = async (currentPath) => {
2037
2208
  const routeElements = document.querySelectorAll('[data-hypen-type="route"]');
2038
2209
  let matchFound = false;
2039
- for (let index = 0;index < routeElements.length; index++) {
2040
- const routeEl = routeElements[index];
2210
+ for (let index2 = 0;index2 < routeElements.length; index2++) {
2211
+ const routeEl = routeElements[index2];
2041
2212
  const htmlEl = routeEl;
2042
2213
  const routePath = htmlEl.dataset.routePath || "/";
2043
2214
  const isMatch = routePath === currentPath;
@@ -2061,11 +2232,11 @@ var Router = app.defineState({
2061
2232
  }
2062
2233
  };
2063
2234
  setTimeout(() => {
2064
- updateRouteVisibility(state.currentPath);
2235
+ updateRouteVisibility(state2.currentPath);
2065
2236
  }, 100);
2066
2237
  router.onNavigate((routeState) => {
2067
- state.currentPath = routeState.currentPath;
2068
- state.routeParams = routeState.params;
2238
+ state2.currentPath = routeState.currentPath;
2239
+ state2.routeParams = routeState.params;
2069
2240
  updateRouteVisibility(routeState.currentPath);
2070
2241
  });
2071
2242
  }).build();
@@ -2073,203 +2244,25 @@ var Route = app.defineState({}, { name: "__Route" }).build();
2073
2244
  var Link = app.defineState({
2074
2245
  to: "/",
2075
2246
  isActive: false
2076
- }, { name: "__Link" }).onAction("navigate", ({ state, context }) => {
2247
+ }, { name: "__Link" }).onAction("navigate", ({ state: state2, context }) => {
2077
2248
  const router = context?.router;
2078
2249
  if (!router) {
2079
2250
  log9.error("Link requires router context");
2080
2251
  return;
2081
2252
  }
2082
- const targetPath = state.to;
2253
+ const targetPath = state2.to;
2083
2254
  router.push(targetPath);
2084
- }).onCreated((state, context) => {
2255
+ }).onCreated((state2, context) => {
2085
2256
  if (!context)
2086
2257
  return;
2087
2258
  const router = context.router;
2088
2259
  if (router) {
2089
2260
  router.onNavigate((routeState) => {
2090
- state.isActive = routeState.currentPath === state.to;
2261
+ state2.isActive = routeState.currentPath === state2.to;
2091
2262
  });
2092
2263
  }
2093
2264
  }).build();
2094
2265
 
2095
- // src/index.ts
2096
- init_app();
2097
-
2098
- // src/hypen.ts
2099
- function createBindingProxy(root) {
2100
- const handler = {
2101
- get(_, prop) {
2102
- if (prop === Symbol.toPrimitive || prop === "toString" || prop === "valueOf") {
2103
- return () => `\${${root}}`;
2104
- }
2105
- if (typeof prop === "symbol") {
2106
- return;
2107
- }
2108
- if (prop === "toJSON") {
2109
- return () => `\${${root}}`;
2110
- }
2111
- return createBindingProxy(`${root}.${prop}`);
2112
- },
2113
- has() {
2114
- return true;
2115
- },
2116
- ownKeys() {
2117
- return [];
2118
- },
2119
- getOwnPropertyDescriptor() {
2120
- return {
2121
- configurable: true,
2122
- enumerable: true
2123
- };
2124
- }
2125
- };
2126
- return new Proxy({}, handler);
2127
- }
2128
- var state = createBindingProxy("state");
2129
- var item = createBindingProxy("item");
2130
- var index = {
2131
- [Symbol.toPrimitive]: () => "${index}",
2132
- toString: () => "${index}",
2133
- valueOf: () => "${index}",
2134
- toJSON: () => "${index}"
2135
- };
2136
- function hypen(strings, ...expressions) {
2137
- let result = strings[0];
2138
- for (let i = 0;i < expressions.length; i++) {
2139
- const expr = expressions[i];
2140
- result += String(expr);
2141
- result += strings[i + 1];
2142
- }
2143
- return result.trim();
2144
- }
2145
-
2146
- // src/index.ts
2147
- init_state();
2148
-
2149
- // src/remote/session.ts
2150
- class SessionManager {
2151
- activeSessions = new Map;
2152
- pendingSessions = new Map;
2153
- sessionConnections = new Map;
2154
- config;
2155
- constructor(config2 = {}) {
2156
- this.config = {
2157
- ttl: config2.ttl ?? 3600,
2158
- concurrent: config2.concurrent ?? "kick-old",
2159
- generateId: config2.generateId ?? (() => crypto.randomUUID())
2160
- };
2161
- }
2162
- getTtl() {
2163
- return this.config.ttl;
2164
- }
2165
- getConcurrentPolicy() {
2166
- return this.config.concurrent;
2167
- }
2168
- createSession(props) {
2169
- const now = new Date;
2170
- const session = {
2171
- id: this.config.generateId(),
2172
- ttl: this.config.ttl,
2173
- createdAt: now,
2174
- lastConnectedAt: now,
2175
- props
2176
- };
2177
- this.activeSessions.set(session.id, session);
2178
- return session;
2179
- }
2180
- getActiveSession(id) {
2181
- return this.activeSessions.get(id) ?? null;
2182
- }
2183
- getPendingSession(id) {
2184
- return this.pendingSessions.get(id) ?? null;
2185
- }
2186
- hasSession(id) {
2187
- return this.activeSessions.has(id) || this.pendingSessions.has(id);
2188
- }
2189
- suspendSession(sessionId, savedState, onExpire) {
2190
- const session = this.activeSessions.get(sessionId);
2191
- if (!session)
2192
- return;
2193
- this.activeSessions.delete(sessionId);
2194
- const expiryTimer = setTimeout(async () => {
2195
- const pending = this.pendingSessions.get(sessionId);
2196
- if (pending) {
2197
- this.pendingSessions.delete(sessionId);
2198
- await onExpire(pending.session);
2199
- }
2200
- }, session.ttl * 1000);
2201
- this.pendingSessions.set(sessionId, {
2202
- session,
2203
- savedState,
2204
- expiryTimer
2205
- });
2206
- }
2207
- resumeSession(sessionId) {
2208
- const pending = this.pendingSessions.get(sessionId);
2209
- if (!pending)
2210
- return null;
2211
- clearTimeout(pending.expiryTimer);
2212
- this.pendingSessions.delete(sessionId);
2213
- pending.session.lastConnectedAt = new Date;
2214
- this.activeSessions.set(sessionId, pending.session);
2215
- return {
2216
- session: pending.session,
2217
- savedState: pending.savedState
2218
- };
2219
- }
2220
- destroySession(sessionId) {
2221
- this.activeSessions.delete(sessionId);
2222
- const pending = this.pendingSessions.get(sessionId);
2223
- if (pending) {
2224
- clearTimeout(pending.expiryTimer);
2225
- this.pendingSessions.delete(sessionId);
2226
- }
2227
- this.sessionConnections.delete(sessionId);
2228
- }
2229
- trackConnection(sessionId, ws) {
2230
- let connections = this.sessionConnections.get(sessionId);
2231
- if (!connections) {
2232
- connections = new Set;
2233
- this.sessionConnections.set(sessionId, connections);
2234
- }
2235
- connections.add(ws);
2236
- }
2237
- untrackConnection(sessionId, ws) {
2238
- const connections = this.sessionConnections.get(sessionId);
2239
- if (connections) {
2240
- connections.delete(ws);
2241
- if (connections.size === 0) {
2242
- this.sessionConnections.delete(sessionId);
2243
- }
2244
- }
2245
- }
2246
- getConnections(sessionId) {
2247
- return this.sessionConnections.get(sessionId);
2248
- }
2249
- getConnectionCount(sessionId) {
2250
- return this.sessionConnections.get(sessionId)?.size ?? 0;
2251
- }
2252
- getStats() {
2253
- let totalConnections = 0;
2254
- for (const connections of this.sessionConnections.values()) {
2255
- totalConnections += connections.size;
2256
- }
2257
- return {
2258
- activeSessions: this.activeSessions.size,
2259
- pendingSessions: this.pendingSessions.size,
2260
- totalConnections
2261
- };
2262
- }
2263
- destroy() {
2264
- for (const pending of this.pendingSessions.values()) {
2265
- clearTimeout(pending.expiryTimer);
2266
- }
2267
- this.activeSessions.clear();
2268
- this.pendingSessions.clear();
2269
- this.sessionConnections.clear();
2270
- }
2271
- }
2272
-
2273
2266
  // src/index.ts
2274
2267
  init_result();
2275
2268
  init_logger();
@@ -2354,4 +2347,4 @@ export {
2354
2347
  ActionError
2355
2348
  };
2356
2349
 
2357
- //# debugId=6B890301380275E464756E2164756E21
2350
+ //# debugId=7C35E17ECF9C051B64756E2164756E21