@vived/host 5.5.0 → 5.6.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 (113) hide show
  1. package/dist/cjs/BoundaryLog/Adapters/boundaryLogAdapter.js +24 -0
  2. package/dist/cjs/BoundaryLog/Adapters/boundaryLogAdapter.js.map +1 -0
  3. package/dist/cjs/BoundaryLog/Adapters/index.js +18 -0
  4. package/dist/cjs/BoundaryLog/Adapters/index.js.map +1 -0
  5. package/dist/cjs/BoundaryLog/Controllers/clearBoundaryLog.js +15 -0
  6. package/dist/cjs/BoundaryLog/Controllers/clearBoundaryLog.js.map +1 -0
  7. package/dist/cjs/BoundaryLog/Controllers/index.js +18 -0
  8. package/dist/cjs/BoundaryLog/Controllers/index.js.map +1 -0
  9. package/dist/cjs/BoundaryLog/Entities/BoundaryLogEntity.js +45 -0
  10. package/dist/cjs/BoundaryLog/Entities/BoundaryLogEntity.js.map +1 -0
  11. package/dist/cjs/BoundaryLog/Entities/index.js +19 -0
  12. package/dist/cjs/BoundaryLog/Entities/index.js.map +1 -0
  13. package/dist/cjs/BoundaryLog/Entities/snapshotPayload.js +62 -0
  14. package/dist/cjs/BoundaryLog/Entities/snapshotPayload.js.map +1 -0
  15. package/dist/cjs/BoundaryLog/Factories/BoundaryLogFactory.js +62 -0
  16. package/dist/cjs/BoundaryLog/Factories/BoundaryLogFactory.js.map +1 -0
  17. package/dist/cjs/BoundaryLog/Factories/index.js +18 -0
  18. package/dist/cjs/BoundaryLog/Factories/index.js.map +1 -0
  19. package/dist/cjs/BoundaryLog/Mocks/BoundaryLogPMMock.js +16 -0
  20. package/dist/cjs/BoundaryLog/Mocks/BoundaryLogPMMock.js.map +1 -0
  21. package/dist/cjs/BoundaryLog/Mocks/index.js +18 -0
  22. package/dist/cjs/BoundaryLog/Mocks/index.js.map +1 -0
  23. package/dist/cjs/BoundaryLog/PMs/BoundaryLogPM.js +56 -0
  24. package/dist/cjs/BoundaryLog/PMs/BoundaryLogPM.js.map +1 -0
  25. package/dist/cjs/BoundaryLog/PMs/index.js +18 -0
  26. package/dist/cjs/BoundaryLog/PMs/index.js.map +1 -0
  27. package/dist/cjs/BoundaryLog/index.js +23 -0
  28. package/dist/cjs/BoundaryLog/index.js.map +1 -0
  29. package/dist/cjs/Dialog/Entities/DialogQueue.js +36 -21
  30. package/dist/cjs/Dialog/Entities/DialogQueue.js.map +1 -1
  31. package/dist/cjs/Dispatcher/Entities/HostDispatchEntity.js +17 -4
  32. package/dist/cjs/Dispatcher/Entities/HostDispatchEntity.js.map +1 -1
  33. package/dist/cjs/Dispatcher/Mocks/MockHostDispatcher.js +1 -0
  34. package/dist/cjs/Dispatcher/Mocks/MockHostDispatcher.js.map +1 -1
  35. package/dist/cjs/Handler/Entities/HostHandler.js +17 -0
  36. package/dist/cjs/Handler/Entities/HostHandler.js.map +1 -1
  37. package/dist/cjs/index.js +1 -0
  38. package/dist/cjs/index.js.map +1 -1
  39. package/dist/esm/BoundaryLog/Adapters/boundaryLogAdapter.js +21 -0
  40. package/dist/esm/BoundaryLog/Adapters/boundaryLogAdapter.js.map +1 -0
  41. package/dist/esm/BoundaryLog/Adapters/index.js +2 -0
  42. package/dist/esm/BoundaryLog/Adapters/index.js.map +1 -0
  43. package/dist/esm/BoundaryLog/Controllers/clearBoundaryLog.js +12 -0
  44. package/dist/esm/BoundaryLog/Controllers/clearBoundaryLog.js.map +1 -0
  45. package/dist/esm/BoundaryLog/Controllers/index.js +2 -0
  46. package/dist/esm/BoundaryLog/Controllers/index.js.map +1 -0
  47. package/dist/esm/BoundaryLog/Entities/BoundaryLogEntity.js +40 -0
  48. package/dist/esm/BoundaryLog/Entities/BoundaryLogEntity.js.map +1 -0
  49. package/dist/esm/BoundaryLog/Entities/index.js +3 -0
  50. package/dist/esm/BoundaryLog/Entities/index.js.map +1 -0
  51. package/dist/esm/BoundaryLog/Entities/snapshotPayload.js +59 -0
  52. package/dist/esm/BoundaryLog/Entities/snapshotPayload.js.map +1 -0
  53. package/dist/esm/BoundaryLog/Factories/BoundaryLogFactory.js +57 -0
  54. package/dist/esm/BoundaryLog/Factories/BoundaryLogFactory.js.map +1 -0
  55. package/dist/esm/BoundaryLog/Factories/index.js +2 -0
  56. package/dist/esm/BoundaryLog/Factories/index.js.map +1 -0
  57. package/dist/esm/BoundaryLog/Mocks/BoundaryLogPMMock.js +11 -0
  58. package/dist/esm/BoundaryLog/Mocks/BoundaryLogPMMock.js.map +1 -0
  59. package/dist/esm/BoundaryLog/Mocks/index.js +2 -0
  60. package/dist/esm/BoundaryLog/Mocks/index.js.map +1 -0
  61. package/dist/esm/BoundaryLog/PMs/BoundaryLogPM.js +51 -0
  62. package/dist/esm/BoundaryLog/PMs/BoundaryLogPM.js.map +1 -0
  63. package/dist/esm/BoundaryLog/PMs/index.js +2 -0
  64. package/dist/esm/BoundaryLog/PMs/index.js.map +1 -0
  65. package/dist/esm/BoundaryLog/index.js +7 -0
  66. package/dist/esm/BoundaryLog/index.js.map +1 -0
  67. package/dist/esm/Dialog/Entities/DialogQueue.js +36 -21
  68. package/dist/esm/Dialog/Entities/DialogQueue.js.map +1 -1
  69. package/dist/esm/Dispatcher/Entities/HostDispatchEntity.js +17 -4
  70. package/dist/esm/Dispatcher/Entities/HostDispatchEntity.js.map +1 -1
  71. package/dist/esm/Dispatcher/Mocks/MockHostDispatcher.js +1 -0
  72. package/dist/esm/Dispatcher/Mocks/MockHostDispatcher.js.map +1 -1
  73. package/dist/esm/Handler/Entities/HostHandler.js +17 -0
  74. package/dist/esm/Handler/Entities/HostHandler.js.map +1 -1
  75. package/dist/esm/index.js +1 -0
  76. package/dist/esm/index.js.map +1 -1
  77. package/dist/types/BoundaryLog/Adapters/boundaryLogAdapter.d.ts +4 -0
  78. package/dist/types/BoundaryLog/Adapters/boundaryLogAdapter.d.ts.map +1 -0
  79. package/dist/types/BoundaryLog/Adapters/index.d.ts +2 -0
  80. package/dist/types/BoundaryLog/Adapters/index.d.ts.map +1 -0
  81. package/dist/types/BoundaryLog/Controllers/clearBoundaryLog.d.ts +4 -0
  82. package/dist/types/BoundaryLog/Controllers/clearBoundaryLog.d.ts.map +1 -0
  83. package/dist/types/BoundaryLog/Controllers/index.d.ts +2 -0
  84. package/dist/types/BoundaryLog/Controllers/index.d.ts.map +1 -0
  85. package/dist/types/BoundaryLog/Entities/BoundaryLogEntity.d.ts +37 -0
  86. package/dist/types/BoundaryLog/Entities/BoundaryLogEntity.d.ts.map +1 -0
  87. package/dist/types/BoundaryLog/Entities/index.d.ts +3 -0
  88. package/dist/types/BoundaryLog/Entities/index.d.ts.map +1 -0
  89. package/dist/types/BoundaryLog/Entities/snapshotPayload.d.ts +16 -0
  90. package/dist/types/BoundaryLog/Entities/snapshotPayload.d.ts.map +1 -0
  91. package/dist/types/BoundaryLog/Factories/BoundaryLogFactory.d.ts +17 -0
  92. package/dist/types/BoundaryLog/Factories/BoundaryLogFactory.d.ts.map +1 -0
  93. package/dist/types/BoundaryLog/Factories/index.d.ts +2 -0
  94. package/dist/types/BoundaryLog/Factories/index.d.ts.map +1 -0
  95. package/dist/types/BoundaryLog/Mocks/BoundaryLogPMMock.d.ts +8 -0
  96. package/dist/types/BoundaryLog/Mocks/BoundaryLogPMMock.d.ts.map +1 -0
  97. package/dist/types/BoundaryLog/Mocks/index.d.ts +2 -0
  98. package/dist/types/BoundaryLog/Mocks/index.d.ts.map +1 -0
  99. package/dist/types/BoundaryLog/PMs/BoundaryLogPM.d.ts +18 -0
  100. package/dist/types/BoundaryLog/PMs/BoundaryLogPM.d.ts.map +1 -0
  101. package/dist/types/BoundaryLog/PMs/index.d.ts +2 -0
  102. package/dist/types/BoundaryLog/PMs/index.d.ts.map +1 -0
  103. package/dist/types/BoundaryLog/index.d.ts +7 -0
  104. package/dist/types/BoundaryLog/index.d.ts.map +1 -0
  105. package/dist/types/Dispatcher/Entities/HostDispatchEntity.d.ts +17 -0
  106. package/dist/types/Dispatcher/Entities/HostDispatchEntity.d.ts.map +1 -1
  107. package/dist/types/Dispatcher/Mocks/MockHostDispatcher.d.ts +1 -0
  108. package/dist/types/Dispatcher/Mocks/MockHostDispatcher.d.ts.map +1 -1
  109. package/dist/types/Handler/Entities/HostHandler.d.ts +18 -1
  110. package/dist/types/Handler/Entities/HostHandler.d.ts.map +1 -1
  111. package/dist/types/index.d.ts +1 -0
  112. package/dist/types/index.d.ts.map +1 -1
  113. package/package.json +1 -1
