@hypen-space/core 0.4.3 → 0.4.11

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 (72) hide show
  1. package/README.md +1 -1
  2. package/dist/app.d.ts +79 -22
  3. package/dist/app.js +248 -155
  4. package/dist/app.js.map +5 -5
  5. package/dist/components/builtin.js +251 -158
  6. package/dist/components/builtin.js.map +6 -6
  7. package/dist/context.js +1 -1
  8. package/dist/context.js.map +1 -1
  9. package/dist/discovery.d.ts +1 -1
  10. package/dist/discovery.js +249 -156
  11. package/dist/discovery.js.map +6 -6
  12. package/dist/disposable.js +1 -1
  13. package/dist/disposable.js.map +1 -1
  14. package/dist/engine.browser.d.ts +6 -0
  15. package/dist/engine.browser.js +192 -5
  16. package/dist/engine.browser.js.map +5 -4
  17. package/dist/engine.d.ts +6 -0
  18. package/dist/engine.js +192 -5
  19. package/dist/engine.js.map +5 -4
  20. package/dist/events.js +1 -1
  21. package/dist/events.js.map +1 -1
  22. package/dist/index.browser.d.ts +1 -1
  23. package/dist/index.browser.js +248 -155
  24. package/dist/index.browser.js.map +6 -6
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.js +254 -158
  27. package/dist/index.js.map +7 -7
  28. package/dist/loader.js +1 -1
  29. package/dist/loader.js.map +1 -1
  30. package/dist/logger.js +245 -0
  31. package/dist/logger.js.map +10 -0
  32. package/dist/managed-router.d.ts +3 -4
  33. package/dist/plugin.js +1 -1
  34. package/dist/plugin.js.map +1 -1
  35. package/dist/remote/client.js +34 -2
  36. package/dist/remote/client.js.map +3 -3
  37. package/dist/remote/index.js +609 -163
  38. package/dist/remote/index.js.map +8 -7
  39. package/dist/remote/server.d.ts +46 -15
  40. package/dist/remote/server.js +609 -163
  41. package/dist/remote/server.js.map +8 -7
  42. package/dist/renderer.js +1 -1
  43. package/dist/renderer.js.map +1 -1
  44. package/dist/result.d.ts +18 -0
  45. package/dist/router.js +1 -1
  46. package/dist/router.js.map +1 -1
  47. package/dist/types.d.ts +1 -1
  48. package/dist/types.js +2 -0
  49. package/dist/types.js.map +9 -0
  50. package/package.json +1 -1
  51. package/src/app.ts +162 -41
  52. package/src/components/builtin.ts +3 -4
  53. package/src/discovery.ts +2 -2
  54. package/src/engine.browser.ts +27 -4
  55. package/src/engine.ts +27 -4
  56. package/src/index.browser.ts +0 -2
  57. package/src/index.ts +3 -2
  58. package/src/managed-router.ts +5 -6
  59. package/src/remote/server.ts +116 -21
  60. package/src/result.ts +48 -0
  61. package/src/types.ts +1 -1
  62. package/wasm-browser/hypen_engine.d.ts +3 -3
  63. package/wasm-browser/hypen_engine.js +73 -66
  64. package/wasm-browser/hypen_engine_bg.wasm +0 -0
  65. package/wasm-browser/hypen_engine_bg.wasm.d.ts +3 -3
  66. package/wasm-browser/package.json +1 -1
  67. package/wasm-node/hypen_engine.js +74 -66
  68. package/wasm-node/hypen_engine_bg.wasm +0 -0
  69. package/wasm-node/hypen_engine_bg.wasm.d.ts +3 -3
  70. package/wasm-node/package.json +1 -1
  71. package/dist/module-registry.d.ts +0 -42
  72. package/src/module-registry.ts +0 -76
@@ -275,144 +275,6 @@ var init_state = __esm(() => {
275
275
  RAW_TARGET = Symbol.for("hypen.rawTarget");
276
276
  });
277
277
 