@@ -19,36 +19,51 @@ class DialogRepoImp extends DialogQueue {
19
19
  this.dialogQueue = [];
20
20
  this.submitDialog = (dialog) => {
21
21
  this.dialogQueue.push(dialog);
22
- if (this.activeDialog === dialog) {
23
- dialog.isOpen = true;
24
- }
25
- dialog.addChangeObserver(this.notifyOnChange);
22
+ dialog.addChangeObserver(this.onDialogChange);
23
+ this.openActiveDialog();
26
24
  this.notifyOnChange();
27
25
  };
28
26
  this.activeDialogHasClosed = () => {
29
27
  const currentActiveDialog = this.activeDialog;
30
- if (currentActiveDialog !== null) {
31
- currentActiveDialog.removeChangeObserver(this.notifyOnChange);
32
- this.filterOutClosedDialogs();
33
- this.dialogQueue.splice(0, 1);
34
- const newActiveDialog = this.activeDialog;
35
- if (newActiveDialog !== null) {
36
- newActiveDialog.isOpen = true;
37
- }
28
+ if (currentActiveDialog === null)
29
+ return;
30
+ // Dismissal comes via two routes: a dialog's own close() (which sets
31
+ // hasBeenClosed) or the host's backdrop/escape path (this method). Mark the
32
+ // active dialog closed here so both routes converge on the same advance.
33
+ currentActiveDialog.hasBeenClosed = true;
34
+ this.advanceQueue();
35
+ };
36
+ /**
37
+ * Observes every queued dialog. When the active dialog closes itself (e.g.
38
+ * via its own close button), advance the queue so the next dialog surfaces;
39
+ * otherwise just forward the change to the queue's own observers.
40
+ */
41
+ this.onDialogChange = () => {
42
+ const currentActiveDialog = this.activeDialog;
43
+ if (currentActiveDialog !== null && currentActiveDialog.hasBeenClosed) {
44
+ this.advanceQueue();
45
+ }
46
+ else {
38
47
  this.notifyOnChange();
39
48
  }
40
49
  };
41
- this.filterOutClosedDialogs = () => {
42
- const dialogsToKeep = [];
43
- this.dialogQueue.forEach((dialog) => {
44
- if (!dialog.hasBeenClosed) {
45
- dialogsToKeep.push(dialog);
46
- }
47
- else {
48
- dialog.removeChangeObserver(this.notifyOnChange);
50
+ /** Drop every closed dialog, then open whatever is now the active dialog. */
51
+ this.advanceQueue = () => {
52
+ this.dialogQueue = this.dialogQueue.filter((dialog) => {
53
+ if (dialog.hasBeenClosed) {
54
+ dialog.removeChangeObserver(this.onDialogChange);
55
+ return false;
49
56
  }
57
+ return true;
50
58
  });
51
- this.dialogQueue = dialogsToKeep;
59
+ this.openActiveDialog();
60
+ this.notifyOnChange();
61
+ };
62
+ this.openActiveDialog = () => {
63
+ const active = this.activeDialog;
64
+ if (active !== null && !active.isOpen) {
65
+ active.isOpen = true;
66
+ }
52
67
  };
53
68
  this.appObjects.registerSingleton(this);
54
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DialogQueue.js","sourceRoot":"","sources":["../../../../src/Dialog/Entities/DialogQueue.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EAEf,qBAAqB,EACtB,MAAM,aAAa,CAAC;AAErB,MAAM,OAAgB,MAAO,SAAQ,eAAe;CAKnD;AAED,MAAM,OAAgB,WAAY,SAAQ,eAAe;IAOvD,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,qBAAqB,CAAc,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;;AARM,gBAAI,GAAG,aAAa,CAAC;AAW9B,MAAM,UAAU,eAAe,CAAC,SAAoB;IAClD,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,aAAc,SAAQ,WAAW;IAGrC,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClE,CAAC;IA6CD,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAlD7B,gBAAW,GAAa,EAAE,CAAC;QAMnC,iBAAY,GAAG,CAAC,MAAc,EAAQ,EAAE;YACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE9B,IAAI,IAAI,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC;gBACjC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YACvB,CAAC;YAED,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAE9C,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,CAAC;QAEF,0BAAqB,GAAG,GAAS,EAAE;YACjC,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY,CAAC;YAC9C,IAAI,mBAAmB,KAAK,IAAI,EAAE,CAAC;gBACjC,mBAAmB,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAE9D,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAE9B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9B,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC;gBAC1C,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;oBAC7B,eAAe,CAAC,MAAM,GAAG,IAAI,CAAC;gBAChC,CAAC;gBAED,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QAEM,2BAAsB,GAAG,GAAG,EAAE;YACpC,MAAM,aAAa,GAAa,EAAE,CAAC;YAEnC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBAClC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;oBAC1B,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC;QACnC,CAAC,CAAC;QAIA,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import {\n AppObject,\n AppObjectEntity,\n AppObjectRepo,\n getSingletonComponent\n} from \"@vived/core\";\n\nexport abstract class Dialog extends AppObjectEntity {\n abstract dialogType: string;\n abstract preventOutsideDismiss: boolean;\n abstract isOpen: boolean;\n abstract hasBeenClosed: boolean;\n}\n\nexport abstract class DialogQueue extends AppObjectEntity {\n static type = \"DialogQueue\";\n\n abstract get activeDialog(): Dialog | null;\n abstract submitDialog(dialog: Dialog): void;\n abstract activeDialogHasClosed(): void;\n\n static get(appObjects: AppObjectRepo) {\n return getSingletonComponent<DialogQueue>(DialogQueue.type, appObjects);\n }\n}\n\nexport function makeDialogQueue(appObject: AppObject): DialogQueue {\n return new DialogRepoImp(appObject);\n}\n\nclass DialogRepoImp extends DialogQueue {\n private dialogQueue: Dialog[] = [];\n\n get activeDialog(): Dialog | null {\n return this.dialogQueue.length > 0 ? this.dialogQueue[0] : null;\n }\n\n submitDialog = (dialog: Dialog): void => {\n this.dialogQueue.push(dialog);\n\n if (this.activeDialog === dialog) {\n dialog.isOpen = true;\n }\n\n dialog.addChangeObserver(this.notifyOnChange);\n\n this.notifyOnChange();\n };\n\n activeDialogHasClosed = (): void => {\n const currentActiveDialog = this.activeDialog;\n if (currentActiveDialog !== null) {\n currentActiveDialog.removeChangeObserver(this.notifyOnChange);\n\n this.filterOutClosedDialogs();\n\n this.dialogQueue.splice(0, 1);\n const newActiveDialog = this.activeDialog;\n if (newActiveDialog !== null) {\n newActiveDialog.isOpen = true;\n }\n\n this.notifyOnChange();\n }\n };\n\n private filterOutClosedDialogs = () => {\n const dialogsToKeep: Dialog[] = [];\n\n this.dialogQueue.forEach((dialog) => {\n if (!dialog.hasBeenClosed) {\n dialogsToKeep.push(dialog);\n } else {\n dialog.removeChangeObserver(this.notifyOnChange);\n }\n });\n\n this.dialogQueue = dialogsToKeep;\n };\n\n constructor(appObject: AppObject) {\n super(appObject, DialogQueue.type);\n this.appObjects.registerSingleton(this);\n }\n}\n"]}
1
+ {"version":3,"file":"DialogQueue.js","sourceRoot":"","sources":["../../../../src/Dialog/Entities/DialogQueue.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EAEf,qBAAqB,EACtB,MAAM,aAAa,CAAC;AAErB,MAAM,OAAgB,MAAO,SAAQ,eAAe;CAKnD;AAED,MAAM,OAAgB,WAAY,SAAQ,eAAe;IAOvD,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,qBAAqB,CAAc,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;;AARM,gBAAI,GAAG,aAAa,CAAC;AAW9B,MAAM,UAAU,eAAe,CAAC,SAAoB;IAClD,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,aAAc,SAAQ,WAAW;IAGrC,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClE,CAAC;IAyDD,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QA9D7B,gBAAW,GAAa,EAAE,CAAC;QAMnC,iBAAY,GAAG,CAAC,MAAc,EAAQ,EAAE;YACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE9B,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAE9C,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,CAAC;QAEF,0BAAqB,GAAG,GAAS,EAAE;YACjC,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY,CAAC;YAC9C,IAAI,mBAAmB,KAAK,IAAI;gBAAE,OAAO;YAEzC,qEAAqE;YACrE,4EAA4E;YAC5E,yEAAyE;YACzE,mBAAmB,CAAC,aAAa,GAAG,IAAI,CAAC;YACzC,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC;QAEF;;;;WAIG;QACK,mBAAc,GAAG,GAAS,EAAE;YAClC,MAAM,mBAAmB,GAAG,IAAI,CAAC,YAAY,CAAC;YAC9C,IAAI,mBAAmB,KAAK,IAAI,IAAI,mBAAmB,CAAC,aAAa,EAAE,CAAC;gBACtE,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QAEF,6EAA6E;QACrE,iBAAY,GAAG,GAAS,EAAE;YAChC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;gBACpD,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;oBACzB,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;oBACjD,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,CAAC,CAAC;QAEM,qBAAgB,GAAG,GAAS,EAAE;YACpC,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC;YACjC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACtC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YACvB,CAAC;QACH,CAAC,CAAC;QAIA,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;CACF","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntity,\r\n AppObjectRepo,\r\n getSingletonComponent\r\n} from \"@vived/core\";\r\n\r\nexport abstract class Dialog extends AppObjectEntity {\r\n abstract dialogType: string;\r\n abstract preventOutsideDismiss: boolean;\r\n abstract isOpen: boolean;\r\n abstract hasBeenClosed: boolean;\r\n}\r\n\r\nexport abstract class DialogQueue extends AppObjectEntity {\r\n static type = \"DialogQueue\";\r\n\r\n abstract get activeDialog(): Dialog | null;\r\n abstract submitDialog(dialog: Dialog): void;\r\n abstract activeDialogHasClosed(): void;\r\n\r\n static get(appObjects: AppObjectRepo) {\r\n return getSingletonComponent<DialogQueue>(DialogQueue.type, appObjects);\r\n }\r\n}\r\n\r\nexport function makeDialogQueue(appObject: AppObject): DialogQueue {\r\n return new DialogRepoImp(appObject);\r\n}\r\n\r\nclass DialogRepoImp extends DialogQueue {\r\n private dialogQueue: Dialog[] = [];\r\n\r\n get activeDialog(): Dialog | null {\r\n return this.dialogQueue.length > 0 ? this.dialogQueue[0] : null;\r\n }\r\n\r\n submitDialog = (dialog: Dialog): void => {\r\n this.dialogQueue.push(dialog);\r\n\r\n dialog.addChangeObserver(this.onDialogChange);\r\n\r\n this.openActiveDialog();\r\n this.notifyOnChange();\r\n };\r\n\r\n activeDialogHasClosed = (): void => {\r\n const currentActiveDialog = this.activeDialog;\r\n if (currentActiveDialog === null) return;\r\n\r\n // Dismissal comes via two routes: a dialog's own close() (which sets\r\n // hasBeenClosed) or the host's backdrop/escape path (this method). Mark the\r\n // active dialog closed here so both routes converge on the same advance.\r\n currentActiveDialog.hasBeenClosed = true;\r\n this.advanceQueue();\r\n };\r\n\r\n /**\r\n * Observes every queued dialog. When the active dialog closes itself (e.g.\r\n * via its own close button), advance the queue so the next dialog surfaces;\r\n * otherwise just forward the change to the queue's own observers.\r\n */\r\n private onDialogChange = (): void => {\r\n const currentActiveDialog = this.activeDialog;\r\n if (currentActiveDialog !== null && currentActiveDialog.hasBeenClosed) {\r\n this.advanceQueue();\r\n } else {\r\n this.notifyOnChange();\r\n }\r\n };\r\n\r\n /** Drop every closed dialog, then open whatever is now the active dialog. */\r\n private advanceQueue = (): void => {\r\n this.dialogQueue = this.dialogQueue.filter((dialog) => {\r\n if (dialog.hasBeenClosed) {\r\n dialog.removeChangeObserver(this.onDialogChange);\r\n return false;\r\n }\r\n return true;\r\n });\r\n\r\n this.openActiveDialog();\r\n this.notifyOnChange();\r\n };\r\n\r\n private openActiveDialog = (): void => {\r\n const active = this.activeDialog;\r\n if (active !== null && !active.isOpen) {\r\n active.isOpen = true;\r\n }\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, DialogQueue.type);\r\n this.appObjects.registerSingleton(this);\r\n }\r\n}\r\n"]}
@@ -61,23 +61,36 @@ class HostDispatchEntityImp extends HostDispatchEntity {
61
61
  this.setupPayloadVersions = (payloadVersion) => {
62
62
  this.appPayloadVersions = payloadVersion;
63
63
  };
64
+ /**
65
+ * Notify the passive observer, if any. Wrapped so a throwing or slow observer
66
+ * can never alter, delay, or fail the Request's delivery (ADR-0002).
67
+ */
68
+ this.notifyObserver = (request, outcome) => {
69
+ if (!this.requestObserver)
70
+ return;
71
+ try {
72
+ this.requestObserver(request, outcome);
73
+ }
74
+ catch {
75
+ // Passive: an observer failure must never affect dispatch.
76
+ }
77
+ };
64
78
  this.dispatch = (request) => {
65
79
  if (!this.appHandler) {
66
80
  this.error("No app handler has been registered");
81
+ this.notifyObserver(request, "no-app-handler");
67
82
  return;
68
83
  }
69
84
  try {
70
85
  this.appHandler(request);
86
+ this.notifyObserver(request, "delivered");
71
87
  }
72
88
  catch (e) {
73
89
  this.warn(e.message);
90
+ this.notifyObserver(request, "threw");
74
91
  }
75
92
  };
76
93
  this.formRequestAndDispatch = (type, version, payload) => {
77
- if (!this.appHandler) {
78
- this.error("No app handler has been registered");
79
- return;
80
- }
81
94
  const request = {
82
95
  type,
83
96
  version,
@@ -1 +1 @@
1
- {"version":3,"file":"HostDispatchEntity.js","sourceRoot":"","sources":["../../../../src/Dispatcher/Entities/HostDispatchEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import { AppObject, AppObjectEntity, AppObjectRepo } from \"@vived/core\";\nimport { Handler, Request } from \"@vived/core\";\n\nexport abstract class HostDispatchEntity extends AppObjectEntity {\n static readonly type = \"HostDispatchEntity\";\n\n abstract appHandlerVersion: number;\n abstract getRequestPayloadVersion(requestType: string): number | undefined;\n abstract registerAppHandler: (appHandler: Handler) => void;\n abstract clearAppHandler: () => void;\n abstract dispatch: (request: Request) => void;\n abstract formRequestAndDispatch: (\n type: string,\n version: number,\n payload?: object | undefined\n ) => void;\n\n static get(appObject: AppObject): HostDispatchEntity | undefined {\n const component = appObject.getComponent<HostDispatchEntity>(\n HostDispatchEntity.type\n );\n if (!component) {\n appObject.appObjectRepo.submitWarning(\n \"AssetEntity.get\",\n \"Unable to find HostDispatchEntity on app object \" + appObject.id\n );\n }\n return component;\n }\n\n static getByID(\n id: string,\n appObjects: AppObjectRepo\n ): HostDispatchEntity | undefined {\n const appObject = appObjects.get(id);\n if (!appObject) {\n appObjects.submitWarning(\n \"AssetEntity.getByID\",\n \"Unable to find app object \" + id\n );\n return;\n }\n return HostDispatchEntity.get(appObject);\n }\n}\n\nexport function makeHostDispatchEntity(\n appObject: AppObject\n): HostDispatchEntity {\n return new HostDispatchEntityImp(appObject);\n}\n\nclass HostDispatchEntityImp extends HostDispatchEntity {\n private appHandler?: Handler;\n\n private _appHandlerVersion = 0;\n public get appHandlerVersion() {\n return this._appHandlerVersion;\n }\n\n private appPayloadVersions = new Map<string, number>();\n\n registerAppHandler = (appHandler: Handler) => {\n this.appHandler = appHandler;\n this.getAppHandlerVersion();\n };\n\n clearAppHandler = () => {\n this.appHandler = undefined;\n };\n\n private getAppHandlerVersion() {\n const type = \"GET_APP_HANDLER_VERSION\";\n const payload = { callback: this.setupVersion };\n\n try {\n this.formRequestAndDispatch(type, 1, payload);\n } catch {\n // All good. this is probably an older app\n }\n }\n\n getRequestPayloadVersion = (requestType: string): number | undefined => {\n return this.appPayloadVersions.get(requestType);\n };\n\n private setupVersion = (version: number) => {\n // Apps before app package version 2.27 will not reach this\n this._appHandlerVersion = version;\n this.getPayloadVersions();\n };\n\n private getPayloadVersions = () => {\n const type = \"GET_APP_PAYLOAD_VERSION\";\n const payload = { callback: this.setupPayloadVersions };\n this.formRequestAndDispatch(type, 2, payload);\n };\n\n private setupPayloadVersions = (payloadVersion: Map<string, number>) => {\n this.appPayloadVersions = payloadVersion;\n };\n\n dispatch = (request: Request) => {\n if (!this.appHandler) {\n this.error(\"No app handler has been registered\");\n return;\n }\n\n try {\n this.appHandler(request);\n } catch (e) {\n this.warn((e as Error).message);\n }\n };\n\n formRequestAndDispatch = (\n type: string,\n version: number,\n payload?: object | undefined\n ) => {\n if (!this.appHandler) {\n this.error(\"No app handler has been registered\");\n return;\n }\n\n const request: Request = {\n type,\n version,\n payload\n };\n\n this.dispatch(request);\n };\n\n constructor(appObject: AppObject) {\n super(appObject, HostDispatchEntity.type);\n }\n}\n"]}
1
+ {"version":3,"file":"HostDispatchEntity.js","sourceRoot":"","sources":["../../../../src/Dispatcher/Entities/HostDispatchEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,eAAe,EAAiB,MAAM,aAAa,CAAC;AAoBxE,MAAM,OAAgB,kBAAmB,SAAQ,eAAe;IAoB9D,MAAM,CAAC,GAAG,CAAC,SAAoB;QAC7B,MAAM,SAAS,GAAG,SAAS,CAAC,YAAY,CACtC,kBAAkB,CAAC,IAAI,CACxB,CAAC;QACF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS,CAAC,aAAa,CAAC,aAAa,CACnC,iBAAiB,EACjB,kDAAkD,GAAG,SAAS,CAAC,EAAE,CAClE,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,OAAO,CACZ,EAAU,EACV,UAAyB;QAEzB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,UAAU,CAAC,aAAa,CACtB,qBAAqB,EACrB,4BAA4B,GAAG,EAAE,CAClC,CAAC;YACF,OAAO;QACT,CAAC;QACD,OAAO,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3C,CAAC;;AA7Ce,uBAAI,GAAG,oBAAoB,CAAC;AAgD9C,MAAM,UAAU,sBAAsB,CACpC,SAAoB;IAEpB,OAAO,IAAI,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,qBAAsB,SAAQ,kBAAkB;IAIpD,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAaO,oBAAoB;QAC1B,MAAM,IAAI,GAAG,yBAAyB,CAAC;QACvC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;QAEhD,IAAI,CAAC;YACH,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,0CAA0C;QAC5C,CAAC;IACH,CAAC;IAmED,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;QA7FpC,uBAAkB,GAAG,CAAC,CAAC;QAKvB,uBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;QAEvD,uBAAkB,GAAG,CAAC,UAAmB,EAAE,EAAE;YAC3C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC7B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC9B,CAAC,CAAC;QAEF,oBAAe,GAAG,GAAG,EAAE;YACrB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC9B,CAAC,CAAC;QAaF,6BAAwB,GAAG,CAAC,WAAmB,EAAsB,EAAE;YACrE,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC,CAAC;QAEM,iBAAY,GAAG,CAAC,OAAe,EAAE,EAAE;YACzC,2DAA2D;YAC3D,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC;YAClC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,CAAC;QAEM,uBAAkB,GAAG,GAAG,EAAE;YAChC,MAAM,IAAI,GAAG,yBAAyB,CAAC;YACvC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,oBAAoB,EAAE,CAAC;YACxD,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC,CAAC;QAEM,yBAAoB,GAAG,CAAC,cAAmC,EAAE,EAAE;YACrE,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC;QAC3C,CAAC,CAAC;QAIF;;;WAGG;QACK,mBAAc,GAAG,CAAC,OAAgB,EAAE,OAAwB,EAAE,EAAE;YACtE,IAAI,CAAC,IAAI,CAAC,eAAe;gBAAE,OAAO;YAClC,IAAI,CAAC;gBACH,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,2DAA2D;YAC7D,CAAC;QACH,CAAC,CAAC;QAEF,aAAQ,GAAG,CAAC,OAAgB,EAAE,EAAE;YAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;gBACjD,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;gBAC/C,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACzB,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAC5C,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;gBAChC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACxC,CAAC;QACH,CAAC,CAAC;QAEF,2BAAsB,GAAG,CACvB,IAAY,EACZ,OAAe,EACf,OAA4B,EAC5B,EAAE;YACF,MAAM,OAAO,GAAY;gBACvB,IAAI;gBACJ,OAAO;gBACP,OAAO;aACR,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC,CAAC;IAIF,CAAC;CACF","sourcesContent":["import { AppObject, AppObjectEntity, AppObjectRepo } from \"@vived/core\";\r\nimport { Handler, Request } from \"@vived/core\";\r\n\r\n/**\r\n * The outcome of an outbound Dispatch, as seen at the dispatch chokepoint:\r\n * \"delivered\" (the app handler ran), \"no-app-handler\" (nothing registered to\r\n * receive it), or \"threw\" (the app handler raised).\r\n */\r\nexport type DispatchOutcome = \"delivered\" | \"no-app-handler\" | \"threw\";\r\n\r\n/**\r\n * Passive observer of outbound Dispatches. Notified after each Request is\r\n * dispatched, with the outcome. Purely observational — see the passivity\r\n * contract in ADR-0002: an observer must never alter, delay, or fail delivery.\r\n */\r\nexport type DispatchObserver = (\r\n request: Request,\r\n outcome: DispatchOutcome\r\n) => void;\r\n\r\nexport abstract class HostDispatchEntity extends AppObjectEntity {\r\n static readonly type = \"HostDispatchEntity\";\r\n\r\n abstract appHandlerVersion: number;\r\n abstract getRequestPayloadVersion(requestType: string): number | undefined;\r\n abstract registerAppHandler: (appHandler: Handler) => void;\r\n abstract clearAppHandler: () => void;\r\n abstract dispatch: (request: Request) => void;\r\n abstract formRequestAndDispatch: (\r\n type: string,\r\n version: number,\r\n payload?: object | undefined\r\n ) => void;\r\n\r\n /**\r\n * Optional passive observer of outbound Dispatches (ADR-0002). Unset by\r\n * default, so production hosts pay nothing and behave exactly as before.\r\n */\r\n abstract requestObserver?: DispatchObserver;\r\n\r\n static get(appObject: AppObject): HostDispatchEntity | undefined {\r\n const component = appObject.getComponent<HostDispatchEntity>(\r\n HostDispatchEntity.type\r\n );\r\n if (!component) {\r\n appObject.appObjectRepo.submitWarning(\r\n \"AssetEntity.get\",\r\n \"Unable to find HostDispatchEntity on app object \" + appObject.id\r\n );\r\n }\r\n return component;\r\n }\r\n\r\n static getByID(\r\n id: string,\r\n appObjects: AppObjectRepo\r\n ): HostDispatchEntity | undefined {\r\n const appObject = appObjects.get(id);\r\n if (!appObject) {\r\n appObjects.submitWarning(\r\n \"AssetEntity.getByID\",\r\n \"Unable to find app object \" + id\r\n );\r\n return;\r\n }\r\n return HostDispatchEntity.get(appObject);\r\n }\r\n}\r\n\r\nexport function makeHostDispatchEntity(\r\n appObject: AppObject\r\n): HostDispatchEntity {\r\n return new HostDispatchEntityImp(appObject);\r\n}\r\n\r\nclass HostDispatchEntityImp extends HostDispatchEntity {\r\n private appHandler?: Handler;\r\n\r\n private _appHandlerVersion = 0;\r\n public get appHandlerVersion() {\r\n return this._appHandlerVersion;\r\n }\r\n\r\n private appPayloadVersions = new Map<string, number>();\r\n\r\n registerAppHandler = (appHandler: Handler) => {\r\n this.appHandler = appHandler;\r\n this.getAppHandlerVersion();\r\n };\r\n\r\n clearAppHandler = () => {\r\n this.appHandler = undefined;\r\n };\r\n\r\n private getAppHandlerVersion() {\r\n const type = \"GET_APP_HANDLER_VERSION\";\r\n const payload = { callback: this.setupVersion };\r\n\r\n try {\r\n this.formRequestAndDispatch(type, 1, payload);\r\n } catch {\r\n // All good. this is probably an older app\r\n }\r\n }\r\n\r\n getRequestPayloadVersion = (requestType: string): number | undefined => {\r\n return this.appPayloadVersions.get(requestType);\r\n };\r\n\r\n private setupVersion = (version: number) => {\r\n // Apps before app package version 2.27 will not reach this\r\n this._appHandlerVersion = version;\r\n this.getPayloadVersions();\r\n };\r\n\r\n private getPayloadVersions = () => {\r\n const type = \"GET_APP_PAYLOAD_VERSION\";\r\n const payload = { callback: this.setupPayloadVersions };\r\n this.formRequestAndDispatch(type, 2, payload);\r\n };\r\n\r\n private setupPayloadVersions = (payloadVersion: Map<string, number>) => {\r\n this.appPayloadVersions = payloadVersion;\r\n };\r\n\r\n requestObserver?: DispatchObserver;\r\n\r\n /**\r\n * Notify the passive observer, if any. Wrapped so a throwing or slow observer\r\n * can never alter, delay, or fail the Request's delivery (ADR-0002).\r\n */\r\n private notifyObserver = (request: Request, outcome: DispatchOutcome) => {\r\n if (!this.requestObserver) return;\r\n try {\r\n this.requestObserver(request, outcome);\r\n } catch {\r\n // Passive: an observer failure must never affect dispatch.\r\n }\r\n };\r\n\r\n dispatch = (request: Request) => {\r\n if (!this.appHandler) {\r\n this.error(\"No app handler has been registered\");\r\n this.notifyObserver(request, \"no-app-handler\");\r\n return;\r\n }\r\n\r\n try {\r\n this.appHandler(request);\r\n this.notifyObserver(request, \"delivered\");\r\n } catch (e) {\r\n this.warn((e as Error).message);\r\n this.notifyObserver(request, \"threw\");\r\n }\r\n };\r\n\r\n formRequestAndDispatch = (\r\n type: string,\r\n version: number,\r\n payload?: object | undefined\r\n ) => {\r\n const request: Request = {\r\n type,\r\n version,\r\n payload\r\n };\r\n\r\n this.dispatch(request);\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, HostDispatchEntity.type);\r\n }\r\n}\r\n"]}
@@ -8,6 +8,7 @@ export class MockHostDispatchEntity extends HostDispatchEntity {
8
8
  this.registerAppHandler = jest.fn();
9
9
  this.dispatch = jest.fn();
10
10
  this.formRequestAndDispatch = jest.fn();
11
+ this.requestObserver = undefined;
11
12
  }
12
13
  }
13
14
  //# sourceMappingURL=MockHostDispatcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MockHostDispatcher.js","sourceRoot":"","sources":["../../../../src/Dispatcher/Mocks/MockHostDispatcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,OAAO,sBAAuB,SAAQ,kBAAkB;IAQ5D,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAR5C,oBAAe,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC5B,sBAAiB,GAAG,CAAC,CAAC;QACtB,6BAAwB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACrC,uBAAkB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC/B,aAAQ,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACrB,2BAAsB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAInC,CAAC;CACF","sourcesContent":["import { AppObject } from \"@vived/core\";\nimport { HostDispatchEntity } from \"../Entities\";\n\nexport class MockHostDispatchEntity extends HostDispatchEntity {\n clearAppHandler = jest.fn();\n appHandlerVersion = 1;\n getRequestPayloadVersion = jest.fn();\n registerAppHandler = jest.fn();\n dispatch = jest.fn();\n formRequestAndDispatch = jest.fn();\n\n constructor(appObject: AppObject) {\n super(appObject, HostDispatchEntity.type);\n }\n}\n"]}
1
+ {"version":3,"file":"MockHostDispatcher.js","sourceRoot":"","sources":["../../../../src/Dispatcher/Mocks/MockHostDispatcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,OAAO,sBAAuB,SAAQ,kBAAkB;IAS5D,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAT5C,oBAAe,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC5B,sBAAiB,GAAG,CAAC,CAAC;QACtB,6BAAwB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACrC,uBAAkB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC/B,aAAQ,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACrB,2BAAsB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QACnC,oBAAe,GAAG,SAAS,CAAC;IAI5B,CAAC;CACF","sourcesContent":["import { AppObject } from \"@vived/core\";\r\nimport { HostDispatchEntity } from \"../Entities\";\r\n\r\nexport class MockHostDispatchEntity extends HostDispatchEntity {\r\n clearAppHandler = jest.fn();\r\n appHandlerVersion = 1;\r\n getRequestPayloadVersion = jest.fn();\r\n registerAppHandler = jest.fn();\r\n dispatch = jest.fn();\r\n formRequestAndDispatch = jest.fn();\r\n requestObserver = undefined;\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, HostDispatchEntity.type);\r\n }\r\n}\r\n"]}
@@ -12,17 +12,34 @@ class RequestHandlerImp extends HostHandlerEntity {
12
12
  constructor(appObj) {
13
13
  super(appObj, HostHandlerEntity.type);
14
14
  this.handlers = new Map();
15
+ /**
16
+ * Notify the passive observer, if any. Wrapped so a throwing or slow observer
17
+ * can never alter, delay, or fail the Request (ADR-0002).
18
+ */
19
+ this.notifyObserver = (request, outcome) => {
20
+ if (!this.requestObserver)
21
+ return;
22
+ try {
23
+ this.requestObserver(request, outcome);
24
+ }
25
+ catch {
26
+ // Passive: an observer failure must never affect handling.
27
+ }
28
+ };
15
29
  this.handler = (request) => {
16
30
  const handler = this.handlers.get(request.type);
17
31
  if (!handler) {
18
32
  this.warn(`Unsupported request type received: ${request.type}`);
33
+ this.notifyObserver(request, "unsupported");
19
34
  return;
20
35
  }
21
36
  try {
22
37
  handler.handleRequest(request.version, request.payload);
38
+ this.notifyObserver(request, "handled");
23
39
  }
24
40
  catch (e) {
25
41
  this.warn(`${e}`);
42
+ this.notifyObserver(request, "threw");
26
43
  }
27
44
  };
28
45
  this.registerRequestHandler = (handler) => {
@@ -1 +1 @@
1
- {"version":3,"file":"HostHandler.js","sourceRoot":"","sources":["../../../../src/Handler/Entities/HostHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,eAAe,EAAE,MAAM,aAAa,CAAC;AAQzD,MAAM,OAAgB,iBAAkB,SAAQ,eAAe;IAG7D,MAAM,CAAC,GAAG,CAAC,SAAoB;QAC7B,OAAO,SAAS,CAAC,YAAY,CAAoB,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC;;AAJM,sBAAI,GAAG,mBAAmB,CAAC;AAUpC,MAAM,UAAU,qBAAqB,CAAC,SAAoB;IACxD,OAAO,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,iBAAkB,SAAQ,iBAAiB;IA4B/C,YAAY,MAAiB;QAC3B,KAAK,CAAC,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;QA5BhC,aAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;QAErD,YAAO,GAAY,CAAC,OAAgB,EAAQ,EAAE;YAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAEhD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC,IAAI,CAAC,sCAAsC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBAChE,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1D,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC;QAEF,2BAAsB,GAAG,CAAC,OAAuB,EAAQ,EAAE;YACzD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC3C,IAAI,CAAC,IAAI,CACP,iDAAiD,OAAO,CAAC,WAAW,yCAAyC,CAC9G,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC,CAAC;IAIF,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,YAAY,WAAmB,EAAE,OAAe;QAC9C,MAAM,GAAG,GAAG,WAAW,OAAO,oBAAoB,WAAW,mBAAmB,CAAC;QACjF,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,WAAmB;QAC7B,MAAM,GAAG,GAAG,2BAA2B,WAAW,qBAAqB,CAAC;QACxE,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,WAAmB,EAAE,OAAe,EAAE,OAAe;QAC/D,MAAM,GAAG,GAAG,sCAAsC,OAAO,oBAAoB,WAAW,KAAK,OAAO,EAAE,CAAC;QACvG,KAAK,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;CACF","sourcesContent":["import { AppObject, AppObjectEntity } from \"@vived/core\";\nimport { Handler, Request } from \"@vived/core\";\n\nexport interface RequestHandler {\n readonly requestType: string;\n handleRequest: (version: number, payload?: unknown) => void;\n}\n\nexport abstract class HostHandlerEntity extends AppObjectEntity {\n static type = \"HostHandlerEntity\";\n\n static get(appObject: AppObject) {\n return appObject.getComponent<HostHandlerEntity>(HostHandlerEntity.type);\n }\n\n abstract handler: Handler;\n abstract registerRequestHandler: (requestHandler: RequestHandler) => void;\n}\n\nexport function makeHostHandlerEntity(appObject: AppObject): HostHandlerEntity {\n return new RequestHandlerImp(appObject);\n}\n\nclass RequestHandlerImp extends HostHandlerEntity {\n private handlers = new Map<string, RequestHandler>();\n\n handler: Handler = (request: Request): void => {\n const handler = this.handlers.get(request.type);\n\n if (!handler) {\n this.warn(`Unsupported request type received: ${request.type}`);\n return;\n }\n\n try {\n handler.handleRequest(request.version, request.payload);\n } catch (e) {\n this.warn(`${e}`);\n }\n };\n\n registerRequestHandler = (handler: RequestHandler): void => {\n if (this.handlers.has(handler.requestType)) {\n this.warn(\n `More than one handler is being registered for ${handler.requestType}. Previous handler is being overwritten`\n );\n }\n\n this.handlers.set(handler.requestType, handler);\n };\n\n constructor(appObj: AppObject) {\n super(appObj, HostHandlerEntity.type);\n }\n}\n\nexport class UnsupportedRequestVersion extends Error {\n constructor(requestType: string, version: number) {\n const msg = `Version ${version} of request type ${requestType} is not supported`;\n super(msg);\n }\n}\n\nexport class ActionNotImplemented extends Error {\n constructor(requestType: string) {\n const msg = `Action for request type ${requestType} is not implemented`;\n super(msg);\n }\n}\n\nexport class UnableToParsePayload extends Error {\n constructor(requestType: string, version: number, payload: string) {\n const msg = `Unable to parse paylod for version ${version} of request type ${requestType}: ${payload}`;\n super(msg);\n }\n}\n"]}
1
+ {"version":3,"file":"HostHandler.js","sourceRoot":"","sources":["../../../../src/Handler/Entities/HostHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { AppObject, AppObjectEntity } from \"@vived/core\";\r\nimport { Handler, Request } from \"@vived/core\";\r\n\r\nexport interface RequestHandler {\r\n readonly requestType: string;\r\n handleRequest: (version: number, payload?: unknown) => void;\r\n}\r\n\r\n/**\r\n * The outcome of an inbound Request, as seen at the handler chokepoint:\r\n * \"handled\" (a registered handler ran), \"unsupported\" (no handler registered\r\n * for the type), or \"threw\" (the handler raised).\r\n */\r\nexport type HandlerOutcome = \"handled\" | \"unsupported\" | \"threw\";\r\n\r\n/**\r\n * Passive observer of inbound Requests. Notified after each Request is routed,\r\n * with the outcome. Purely observational — see the passivity contract in\r\n * ADR-0002: an observer must never alter, delay, or fail the Request.\r\n */\r\nexport type HandlerObserver = (\r\n request: Request,\r\n outcome: HandlerOutcome\r\n) => void;\r\n\r\nexport abstract class HostHandlerEntity extends AppObjectEntity {\r\n static type = \"HostHandlerEntity\";\r\n\r\n static get(appObject: AppObject) {\r\n return appObject.getComponent<HostHandlerEntity>(HostHandlerEntity.type);\r\n }\r\n\r\n abstract handler: Handler;\r\n abstract registerRequestHandler: (requestHandler: RequestHandler) => void;\r\n\r\n /**\r\n * Optional passive observer of inbound Requests (ADR-0002). Unset by default,\r\n * so production hosts pay nothing and behave exactly as before.\r\n */\r\n abstract requestObserver?: HandlerObserver;\r\n}\r\n\r\nexport function makeHostHandlerEntity(appObject: AppObject): HostHandlerEntity {\r\n return new RequestHandlerImp(appObject);\r\n}\r\n\r\nclass RequestHandlerImp extends HostHandlerEntity {\r\n private handlers = new Map<string, RequestHandler>();\r\n\r\n requestObserver?: HandlerObserver;\r\n\r\n /**\r\n * Notify the passive observer, if any. Wrapped so a throwing or slow observer\r\n * can never alter, delay, or fail the Request (ADR-0002).\r\n */\r\n private notifyObserver = (request: Request, outcome: HandlerOutcome) => {\r\n if (!this.requestObserver) return;\r\n try {\r\n this.requestObserver(request, outcome);\r\n } catch {\r\n // Passive: an observer failure must never affect handling.\r\n }\r\n };\r\n\r\n handler: Handler = (request: Request): void => {\r\n const handler = this.handlers.get(request.type);\r\n\r\n if (!handler) {\r\n this.warn(`Unsupported request type received: ${request.type}`);\r\n this.notifyObserver(request, \"unsupported\");\r\n return;\r\n }\r\n\r\n try {\r\n handler.handleRequest(request.version, request.payload);\r\n this.notifyObserver(request, \"handled\");\r\n } catch (e) {\r\n this.warn(`${e}`);\r\n this.notifyObserver(request, \"threw\");\r\n }\r\n };\r\n\r\n registerRequestHandler = (handler: RequestHandler): void => {\r\n if (this.handlers.has(handler.requestType)) {\r\n this.warn(\r\n `More than one handler is being registered for ${handler.requestType}. Previous handler is being overwritten`\r\n );\r\n }\r\n\r\n this.handlers.set(handler.requestType, handler);\r\n };\r\n\r\n constructor(appObj: AppObject) {\r\n super(appObj, HostHandlerEntity.type);\r\n }\r\n}\r\n\r\nexport class UnsupportedRequestVersion extends Error {\r\n constructor(requestType: string, version: number) {\r\n const msg = `Version ${version} of request type ${requestType} is not supported`;\r\n super(msg);\r\n }\r\n}\r\n\r\nexport class ActionNotImplemented extends Error {\r\n constructor(requestType: string) {\r\n const msg = `Action for request type ${requestType} is not implemented`;\r\n super(msg);\r\n }\r\n}\r\n\r\nexport class UnableToParsePayload extends Error {\r\n constructor(requestType: string, version: number, payload: string) {\r\n const msg = `Unable to parse paylod for version ${version} of request type ${requestType}: ${payload}`;\r\n super(msg);\r\n }\r\n}\r\n"]}
package/dist/esm/index.js CHANGED
@@ -2,6 +2,7 @@ export * from "./Apps";
2
2
  export * from "./AppSandbox";
3
3
  export * from "./AssetPlugin";
4
4
  export * from "./Assets";
5
+ export * from "./BoundaryLog";
5
6
  export * from "./Cache";
6
7
  export * from "./ChallengeResults";
7
8
  export * from "./Dialog";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC","sourcesContent":["export * from \"./Apps\";\nexport * from \"./AppSandbox\";\nexport * from \"./AssetPlugin\";\nexport * from \"./Assets\";\nexport * from \"./Cache\";\nexport * from \"./ChallengeResults\";\nexport * from \"./Dialog\";\nexport * from \"./Dispatcher\";\nexport * from \"./Events\";\nexport * from \"./Handler\";\nexport * from \"./Logger\";\nexport * from \"./Snackbar\";\nexport * from \"./StateMachine\";\nexport * from \"./ThemeColors\";\nexport * from \"./VivedAPI\";\nexport * from \"./ZSpaceHost\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC","sourcesContent":["export * from \"./Apps\";\r\nexport * from \"./AppSandbox\";\r\nexport * from \"./AssetPlugin\";\r\nexport * from \"./Assets\";\r\nexport * from \"./BoundaryLog\";\r\nexport * from \"./Cache\";\r\nexport * from \"./ChallengeResults\";\r\nexport * from \"./Dialog\";\r\nexport * from \"./Dispatcher\";\r\nexport * from \"./Events\";\r\nexport * from \"./Handler\";\r\nexport * from \"./Logger\";\r\nexport * from \"./Snackbar\";\r\nexport * from \"./StateMachine\";\r\nexport * from \"./ThemeColors\";\r\nexport * from \"./VivedAPI\";\r\nexport * from \"./ZSpaceHost\";\r\n"]}
@@ -0,0 +1,4 @@
1
+ import { SingletonPmAdapter } from "@vived/core";
2
+ import { BoundaryLogVM } from "../PMs/BoundaryLogPM";
3
+ export declare const boundaryLogAdapter: SingletonPmAdapter<BoundaryLogVM>;
4
+ //# sourceMappingURL=boundaryLogAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundaryLogAdapter.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Adapters/boundaryLogAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAEL,aAAa,EAEd,MAAM,sBAAsB,CAAC;AAE9B,eAAO,MAAM,kBAAkB,EAAE,kBAAkB,CAAC,aAAa,CA8BhE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./boundaryLogAdapter";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Adapters/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { AppObjectRepo } from "@vived/core";
2
+ /** Clears the Boundary Log on demand (the tab's Clear action). */
3
+ export declare function clearBoundaryLog(appObjects: AppObjectRepo): void;
4
+ //# sourceMappingURL=clearBoundaryLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clearBoundaryLog.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Controllers/clearBoundaryLog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,aAAa,QAUzD"}
@@ -0,0 +1,2 @@
1
+ export * from "./clearBoundaryLog";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Controllers/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { AppObject, AppObjectEntity, AppObjectRepo, Request } from "@vived/core";
2
+ import { PayloadSnapshot } from "./snapshotPayload";
3
+ /** Which way a recorded Request crossed the host↔App boundary. */
4
+ export type RequestDirection = "dispatch" | "handler";
5
+ /**
6
+ * What happened to a recorded Request. Outbound (Dispatch) records use
7
+ * "delivered" | "no-app-handler" | "threw"; inbound (Handler) records use
8
+ * "handled" | "unsupported" | "threw".
9
+ */
10
+ export type RequestOutcome = "delivered" | "no-app-handler" | "handled" | "unsupported" | "threw";
11
+ /**
12
+ * One captured entry in the Boundary Log: the observed Request plus its
13
+ * direction, a frozen payload snapshot, the time it was observed, and its
14
+ * outcome. Distinct from the live wire Request it was captured from.
15
+ */
16
+ export interface RequestRecord {
17
+ direction: RequestDirection;
18
+ type: string;
19
+ version: number;
20
+ payload: PayloadSnapshot;
21
+ timestamp: number;
22
+ outcome: RequestOutcome;
23
+ }
24
+ /**
25
+ * The Boundary Log: a passive, chronological recording of every Request
26
+ * observed crossing the host↔App boundary. Accumulates unbounded within a
27
+ * session and is only reset by an explicit clear() — never by traffic itself.
28
+ */
29
+ export declare abstract class BoundaryLogEntity extends AppObjectEntity {
30
+ static type: string;
31
+ static get(appObjects: AppObjectRepo): BoundaryLogEntity | undefined;
32
+ abstract records: RequestRecord[];
33
+ abstract recordTraffic: (direction: RequestDirection, request: Request, outcome: RequestOutcome) => void;
34
+ abstract clear: () => void;
35
+ }
36
+ export declare function makeBoundaryLogEntity(appObject: AppObject): BoundaryLogEntity;
37
+ //# sourceMappingURL=BoundaryLogEntity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BoundaryLogEntity.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Entities/BoundaryLogEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EACT,eAAe,EACf,aAAa,EACb,OAAO,EACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAmB,MAAM,mBAAmB,CAAC;AAErE,kEAAkE;AAClE,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,gBAAgB,GAChB,SAAS,GACT,aAAa,GACb,OAAO,CAAC;AAEZ;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;;GAIG;AACH,8BAAsB,iBAAkB,SAAQ,eAAe;IAC7D,MAAM,CAAC,IAAI,SAAuB;IAElC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa;IAOpC,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC;IAElC,QAAQ,CAAC,aAAa,EAAE,CACtB,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,KACpB,IAAI,CAAC;IAEV,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,iBAAiB,CAE7E"}
@@ -0,0 +1,3 @@
1
+ export * from "./BoundaryLogEntity";
2
+ export * from "./snapshotPayload";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Entities/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * A best-effort, one-level-deep structural snapshot of a Request payload, taken
3
+ * at the moment the Request crosses the host↔App boundary. It never throws:
4
+ * callbacks, circular references, and throwing getters are all rendered as
5
+ * previews rather than expanded or serialized. Nested objects/arrays are marked
6
+ * (not recursed), so what a developer inspects is exactly what was sent —
7
+ * frozen, safe to render, and cheap to build.
8
+ */
9
+ export interface PayloadSnapshot {
10
+ /** True when the payload was undefined/null or carried no own-enumerable keys. */
11
+ isEmpty: boolean;
12
+ /** Own-enumerable key → one-level preview string. */
13
+ fields: Record<string, string>;
14
+ }
15
+ export declare function snapshotPayload(payload: unknown): PayloadSnapshot;
16
+ //# sourceMappingURL=snapshotPayload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotPayload.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Entities/snapshotPayload.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAkCD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAwBjE"}
@@ -0,0 +1,17 @@
1
+ import { AppObject, AppObjectRepo, DomainFactory } from "@vived/core";
2
+ /**
3
+ * Sets up the Boundary Log and wires its passive observers into the per-App
4
+ * communication entities (ADR-0002). The observers are attached in finalSetup,
5
+ * after every entity exists but before the App mounts — so the host-internal
6
+ * version-negotiation dispatches fired at registration are captured too.
7
+ */
8
+ export declare class BoundaryLogFactory extends DomainFactory {
9
+ readonly factoryName = "BoundaryLogFactory";
10
+ constructor(appObject: AppObject);
11
+ setupEntities(): void;
12
+ setupUCs(): void;
13
+ setupPMs(): void;
14
+ finalSetup(): void;
15
+ }
16
+ export declare function makeBoundaryLogFactory(appObjects: AppObjectRepo): BoundaryLogFactory;
17
+ //# sourceMappingURL=BoundaryLogFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BoundaryLogFactory.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Factories/BoundaryLogFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAOtE;;;;;GAKG;AACH,qBAAa,kBAAmB,SAAQ,aAAa;IACnD,QAAQ,CAAC,WAAW,wBAAwB;gBAEhC,SAAS,EAAE,SAAS;IAIhC,aAAa,IAAI,IAAI;IAIrB,QAAQ,IAAI,IAAI;IAIhB,QAAQ,IAAI,IAAI;IAIhB,UAAU,IAAI,IAAI;CA+BnB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,aAAa,GACxB,kBAAkB,CAGpB"}
@@ -0,0 +1,2 @@
1
+ export * from "./BoundaryLogFactory";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Factories/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { AppObject, AppObjectRepo } from "@vived/core";
2
+ import { BoundaryLogPM } from "../PMs";
3
+ export declare class BoundaryLogPMMock extends BoundaryLogPM {
4
+ vmsAreEqual: jest.Mock<any, any, any>;
5
+ constructor(appObject: AppObject);
6
+ }
7
+ export declare function makeBoundaryLogPMMock(appObjects: AppObjectRepo): BoundaryLogPMMock;
8
+ //# sourceMappingURL=BoundaryLogPMMock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BoundaryLogPMMock.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Mocks/BoundaryLogPMMock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,WAAW,2BAAa;gBAEZ,SAAS,EAAE,SAAS;CAGjC;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,aAAa,qBAE9D"}
@@ -0,0 +1,2 @@
1
+ export * from "./BoundaryLogPMMock";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/Mocks/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { AppObject, AppObjectPM, AppObjectRepo } from "@vived/core";
2
+ import { RequestRecord } from "../Entities";
3
+ /**
4
+ * The view projection of the Boundary Log: the recorded Requests in observation
5
+ * order (each row carries its direction so the view can side Dispatches and
6
+ * Handlers independently) plus the total count.
7
+ */
8
+ export interface BoundaryLogVM {
9
+ records: RequestRecord[];
10
+ count: number;
11
+ }
12
+ export declare const defaultBoundaryLogVM: BoundaryLogVM;
13
+ export declare abstract class BoundaryLogPM extends AppObjectPM<BoundaryLogVM> {
14
+ static type: string;
15
+ static get(appObjects: AppObjectRepo): BoundaryLogPM | undefined;
16
+ }
17
+ export declare function makeBoundaryLogPM(appObject: AppObject): BoundaryLogPM;
18
+ //# sourceMappingURL=BoundaryLogPM.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BoundaryLogPM.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/PMs/BoundaryLogPM.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EACT,WAAW,EACX,aAAa,EACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAqB,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,oBAAoB,EAAE,aAGlC,CAAC;AAEF,8BAAsB,aAAc,SAAQ,WAAW,CAAC,aAAa,CAAC;IACpE,MAAM,CAAC,IAAI,SAAmB;IAE9B,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,aAAa;CAGrC;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,aAAa,CAErE"}
@@ -0,0 +1,2 @@
1
+ export * from "./BoundaryLogPM";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/BoundaryLog/PMs/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from "./Adapters";
2
+ export * from "./Controllers";
3
+ export * from "./Entities";
4
+ export * from "./Factories";
5
+ export * from "./Mocks";
6
+ export * from "./PMs";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/BoundaryLog/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC"}
@@ -1,5 +1,17 @@
1
1
  import { AppObject, AppObjectEntity, AppObjectRepo } from "@vived/core";
2
2
  import { Handler, Request } from "@vived/core";
3
+ /**
4
+ * The outcome of an outbound Dispatch, as seen at the dispatch chokepoint:
5
+ * "delivered" (the app handler ran), "no-app-handler" (nothing registered to
6
+ * receive it), or "threw" (the app handler raised).
7
+ */
8
+ export type DispatchOutcome = "delivered" | "no-app-handler" | "threw";
9
+ /**
10
+ * Passive observer of outbound Dispatches. Notified after each Request is
11
+ * dispatched, with the outcome. Purely observational — see the passivity
12
+ * contract in ADR-0002: an observer must never alter, delay, or fail delivery.
13
+ */
14
+ export type DispatchObserver = (request: Request, outcome: DispatchOutcome) => void;
3
15
  export declare abstract class HostDispatchEntity extends AppObjectEntity {
4
16
  static readonly type = "HostDispatchEntity";
5
17
  abstract appHandlerVersion: number;
@@ -8,6 +20,11 @@ export declare abstract class HostDispatchEntity extends AppObjectEntity {
8
20
  abstract clearAppHandler: () => void;
9
21
  abstract dispatch: (request: Request) => void;
10
22
  abstract formRequestAndDispatch: (type: string, version: number, payload?: object | undefined) => void;
23
+ /**
24
+ * Optional passive observer of outbound Dispatches (ADR-0002). Unset by
25
+ * default, so production hosts pay nothing and behave exactly as before.
26
+ */
27
+ abstract requestObserver?: DispatchObserver;
11
28
  static get(appObject: AppObject): HostDispatchEntity | undefined;
12
29
  static getByID(id: string, appObjects: AppObjectRepo): HostDispatchEntity | undefined;
13
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HostDispatchEntity.d.ts","sourceRoot":"","sources":["../../../../src/Dispatcher/Entities/HostDispatchEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE/C,8BAAsB,kBAAmB,SAAQ,eAAe;IAC9D,MAAM,CAAC,QAAQ,CAAC,IAAI,wBAAwB;IAE5C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAC1E,QAAQ,CAAC,kBAAkB,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,sBAAsB,EAAE,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,KACzB,IAAI,CAAC;IAEV,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,kBAAkB,GAAG,SAAS;IAahE,MAAM,CAAC,OAAO,CACZ,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,aAAa,GACxB,kBAAkB,GAAG,SAAS;CAWlC;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,GACnB,kBAAkB,CAEpB"}
1
+ {"version":3,"file":"HostDispatchEntity.d.ts","sourceRoot":"","sources":["../../../../src/Dispatcher/Entities/HostDispatchEntity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,KACrB,IAAI,CAAC;AAEV,8BAAsB,kBAAmB,SAAQ,eAAe;IAC9D,MAAM,CAAC,QAAQ,CAAC,IAAI,wBAAwB;IAE5C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAC1E,QAAQ,CAAC,kBAAkB,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,sBAAsB,EAAE,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,KACzB,IAAI,CAAC;IAEV;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,gBAAgB,CAAC;IAE5C,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,kBAAkB,GAAG,SAAS;IAahE,MAAM,CAAC,OAAO,CACZ,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,aAAa,GACxB,kBAAkB,GAAG,SAAS;CAWlC;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,GACnB,kBAAkB,CAEpB"}
@@ -7,6 +7,7 @@ export declare class MockHostDispatchEntity extends HostDispatchEntity {
7
7
  registerAppHandler: jest.Mock<any, any, any>;
8
8
  dispatch: jest.Mock<any, any, any>;
9
9
  formRequestAndDispatch: jest.Mock<any, any, any>;
10
+ requestObserver: undefined;
10
11
  constructor(appObject: AppObject);
11
12
  }
12
13
  //# sourceMappingURL=MockHostDispatcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MockHostDispatcher.d.ts","sourceRoot":"","sources":["../../../../src/Dispatcher/Mocks/MockHostDispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAC5D,eAAe,2BAAa;IAC5B,iBAAiB,SAAK;IACtB,wBAAwB,2BAAa;IACrC,kBAAkB,2BAAa;IAC/B,QAAQ,2BAAa;IACrB,sBAAsB,2BAAa;gBAEvB,SAAS,EAAE,SAAS;CAGjC"}
1
+ {"version":3,"file":"MockHostDispatcher.d.ts","sourceRoot":"","sources":["../../../../src/Dispatcher/Mocks/MockHostDispatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,qBAAa,sBAAuB,SAAQ,kBAAkB;IAC5D,eAAe,2BAAa;IAC5B,iBAAiB,SAAK;IACtB,wBAAwB,2BAAa;IACrC,kBAAkB,2BAAa;IAC/B,QAAQ,2BAAa;IACrB,sBAAsB,2BAAa;IACnC,eAAe,YAAa;gBAEhB,SAAS,EAAE,SAAS;CAGjC"}
@@ -1,14 +1,31 @@
1
1
  import { AppObject, AppObjectEntity } from "@vived/core";
2
- import { Handler } from "@vived/core";
2
+ import { Handler, Request } from "@vived/core";
3
3
  export interface RequestHandler {
4
4
  readonly requestType: string;
5
5
  handleRequest: (version: number, payload?: unknown) => void;
6
6
  }
7
+ /**
8
+ * The outcome of an inbound Request, as seen at the handler chokepoint:
9
+ * "handled" (a registered handler ran), "unsupported" (no handler registered
10
+ * for the type), or "threw" (the handler raised).
11
+ */
12
+ export type HandlerOutcome = "handled" | "unsupported" | "threw";
13
+ /**
14
+ * Passive observer of inbound Requests. Notified after each Request is routed,
15
+ * with the outcome. Purely observational — see the passivity contract in
16
+ * ADR-0002: an observer must never alter, delay, or fail the Request.
17
+ */
18
+ export type HandlerObserver = (request: Request, outcome: HandlerOutcome) => void;
7
19
  export declare abstract class HostHandlerEntity extends AppObjectEntity {
8
20
  static type: string;
9
21
  static get(appObject: AppObject): HostHandlerEntity | undefined;
10
22
  abstract handler: Handler;
11
23
  abstract registerRequestHandler: (requestHandler: RequestHandler) => void;
24
+ /**
25
+ * Optional passive observer of inbound Requests (ADR-0002). Unset by default,
26
+ * so production hosts pay nothing and behave exactly as before.
27
+ */
28
+ abstract requestObserver?: HandlerObserver;
12
29
  }
13
30
  export declare function makeHostHandlerEntity(appObject: AppObject): HostHandlerEntity;
14
31
  export declare class UnsupportedRequestVersion extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"HostHandler.d.ts","sourceRoot":"","sources":["../../../../src/Handler/Entities/HostHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,OAAO,EAAW,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7D;AAED,8BAAsB,iBAAkB,SAAQ,eAAe;IAC7D,MAAM,CAAC,IAAI,SAAuB;IAElC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS;IAI/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,sBAAsB,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,IAAI,CAAC;CAC3E;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,iBAAiB,CAE7E;AAmCD,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIjD;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,WAAW,EAAE,MAAM;CAIhC;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIlE"}
1
+ {"version":3,"file":"HostHandler.d.ts","sourceRoot":"","sources":["../../../../src/Handler/Entities/HostHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7D;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,CAAC;AAEjE;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,KACpB,IAAI,CAAC;AAEV,8BAAsB,iBAAkB,SAAQ,eAAe;IAC7D,MAAM,CAAC,IAAI,SAAuB;IAElC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS;IAI/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,sBAAsB,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,IAAI,CAAC;IAE1E;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC;CAC5C;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,iBAAiB,CAE7E;AAqDD,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIjD;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,WAAW,EAAE,MAAM;CAIhC;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIlE"}
@@ -2,6 +2,7 @@ export * from "./Apps";
2
2
  export * from "./AppSandbox";
3
3
  export * from "./AssetPlugin";
4
4
  export * from "./Assets";
5
+ export * from "./BoundaryLog";
5
6
  export * from "./Cache";
6
7
  export * from "./ChallengeResults";
7
8
  export * from "./Dialog";