278
- // src/result.ts
279
- function Ok(value) {
280
- return { ok: true, value };
281
- }
282
- function Err(error) {
283
- return { ok: false, error };
284
- }
285
- function isOk(result) {
286
- return result.ok;
287
- }
288
- function isErr(result) {
289
- return !result.ok;
290
- }
291
- async function fromPromise(promise, mapError) {
292
- try {
293
- const value = await promise;
294
- return Ok(value);
295
- } catch (e) {
296
- if (mapError) {
297
- return Err(mapError(e));
298
- }
299
- return Err(e);
300
- }
301
- }
302
- function fromTry(fn, mapError) {
303
- try {
304
- return Ok(fn());
305
- } catch (e) {
306
- if (mapError) {
307
- return Err(mapError(e));
308
- }
309
- return Err(e);
310
- }
311
- }
312
- function map(result, fn) {
313
- if (result.ok) {
314
- return Ok(fn(result.value));
315
- }
316
- return result;
317
- }
318
- function mapErr(result, fn) {
319
- if (!result.ok) {
320
- return Err(fn(result.error));
321
- }
322
- return result;
323
- }
324
- function flatMap(result, fn) {
325
- if (result.ok) {
326
- return fn(result.value);
327
- }
328
- return result;
329
- }
330
- function unwrap(result) {
331
- if (result.ok) {
332
- return result.value;
333
- }
334
- throw result.error;
335
- }
336
- function unwrapOr(result, defaultValue) {
337
- if (result.ok) {
338
- return result.value;
339
- }
340
- return defaultValue;
341
- }
342
- function unwrapOrElse(result, fn) {
343
- if (result.ok) {
344
- return result.value;
345
- }
346
- return fn(result.error);
347
- }
348
- function match(result, handlers) {
349
- if (result.ok) {
350
- return handlers.ok(result.value);
351
- }
352
- return handlers.err(result.error);
353
- }
354
- function all(results) {
355
- const values = [];
356
- for (const result of results) {
357
- if (!result.ok) {
358
- return result;
359
- }
360
- values.push(result.value);
361
- }
362
- return Ok(values);
363
- }
364
- var HypenError, ActionError, ConnectionError, StateError;
365
- var init_result = __esm(() => {
366
- HypenError = class HypenError extends Error {
367
- code;
368
- context;
369
- cause;
370
- constructor(code, message, options) {
371
- super(message);
372
- this.name = "HypenError";
373
- this.code = code;
374
- this.context = options?.context;
375
- this.cause = options?.cause;
376
- Object.setPrototypeOf(this, new.target.prototype);
377
- }
378
- };
379
- ActionError = class ActionError extends HypenError {
380
- actionName;
381
- constructor(actionName, cause) {
382
- super("ACTION_ERROR", `Action handler "${actionName}" failed: ${cause instanceof Error ? cause.message : String(cause)}`, {
383
- context: { actionName },
384
- cause: cause instanceof Error ? cause : undefined
385
- });
386
- this.name = "ActionError";
387
- this.actionName = actionName;
388
- }
389
- };
390
- ConnectionError = class ConnectionError extends HypenError {
391
- url;
392
- attempt;
393
- constructor(url, cause, attempt) {
394
- super("CONNECTION_ERROR", `Connection to "${url}" failed${attempt ? ` (attempt ${attempt})` : ""}: ${cause instanceof Error ? cause.message : String(cause)}`, {
395
- context: { url, attempt },
396
- cause: cause instanceof Error ? cause : undefined
397
- });
398
- this.name = "ConnectionError";
399
- this.url = url;
400
- this.attempt = attempt;
401
- }
402
- };
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
278
  // src/logger.ts
417
279
  function isProduction() {
418
280
  if (typeof process !== "undefined" && process.env) {
@@ -612,6 +474,176 @@ var init_logger = __esm(() => {
612
474
  };
613
475
  });
614
476
 
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);
499
+ }
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);
509
+ }
510
+ }
511
+ function map(result, fn) {
512
+ if (result.ok) {
513
+ return Ok(fn(result.value));
514
+ }
515
+ return result;
516
+ }
517
+ function mapErr(result, fn) {
518
+ if (!result.ok) {
519
+ return Err(fn(result.error));
520
+ }
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
+
615
647
  // src/app.ts
616
648
  var exports_app = {};
617
649
  __export(exports_app, {
@@ -632,9 +664,11 @@ class HypenAppBuilder {
632
664
  expireHandler;
633
665
  errorHandler;
634
666
  template;
635
- constructor(initialState, options) {
667
+ _registry;
668
+ constructor(initialState, options, registry) {
636
669
  this.initialState = initialState;
637
670
  this.options = options || {};
671
+ this._registry = registry;
638
672
  }
639
673
  onCreated(fn) {
640
674
  this.createdHandler = fn;
@@ -670,7 +704,7 @@ class HypenAppBuilder {
670
704
  }
671
705
  build() {
672
706
  const stateKeys = this.initialState !== null && typeof this.initialState === "object" ? Object.keys(this.initialState) : [];
673
- return {
707
+ const definition = {
674
708
  name: this.options.name,
675
709
  actions: Array.from(this.actionHandlers.keys()),
676
710
  stateKeys,
@@ -688,12 +722,46 @@ class HypenAppBuilder {
688
722
  onError: this.errorHandler
689
723
  }
690
724
  };
725
+ if (this.options.name && this._registry) {
726
+ this._registry.set(this.options.name, definition);
727
+ }
728
+ return definition;
691
729
  }
692
730
  }
693
731
 
694
732
  class HypenApp {
733
+ _registry = new Map;
695
734
  defineState(initial, options) {
696
- return new HypenAppBuilder(initial, options);
735
+ return new HypenAppBuilder(initial, options, this._registry);
736
+ }
737
+ module(name) {
738
+ const registry = this._registry;
739
+ return {
740
+ defineState: (initial, options) => {
741
+ return new HypenAppBuilder(initial, { ...options, name }, registry);
742
+ }
743
+ };
744
+ }
745
+ get(name) {
746
+ return this._registry.get(name);
747
+ }
748
+ has(name) {
749
+ return this._registry.has(name);
750
+ }
751
+ get components() {
752
+ return this._registry;
753
+ }
754
+ getNames() {
755
+ return Array.from(this._registry.keys());
756
+ }
757
+ get size() {
758
+ return this._registry.size;
759
+ }
760
+ unregister(name) {
761
+ this._registry.delete(name);
762
+ }
763
+ clear() {
764
+ this._registry.clear();
697
765
  }
698
766
  }
699
767
 
@@ -702,13 +770,13 @@ class HypenModuleInstance {
702
770
  definition;
703
771
  state;
704
772
  isDestroyed = false;
705
- routerContext;
773
+ router;
706
774
  globalContext;
707
775
  stateChangeCallbacks = [];
708
- constructor(engine, definition, routerContext, globalContext) {
776
+ constructor(engine, definition, router, globalContext) {
709
777
  this.engine = engine;
710
778
  this.definition = definition;
711
- this.routerContext = routerContext;
779
+ this.router = router ?? null;
712
780
  this.globalContext = globalContext;
713
781
  const statePrefix = (definition.name || "").toLowerCase();
714
782
  this.state = createObservableState(definition.initialState, {
@@ -730,14 +798,10 @@ class HypenModuleInstance {
730
798
  payload: action.payload,
731
799
  sender: action.sender
732
800
  };
733
- const next = {
734
- router: this.routerContext?.root || null
735
- };
736
801
  const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
737
802
  const result = await this.executeAction(actionName, handler, {
738
803
  action: actionCtx,
739
804
  state: this.state,
740
- next,
741
805
  context
742
806
  });
743
807
  if (!result.ok) {
@@ -750,6 +814,21 @@ class HypenModuleInstance {
750
814
  }
751
815
  });
752
816
  }
817
+ this.engine.onAction("__hypen_bind", (action) => {
818
+ const payload = action.payload;
819
+ if (!payload?.path)
820
+ return;
821
+ const segments = payload.path.split(".");
822
+ let target = this.state;
823
+ for (let i = 0;i < segments.length - 1; i++) {
824
+ const seg = segments[i];
825
+ target = target?.[seg];
826
+ if (target == null)
827
+ return;
828
+ }
829
+ const lastSeg = segments[segments.length - 1];
830
+ target[lastSeg] = payload.value;
831
+ });
753
832
  this.callCreatedHandler();
754
833
  }
755
834
  createGlobalContextAPI() {
@@ -763,11 +842,9 @@ class HypenModuleInstance {
763
842
  getModuleIds: () => ctx.getModuleIds(),
764
843
  getGlobalState: () => ctx.getGlobalState(),
765
844
  emit: (event, payload) => ctx.emit(event, payload),
766
- on: (event, handler) => ctx.on(event, handler)
845
+ on: (event, handler) => ctx.on(event, handler),
846
+ router: this.router
767
847
  };
768
- if (ctx.__router) {
769
- api.__router = ctx.__router;
770
- }
771
848
  if (ctx.__hypenEngine) {
772
849
  api.__hypenEngine = ctx.__hypenEngine;
773
850
  }
@@ -818,7 +895,15 @@ class HypenModuleInstance {
818
895
  async callCreatedHandler() {
819
896
  if (this.definition.handlers.onCreated) {
820
897
  const context = this.globalContext ? this.createGlobalContextAPI() : undefined;
821
- await this.definition.handlers.onCreated(this.state, context);
898
+ try {
899
+ await this.definition.handlers.onCreated(this.state, context);
900
+ } catch (e) {
901
+ const error = e instanceof HypenError ? e : new ActionError("onCreated", e);
902
+ const shouldRethrow = await this.handleError(error, { lifecycle: "created" });
903
+ if (shouldRethrow) {
904
+ throw error;
905
+ }
906
+ }
822
907
  }
823
908
  }
824
909
  onStateChange(callback) {
@@ -828,7 +913,15 @@ class HypenModuleInstance {
828
913
  if (this.isDestroyed)
829
914
  return;
830
915
  if (this.definition.handlers.onDestroyed) {
831
- await this.definition.handlers.onDestroyed(this.state);
916
+ try {
917
+ await this.definition.handlers.onDestroyed(this.state);
918
+ } catch (e) {
919
+ const error = e instanceof HypenError ? e : new ActionError("onDestroyed", e);
920
+ const shouldRethrow = await this.handleError(error, { lifecycle: "destroyed" });
921
+ if (shouldRethrow) {
922
+ throw error;
923
+ }
924
+ }
832
925
  }
833
926
  this.isDestroyed = true;
834
927
  }
@@ -1841,4 +1934,4 @@ export {
1841
1934
  BaseRenderer
1842
1935
  };
1843
1936
 
1844
- //# debugId=9E4501F170B224D064756E2164756E21
1937
+ //# debugId=46120A0CB1E9405A64756E2164756E21