@hyperfrontend/features 0.1.0 → 0.2.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 (159) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/_dependencies/@hyperfrontend/builder/bundle/dependencies/index.cjs.js +1 -0
  3. package/_dependencies/@hyperfrontend/builder/bundle/dependencies/index.esm.js +1 -0
  4. package/_dependencies/@hyperfrontend/builder/bundle/dependencies/worker/index.cjs.js +1 -0
  5. package/_dependencies/@hyperfrontend/builder/bundle/dependencies/worker/index.esm.js +1 -0
  6. package/_dependencies/@hyperfrontend/builder/bundle/index.cjs.js +12 -10
  7. package/_dependencies/@hyperfrontend/builder/bundle/index.esm.js +14 -12
  8. package/_dependencies/@hyperfrontend/builder/bundle/rollup/index.cjs.js +2 -0
  9. package/_dependencies/@hyperfrontend/builder/bundle/rollup/index.esm.js +2 -0
  10. package/_dependencies/@hyperfrontend/builder/bundle/rollup/worker/index.cjs.js +2 -0
  11. package/_dependencies/@hyperfrontend/builder/bundle/rollup/worker/index.esm.js +2 -0
  12. package/_dependencies/@hyperfrontend/builder/index.cjs.js +87 -53
  13. package/_dependencies/@hyperfrontend/builder/index.esm.js +89 -55
  14. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.cjs.js +4 -0
  15. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/promise/index.esm.js +3 -1
  16. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/reflect/index.cjs.js +10 -0
  17. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/reflect/index.esm.js +6 -0
  18. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/timers/index.cjs.js +5 -0
  19. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/timers/index.esm.js +5 -1
  20. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/typed-arrays/index.cjs.js +2 -2
  21. package/_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/typed-arrays/index.esm.js +2 -2
  22. package/_dependencies/@hyperfrontend/network-protocol/browser/channel/index.cjs.js +5 -19
  23. package/_dependencies/@hyperfrontend/network-protocol/browser/channel/index.esm.js +1 -15
  24. package/_dependencies/@hyperfrontend/network-protocol/browser/data/index.cjs.js +15 -23
  25. package/_dependencies/@hyperfrontend/network-protocol/browser/data/index.esm.js +7 -15
  26. package/_dependencies/@hyperfrontend/network-protocol/browser/packet/index.cjs.js +6 -14
  27. package/_dependencies/@hyperfrontend/network-protocol/browser/packet/index.esm.js +7 -15
  28. package/_dependencies/@hyperfrontend/network-protocol/browser/receiver/index.cjs.js +4 -18
  29. package/_dependencies/@hyperfrontend/network-protocol/browser/receiver/index.esm.js +1 -15
  30. package/_dependencies/@hyperfrontend/network-protocol/browser/sender/index.cjs.js +5 -19
  31. package/_dependencies/@hyperfrontend/network-protocol/browser/sender/index.esm.js +2 -16
  32. package/_dependencies/@hyperfrontend/network-protocol/browser/v1/index.cjs.js +16 -24
  33. package/_dependencies/@hyperfrontend/network-protocol/browser/v1/index.esm.js +7 -15
  34. package/_dependencies/@hyperfrontend/network-protocol/browser/v2/index.cjs.js +16 -24
  35. package/_dependencies/@hyperfrontend/network-protocol/browser/v2/index.esm.js +7 -15
  36. package/_dependencies/@hyperfrontend/network-protocol/node/channel/index.cjs.js +3 -17
  37. package/_dependencies/@hyperfrontend/network-protocol/node/channel/index.esm.js +1 -15
  38. package/_dependencies/@hyperfrontend/network-protocol/node/data/index.cjs.js +6 -14
  39. package/_dependencies/@hyperfrontend/network-protocol/node/data/index.esm.js +7 -15
  40. package/_dependencies/@hyperfrontend/network-protocol/node/packet/index.cjs.js +6 -14
  41. package/_dependencies/@hyperfrontend/network-protocol/node/packet/index.esm.js +7 -15
  42. package/_dependencies/@hyperfrontend/network-protocol/node/receiver/index.cjs.js +3 -17
  43. package/_dependencies/@hyperfrontend/network-protocol/node/receiver/index.esm.js +1 -15
  44. package/_dependencies/@hyperfrontend/network-protocol/node/sender/index.cjs.js +2 -16
  45. package/_dependencies/@hyperfrontend/network-protocol/node/sender/index.esm.js +2 -16
  46. package/_dependencies/@hyperfrontend/network-protocol/node/v1/index.cjs.js +6 -14
  47. package/_dependencies/@hyperfrontend/network-protocol/node/v1/index.esm.js +7 -15
  48. package/_dependencies/@hyperfrontend/network-protocol/node/v2/index.cjs.js +6 -14
  49. package/_dependencies/@hyperfrontend/network-protocol/node/v2/index.esm.js +7 -15
  50. package/_dependencies/@hyperfrontend/nexus/index.cjs.js +49 -19
  51. package/_dependencies/@hyperfrontend/nexus/index.esm.js +49 -19
  52. package/_dependencies/@hyperfrontend/project-scope/core/fs/index.cjs.js +62 -0
  53. package/_dependencies/@hyperfrontend/project-scope/core/fs/index.esm.js +60 -2
  54. package/_shared/generators/feature/generate-feature-module/index.esm.js +11 -6
  55. package/_shared/generators/metadata/generate-metadata/index.esm.js +1 -0
  56. package/_shared/shared/control/index.cjs.js +12 -2
  57. package/_shared/shared/control/index.esm.js +12 -2
  58. package/_shared/shared/request/index.cjs.js +91 -0
  59. package/_shared/shared/request/index.esm.js +88 -0
  60. package/_shared/shared/shutdown/index.esm.js +12 -0
  61. package/bin/hf.js +643 -70
  62. package/bundle/host/index.iife.js +290 -4041
  63. package/bundle/host/index.iife.min.js +1 -1
  64. package/bundle/host/index.umd.js +290 -4041
  65. package/bundle/host/index.umd.min.js +1 -1
  66. package/bundle/hostee/index.iife.js +215 -2893
  67. package/bundle/hostee/index.iife.min.js +1 -1
  68. package/bundle/hostee/index.umd.js +215 -2893
  69. package/bundle/hostee/index.umd.min.js +1 -1
  70. package/cli/args.d.ts +2 -0
  71. package/cli/args.d.ts.map +1 -1
  72. package/cli/commands/build.d.ts +8 -5
  73. package/cli/commands/build.d.ts.map +1 -1
  74. package/cli/commands/dev.d.ts +7 -2
  75. package/cli/commands/dev.d.ts.map +1 -1
  76. package/cli/config/resolve.d.ts +3 -1
  77. package/cli/config/resolve.d.ts.map +1 -1
  78. package/cli/index.cjs.js +643 -70
  79. package/cli/index.d.ts +21 -10
  80. package/cli/index.esm.js +591 -60
  81. package/cli/usage.d.ts +1 -1
  82. package/cli/usage.d.ts.map +1 -1
  83. package/generators/feature/generate-feature-module.d.ts.map +1 -1
  84. package/generators/index.cjs.js +435 -42
  85. package/generators/index.d.ts +9 -8
  86. package/generators/index.esm.js +404 -30
  87. package/generators/metadata/generate-metadata.d.ts +4 -4
  88. package/generators/metadata/generate-metadata.d.ts.map +1 -1
  89. package/generators/shell/connector-types.d.ts +19 -0
  90. package/generators/shell/connector-types.d.ts.map +1 -0
  91. package/generators/shell/generate-shell.d.ts +5 -4
  92. package/generators/shell/generate-shell.d.ts.map +1 -1
  93. package/generators/shell/schema-type.d.ts +20 -0
  94. package/generators/shell/schema-type.d.ts.map +1 -0
  95. package/generators/shell/source-literal.d.ts +28 -0
  96. package/generators/shell/source-literal.d.ts.map +1 -1
  97. package/host/create-shell.d.ts +4 -1
  98. package/host/create-shell.d.ts.map +1 -1
  99. package/host/display-modes/dialog.d.ts +1 -1
  100. package/host/display-modes/dialog.d.ts.map +1 -1
  101. package/host/display-modes/embedded.d.ts +1 -1
  102. package/host/display-modes/embedded.d.ts.map +1 -1
  103. package/host/index.cjs.js +150 -30
  104. package/host/index.d.ts +53 -38
  105. package/host/index.d.ts.map +1 -1
  106. package/host/index.esm.js +129 -9
  107. package/host/lifecycle.d.ts.map +1 -1
  108. package/host/plugins.d.ts +1 -34
  109. package/host/plugins.d.ts.map +1 -1
  110. package/host/types.d.ts +49 -0
  111. package/host/types.d.ts.map +1 -1
  112. package/hostee/index.cjs.js +54 -9
  113. package/hostee/index.d.ts +41 -1
  114. package/hostee/index.d.ts.map +1 -1
  115. package/hostee/index.esm.js +51 -6
  116. package/hostee/lifecycle.d.ts.map +1 -1
  117. package/hostee/types.d.ts +40 -0
  118. package/hostee/types.d.ts.map +1 -1
  119. package/index.cjs.js +32 -1
  120. package/index.d.ts +89 -3
  121. package/index.d.ts.map +1 -1
  122. package/index.esm.js +32 -1
  123. package/nx/executors/build/index.cjs.js +14975 -137
  124. package/nx/executors/build/index.esm.js +14935 -115
  125. package/nx/executors/serve/executor.d.ts.map +1 -1
  126. package/nx/executors/serve/index.cjs.js +6594 -80
  127. package/nx/executors/serve/index.esm.js +6529 -44
  128. package/nx/generators/feature/index.cjs.js +8751 -108
  129. package/nx/generators/feature/index.esm.js +8711 -81
  130. package/package.json +15 -5
  131. package/server/debug-ui/index.d.ts +2 -0
  132. package/server/debug-ui/index.d.ts.map +1 -0
  133. package/server/debug-ui/index.html +15 -0
  134. package/server/debug-ui/index.iife.js +427 -0
  135. package/server/debug-ui/index.iife.min.js +1 -0
  136. package/server/dev-server.d.ts.map +1 -1
  137. package/server/index.cjs.js +78 -10
  138. package/server/index.esm.js +78 -11
  139. package/server/module-dir.d.ts +17 -0
  140. package/server/module-dir.d.ts.map +1 -0
  141. package/server/module-dir.stub.d.ts +15 -0
  142. package/server/module-dir.stub.d.ts.map +1 -0
  143. package/shared/contract.d.ts +1 -1
  144. package/shared/contract.d.ts.map +1 -1
  145. package/shared/control.d.ts +4 -0
  146. package/shared/control.d.ts.map +1 -1
  147. package/shared/invert-contract.d.ts +20 -0
  148. package/shared/invert-contract.d.ts.map +1 -0
  149. package/shared/request.d.ts +68 -0
  150. package/shared/request.d.ts.map +1 -0
  151. package/{nx/shared → shared}/shutdown.d.ts +3 -2
  152. package/shared/shutdown.d.ts.map +1 -0
  153. package/shared/types.d.ts +72 -1
  154. package/shared/types.d.ts.map +1 -1
  155. package/_shared/nx/shared/context/index.cjs.js +0 -18
  156. package/_shared/nx/shared/context/index.esm.js +0 -16
  157. package/nx/shared/shutdown.d.ts.map +0 -1
  158. package/server/debug-ui/bootstrap.d.ts +0 -2
  159. package/server/debug-ui/bootstrap.d.ts.map +0 -1
@@ -1,120 +1,26 @@
1
1
  var HyperfrontendFeaturesHostee = (function (exports) {
2
2
  'use strict';
3
3
 
4
- /**
5
- * Safe copies of Error built-ins via factory functions.
6
- *
7
- * Since constructors cannot be safely captured via Object.assign, this module
8
- * provides factory functions that use Reflect.construct internally.
9
- *
10
- * These references are captured at module initialization time to protect against
11
- * prototype pollution attacks. Import only what you need for tree-shaking.
12
- *
13
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/error
14
- */
15
4
  const _Error = globalThis.Error;
16
- const _Reflect$9 = globalThis.Reflect;
17
- /**
18
- * (Safe copy) Creates a new Error using the captured Error constructor.
19
- * Use this instead of `new Error()`.
20
- *
21
- * @param message - Optional error message.
22
- * @param options - Optional error options.
23
- * @returns A new Error instance.
24
- *
25
- * @example Creating Error instances
26
- * ```typescript
27
- * const error = createError('Operation failed')
28
- * // With cause for error chaining
29
- * const wrapped = createError('Request failed', { cause: originalError })
30
- * ```
31
- */
32
- const createError = (message, options) => _Reflect$9.construct(_Error, [message, options]);
33
-
34
- /**
35
- * Safe copies of Object built-in methods.
36
- *
37
- * These references are captured at module initialization time to protect against
38
- * prototype pollution attacks. Import only what you need for tree-shaking.
39
- *
40
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/object
41
- */
5
+ const _Reflect$a = globalThis.Reflect;
6
+ const createError = (message, options) => _Reflect$a.construct(_Error, [message, options]);
7
+
42
8
  const _Object = globalThis.Object;
43
- const _Reflect$8 = globalThis.Reflect;
9
+ const _Reflect$9 = globalThis.Reflect;
44
10
  const _ObjectPrototype = _Object.prototype;
45
11
  const _hasOwnProperty = _ObjectPrototype.hasOwnProperty;
46
- /**
47
- * (Safe copy) Prevents modification of existing property attributes and values,
48
- * and prevents the addition of new properties.
49
- */
50
12
  const freeze = _Object.freeze;
51
- /**
52
- * (Safe copy) Returns the names of the enumerable string properties and methods of an object.
53
- */
54
13
  const keys = _Object.keys;
55
- /**
56
- * (Safe copy) Returns an array of key/values of the enumerable own properties of an object.
57
- */
58
14
  const entries = _Object.entries;
59
- /**
60
- * (Safe copy) Adds a property to an object, or modifies attributes of an existing property.
61
- */
15
+ const values = _Object.values;
62
16
  const defineProperty = _Object.defineProperty;
63
- /**
64
- * (Safe copy) Sets the prototype of a specified object o to object proto or null.
65
- */
66
17
  const setPrototypeOf = _Object.setPrototypeOf;
67
- /**
68
- * (Safe copy) Safe wrapper for Object.prototype.hasOwnProperty.call().
69
- * Checks if an object has a property as its own (not inherited) property.
70
- *
71
- * @param obj - The object to check.
72
- * @param key - The property key to check.
73
- * @returns True if the object has the property as its own property.
74
- *
75
- * @example Checking own properties
76
- * ```typescript
77
- * const user = { name: 'Alice' }
78
- * hasOwn(user, 'name') // => true
79
- * hasOwn(user, 'toString') // => false (inherited from prototype)
80
- * ```
81
- */
82
- const hasOwn = (obj, key) => _Reflect$8.apply(_hasOwnProperty, obj, [key]);
83
-
84
- /**
85
- * Safe copies of Math built-in methods.
86
- *
87
- * These references are captured at module initialization time to protect against
88
- * prototype pollution attacks. Import only what you need for tree-shaking.
89
- *
90
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/math
91
- */
18
+ const hasOwn = (obj, key) => _Reflect$9.apply(_hasOwnProperty, obj, [key]);
19
+
92
20
  const _Math = globalThis.Math;
93
- /**
94
- * (Safe copy) Returns the absolute value of a number.
95
- */
96
21
  const abs = _Math.abs;
97
- /**
98
- * (Safe copy) Returns a pseudo-random number between 0 and 1.
99
- * Note: This is NOT cryptographically secure. For secure random values,
100
- * use crypto.getRandomValues().
101
- */
102
22
  const random = _Math.random;
103
23
 
104
- /**
105
- * Generates a version 4 UUID.
106
- *
107
- * @returns a version 4 UUID.
108
- *
109
- * @example Creating unique identifiers for entities
110
- * ```typescript
111
- * const userId = uuidV4()
112
- * // => 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d'
113
- *
114
- * const sessionId = uuidV4()
115
- * // => '9f8e7d6c-5b4a-4321-8765-4321fedcba98'
116
- * ```
117
- */
118
24
  function uuidV4() {
119
25
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (char) => {
120
26
  const randomHex = (random() * 16) | 0;
@@ -123,17 +29,7 @@ var HyperfrontendFeaturesHostee = (function (exports) {
123
29
  });
124
30
  }
125
31
 
126
- /**
127
- * Protocol prefix for all action types.
128
- * This is the Nexus protocol identifier.
129
- */
130
32
  const PROTOCOL = 'nexus';
131
- /**
132
- * Action type string literals for the Nexus protocol.
133
- *
134
- * These define the wire format for all connection lifecycle actions.
135
- * The connection flow behavior is 1:1 with the proven legacy implementation.
136
- */
137
33
  const ACTION_TYPES = {
138
34
  INVALID_REQUEST: `[${PROTOCOL}] invalid-request`,
139
35
  REQUEST_CONNECTION: `[${PROTOCOL}] connection-request`,
@@ -147,66 +43,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
147
43
  OPEN_CONNECTION: `[${PROTOCOL}] connection-opened`,
148
44
  NEW_MESSAGE: `[${PROTOCOL}] new-message`,
149
45
  };
150
- /**
151
- * Type guards for specific action types
152
- *
153
- * @param action - The action to check
154
- * @returns True if action contains a contract property
155
- *
156
- * @example Checking for contract property
157
- * ```typescript
158
- * if (isActionWithContract(action)) {
159
- * console.log(action.contract)
160
- * }
161
- * ```
162
- */
163
46
  const isActionWithContract = (action) => 'contract' in action;
164
- /**
165
- * Type guard for actions with data property.
166
- *
167
- * @param action - The action to check
168
- * @returns True if action contains a data property
169
- *
170
- * @example Checking for data property
171
- * ```typescript
172
- * if (isActionWithData(action)) {
173
- * processData(action.data)
174
- * }
175
- * ```
176
- */
177
47
  const isActionWithData = (action) => 'data' in action;
178
- /**
179
- * Type guard for actions with processId property.
180
- *
181
- * @param action - The action to check
182
- * @returns True if action contains a processId property
183
- *
184
- * @example Checking for processId property
185
- * ```typescript
186
- * if (isActionWithProcess(action)) {
187
- * trackProcess(action.processId)
188
- * }
189
- * ```
190
- */
191
48
  const isActionWithProcess = (action) => 'processId' in action;
192
49
 
193
- /**
194
- * Creates ACCEPT_CONNECTION action
195
- *
196
- * @param deps - Action dependencies (getBrokerId, getContract)
197
- * @returns Function that takes processId and optional security response, returns frozen action
198
- *
199
- * @example Creating accept connection actions
200
- * ```typescript
201
- * // Without security
202
- * const action = acceptConnection(deps)('process-123')
203
- *
204
- * // With security negotiation response
205
- * const secureAction = acceptConnection(deps)('process-123', {
206
- * negotiated: 'v2'
207
- * })
208
- * ```
209
- */
210
50
  const acceptConnection = (deps) => (processId, security) => {
211
51
  const base = {
212
52
  type: ACTION_TYPES.ACCEPT_CONNECTION,
@@ -220,57 +60,18 @@ var HyperfrontendFeaturesHostee = (function (exports) {
220
60
  return freeze(base);
221
61
  };
222
62
 
223
- /**
224
- * Creates a cancel connection action.
225
- *
226
- * @param deps - Action dependencies containing broker ID
227
- * @returns A function that creates a cancel connection action for a process
228
- *
229
- * @example Creating cancel connection actions
230
- * ```typescript
231
- * const createCancelAction = cancelConnection({ getBrokerId: () => 'broker-1' })
232
- * const action = createCancelAction('process-123')
233
- * // => { type: 'CANCEL_CONNECTION', processId: 'process-123', senderId: 'broker-1' }
234
- * ```
235
- */
236
63
  const cancelConnection = (deps) => (processId) => freeze({
237
64
  type: ACTION_TYPES.CANCEL_CONNECTION,
238
65
  processId,
239
66
  senderId: deps.getBrokerId(),
240
67
  });
241
68
 
242
- /**
243
- * Creates a close connection action.
244
- *
245
- * @param deps - Action dependencies containing broker ID
246
- * @returns A function that creates a close connection action for a process
247
- *
248
- * @example Creating close connection actions
249
- * ```typescript
250
- * const createCloseAction = closeConnection({ getBrokerId: () => 'broker-1' })
251
- * const action = createCloseAction('process-123')
252
- * // => { type: 'CLOSE_CONNECTION', processId: 'process-123', senderId: 'broker-1' }
253
- * ```
254
- */
255
69
  const closeConnection = (deps) => (processId) => freeze({
256
70
  type: ACTION_TYPES.CLOSE_CONNECTION,
257
71
  processId,
258
72
  senderId: deps.getBrokerId(),
259
73
  });
260
74
 
261
- /**
262
- * Creates a deny connection action with an error message.
263
- *
264
- * @param deps - Action dependencies containing broker ID
265
- * @returns A function that creates a deny connection action for a process
266
- *
267
- * @example Creating deny connection actions
268
- * ```typescript
269
- * const createDenyAction = denyConnection({ getBrokerId: () => 'broker-1' })
270
- * const action = createDenyAction('process-123', 'Origin not allowed')
271
- * // => { type: 'DENY_CONNECTION', processId: 'process-123', senderId: 'broker-1', error: 'Origin not allowed' }
272
- * ```
273
- */
274
75
  const denyConnection = (deps) => (processId, error) => freeze({
275
76
  type: ACTION_TYPES.DENY_CONNECTION,
276
77
  processId,
@@ -278,37 +79,11 @@ var HyperfrontendFeaturesHostee = (function (exports) {
278
79
  error,
279
80
  });
280
81
 
281
- /**
282
- * Creates a destroy connection action.
283
- *
284
- * @param deps - Action dependencies containing broker ID
285
- * @returns A function that creates a destroy connection action
286
- *
287
- * @example Creating destroy connection actions
288
- * ```typescript
289
- * const createDestroyAction = destroyConnection({ getBrokerId: () => 'broker-1' })
290
- * const action = createDestroyAction()
291
- * // => { type: 'DESTROY_CONNECTION', senderId: 'broker-1' }
292
- * ```
293
- */
294
82
  const destroyConnection = (deps) => () => freeze({
295
83
  type: ACTION_TYPES.DESTROY_CONNECTION,
296
84
  senderId: deps.getBrokerId(),
297
85
  });
298
86
 
299
- /**
300
- * Creates an invalid request action with an error message.
301
- *
302
- * @param deps - Action dependencies containing broker ID
303
- * @returns A function that creates an invalid request action for a process
304
- *
305
- * @example Creating invalid request actions
306
- * ```typescript
307
- * const createInvalidAction = invalidRequest({ getBrokerId: () => 'broker-1' })
308
- * const action = createInvalidAction('process-123', 'Malformed payload')
309
- * // => { type: 'INVALID_REQUEST', processId: 'process-123', senderId: 'broker-1', error: 'Malformed payload' }
310
- * ```
311
- */
312
87
  const invalidRequest = (deps) => (processId, error) => freeze({
313
88
  type: ACTION_TYPES.INVALID_REQUEST,
314
89
  processId,
@@ -316,43 +91,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
316
91
  error,
317
92
  });
318
93
 
319
- /**
320
- * Creates a new message action with data payload.
321
- *
322
- * @param deps - Action dependencies containing broker ID
323
- * @returns A function that creates a new message action with data
324
- *
325
- * @example Creating message actions with data
326
- * ```typescript
327
- * const createMessageAction = newMessage({ getBrokerId: () => 'broker-1' })
328
- * const action = createMessageAction({ userId: 123, event: 'login' })
329
- * // => { type: 'NEW_MESSAGE', senderId: 'broker-1', data: { userId: 123, event: 'login' } }
330
- * ```
331
- */
332
- const newMessage = (deps) => (data) => freeze({
94
+ const newMessage = (deps) => (message) => freeze({
333
95
  type: ACTION_TYPES.NEW_MESSAGE,
334
96
  senderId: deps.getBrokerId(),
335
- data,
97
+ data: message,
336
98
  });
337
99
 
338
- /**
339
- * Creates OPEN_CONNECTION action
340
- *
341
- * @param deps - Action dependencies (getBrokerId, getContract)
342
- * @returns Function that takes processId and optional security confirmation, returns frozen action
343
- *
344
- * @example Creating open connection actions
345
- * ```typescript
346
- * // Without security
347
- * const action = openConnection(deps)('process-123')
348
- *
349
- * // With security confirmation
350
- * const secureAction = openConnection(deps)('process-123', {
351
- * active: true,
352
- * protocol: 'v2'
353
- * })
354
- * ```
355
- */
356
100
  const openConnection = (deps) => (processId, security) => {
357
101
  const base = {
358
102
  type: ACTION_TYPES.OPEN_CONNECTION,
@@ -365,24 +109,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
365
109
  return freeze(base);
366
110
  };
367
111
 
368
- /**
369
- * Creates REQUEST_CONNECTION action
370
- *
371
- * @param deps - Action dependencies (getBrokerId, getContract)
372
- * @returns Function that takes processId and optional security request, returns frozen action
373
- *
374
- * @example Creating request connection actions
375
- * ```typescript
376
- * // Without security
377
- * const action = requestConnection(deps)('process-123')
378
- *
379
- * // With security negotiation
380
- * const secureAction = requestConnection(deps)('process-123', {
381
- * supported: ['v2', 'v1', 'none'],
382
- * preferred: 'v2'
383
- * })
384
- * ```
385
- */
386
112
  const requestConnection = (deps) => (processId, security) => {
387
113
  const base = {
388
114
  type: ACTION_TYPES.REQUEST_CONNECTION,
@@ -396,21 +122,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
396
122
  return freeze(base);
397
123
  };
398
124
 
399
- /**
400
- * Creates all action creators bound to the provided dependencies
401
- *
402
- * @param deps - Action dependencies (getBrokerId, getContract)
403
- * @returns Frozen object containing all action creator functions
404
- *
405
- * @example Creating action creators
406
- * ```typescript
407
- * const actions = createActionCreators({
408
- * getBrokerId: () => 'broker-123',
409
- * getContract: () => myContract
410
- * })
411
- * const action = actions.requestConnection('process-456')
412
- * ```
413
- */
414
125
  const createActionCreators = (deps) => freeze({
415
126
  requestConnection: requestConnection(deps),
416
127
  acceptConnection: acceptConnection(deps),
@@ -423,102 +134,26 @@ var HyperfrontendFeaturesHostee = (function (exports) {
423
134
  invalidRequest: invalidRequest(deps),
424
135
  });
425
136
 
426
- /**
427
- * Safe Map factory with optional groupBy for ES2024+.
428
- *
429
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/map
430
- */
431
- /* eslint-disable workspace/lib-require-jsdoc-example */
432
137
  const _Map = globalThis.Map;
433
- const _Reflect$7 = globalThis.Reflect;
434
- /**
435
- * (Safe copy) Creates a new Map using the captured Map constructor.
436
- * Use this instead of `new Map()`.
437
- *
438
- * @param iterable - Optional iterable of key-value pairs.
439
- * @returns A new Map instance.
440
- */
441
- const createMap = (iterable) => _Reflect$7.construct(_Map, iterable ? [iterable] : []);
442
-
443
- /**
444
- * Clears all processes from the registry
445
- *
446
- * @param processes - Map storing process to channel mappings
447
- * @returns Function that clears all processes
448
- *
449
- * @example Clearing all processes
450
- * ```typescript
451
- * const clear = clearProcesses(processMap)
452
- * clear() // All processes removed
453
- * ```
454
- */
138
+ const _Reflect$8 = globalThis.Reflect;
139
+ const createMap = (iterable) => _Reflect$8.construct(_Map, iterable ? [iterable] : []);
140
+
455
141
  const clearProcesses = (processes) => () => {
456
142
  processes.clear();
457
143
  };
458
144
 
459
- /**
460
- * Creates a process ID and registers the channel
461
- *
462
- * @param processes - Map storing process to channel mappings
463
- * @returns Function that takes a channel and returns new process ID
464
- *
465
- * @example Registering a channel process
466
- * ```typescript
467
- * const create = createProcess(processMap)
468
- * const processId = create(myChannel)
469
- * ```
470
- */
471
145
  const createProcess = (processes) => (channel) => {
472
146
  const processId = uuidV4();
473
147
  processes.set(processId, channel);
474
148
  return processId;
475
149
  };
476
150
 
477
- /**
478
- * Gets a channel by its process ID
479
- *
480
- * @param processes - Map storing process to channel mappings
481
- * @returns Function that takes processId and returns channel or undefined
482
- *
483
- * @example Looking up channel by process ID
484
- * ```typescript
485
- * const processes = new Map([['proc-1', channelHandle]])
486
- * const findChannel = getChannel(processes)
487
- * const channel = findChannel('proc-1')
488
- * // => channelHandle or undefined
489
- * ```
490
- */
491
151
  const getChannel$1 = (processes) => (processId) => processes.get(processId);
492
152
 
493
- /**
494
- * Removes a process ID from the registry
495
- *
496
- * @param processes - Map storing process to channel mappings
497
- * @returns Function that takes processId and removes it
498
- *
499
- * @example Removing a process
500
- * ```typescript
501
- * const remove = removeProcess(processMap)
502
- * remove('some-process-id')
503
- * ```
504
- */
505
153
  const removeProcess = (processes) => (processId) => {
506
154
  processes.delete(processId);
507
155
  };
508
156
 
509
- /**
510
- * Creates a process manager for tracking process IDs to channel mappings
511
- *
512
- * @returns Object with process management methods
513
- *
514
- * @example Managing channel processes
515
- * ```typescript
516
- * const processManager = createProcessManager()
517
- * const processId = processManager.create(channel)
518
- * const found = processManager.get(processId)
519
- * processManager.remove(processId)
520
- * ```
521
- */
522
157
  const createProcessManager = () => {
523
158
  const processes = createMap();
524
159
  return freeze({
@@ -526,98 +161,27 @@ var HyperfrontendFeaturesHostee = (function (exports) {
526
161
  get: getChannel$1(processes),
527
162
  remove: removeProcess(processes),
528
163
  clear: clearProcesses(processes),
529
- /**
530
- * Track an existing process ID with a channel.
531
- * Useful when receiving a process ID from the remote side that needs to be associated
532
- * with a local channel instance.
533
- *
534
- * @param processId - The process ID to track
535
- * @param channel - The channel handle to associate with the process ID
536
- */
537
164
  track: (processId, channel) => {
538
165
  processes.set(processId, channel);
539
166
  },
540
- /**
541
- * Check if a process ID exists in the manager.
542
- *
543
- * @param processId - The process ID to check
544
- * @returns True if the process ID exists, false otherwise
545
- */
546
167
  has: (processId) => {
547
168
  return processes.has(processId);
548
169
  },
549
170
  });
550
171
  };
551
172
 
552
- /**
553
- * Safe copies of Array built-in static methods.
554
- *
555
- * These references are captured at module initialization time to protect against
556
- * prototype pollution attacks. Import only what you need for tree-shaking.
557
- *
558
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/array
559
- */
560
173
  const _Array = globalThis.Array;
561
- /**
562
- * (Safe copy) Determines whether the passed value is an Array.
563
- */
564
174
  const isArray = _Array.isArray;
565
- /**
566
- * (Safe copy) Creates an array from an array-like or iterable object.
567
- */
568
175
  const from = _Array.from;
569
176
 
570
- /**
571
- * Safe Set factory for protected set construction.
572
- *
573
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/set
574
- */
575
- /* eslint-disable workspace/lib-require-jsdoc-example */
576
177
  const _Set = globalThis.Set;
577
- const _Reflect$6 = globalThis.Reflect;
578
- /**
579
- * (Safe copy) Creates a new Set using the captured Set constructor.
580
- * Use this instead of `new Set()`.
581
- *
582
- * @param iterable - Optional iterable of values.
583
- * @returns A new Set instance.
584
- */
585
- const createSet = (iterable) => _Reflect$6.construct(_Set, iterable ? [iterable] : []);
586
-
587
- /**
588
- * Safe WeakMap factory for protected weak map construction.
589
- *
590
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/weak-map
591
- */
592
- /* eslint-disable workspace/lib-require-jsdoc-example */
178
+ const _Reflect$7 = globalThis.Reflect;
179
+ const createSet = (iterable) => _Reflect$7.construct(_Set, iterable ? [iterable] : []);
180
+
593
181
  const _WeakMap = globalThis.WeakMap;
594
- const _Reflect$5 = globalThis.Reflect;
595
- /**
596
- * (Safe copy) Creates a new WeakMap using the captured WeakMap constructor.
597
- * Use this instead of `new WeakMap()`.
598
- *
599
- * @param iterable - Optional iterable of key-value pairs.
600
- * @returns A new WeakMap instance.
601
- */
602
- const createWeakMap = (iterable) => _Reflect$5.construct(_WeakMap, iterable ? [iterable] : []);
603
-
604
- /**
605
- * Minimal channel structure required for registry operations.
606
- * Extended with optional methods for use with full ChannelHandle objects.
607
- */
608
- /**
609
- * Creates a new channel registry with isolated state.
610
- * All lookup operations are O(1) using WeakMap/Map.
611
- *
612
- * @returns Registry functions for managing channels
613
- *
614
- * @example Creating and using a registry
615
- * ```typescript
616
- * const registry = createRegistry()
617
- * registry.add({ id: 'ch-1', name: 'main', target: iframe.contentWindow })
618
- * const channel = registry.getById('ch-1')
619
- * ```
620
- */
182
+ const _Reflect$6 = globalThis.Reflect;
183
+ const createWeakMap = (iterable) => _Reflect$6.construct(_WeakMap, iterable ? [iterable] : []);
184
+
621
185
  function createRegistry() {
622
186
  const windowMap = createWeakMap();
623
187
  const idMap = createMap();
@@ -664,31 +228,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
664
228
  });
665
229
  }
666
230
 
667
- /* eslint-disable workspace/lib-require-jsdoc-example */
668
- /**
669
- * Check if value is an object (not null, not array)
670
- *
671
- * @param value - The value to check
672
- * @returns True if value is a plain object
673
- */
674
231
  function isObject(value) {
675
232
  return value !== null && typeof value === 'object' && !isArray(value);
676
233
  }
677
234
 
678
- /**
679
- * Validates a channel contract structure.
680
- *
681
- * @param contract - The contract to validate
682
- * @throws {Error} Error if contract is invalid
683
- *
684
- * @example Validating contract structure
685
- * ```typescript
686
- * validateContract({
687
- * emitted: [{ type: 'ping' }],
688
- * accepted: [{ type: 'pong' }]
689
- * })
690
- * ```
691
- */
692
235
  function validateContract$1(contract) {
693
236
  if (!contract) {
694
237
  throw createError('Contract cannot be null or undefined');
@@ -722,27 +265,9 @@ var HyperfrontendFeaturesHostee = (function (exports) {
722
265
  }
723
266
  }
724
267
 
725
- /**
726
- * Helper to check if a string is empty after trimming
727
- *
728
- * @param str - The string to check
729
- * @returns True if string is empty after trimming
730
- */
731
268
  function isEmpty(str) {
732
269
  return str.trim().length === 0;
733
270
  }
734
- /**
735
- * Validates a channel or broker name.
736
- *
737
- * @param name - The name to validate
738
- * @throws {Error} Error if name is invalid
739
- *
740
- * @example Validating channel name
741
- * ```typescript
742
- * validateName('my-channel') // valid
743
- * validateName('') // throws Error
744
- * ```
745
- */
746
271
  function validateName(name) {
747
272
  if (name === null || name === undefined) {
748
273
  throw createError('Name cannot be null or undefined');
@@ -755,98 +280,29 @@ var HyperfrontendFeaturesHostee = (function (exports) {
755
280
  }
756
281
  }
757
282
 
758
- /**
759
- * Protocol registry factory.
760
- *
761
- * Creates a registry for managing protocol providers at the broker level.
762
- *
763
- * @module security/registry/factory
764
- */
765
- /**
766
- * Creates a protocol registry for managing security protocol providers.
767
- *
768
- * The registry provides a centralized store for protocol providers,
769
- * allowing channels to retrieve the appropriate provider based on
770
- * the negotiated protocol version.
771
- *
772
- * The 'none' protocol is always considered supported (it requires
773
- * no provider) and cannot be registered or unregistered.
774
- *
775
- * @returns A new protocol registry instance
776
- *
777
- * @example Managing protocol providers
778
- * ```typescript
779
- * const registry = createProtocolRegistry()
780
- *
781
- * // Register v1 protocol
782
- * registry.register('v1', createProtocol(logger, 60))
783
- *
784
- * // Check availability
785
- * registry.has('v1') // true
786
- * registry.has('v2') // false
787
- * registry.has('none') // always true
788
- *
789
- * // Get supported versions
790
- * registry.getSupportedVersions() // ['v1', 'none']
791
- * ```
792
- */
793
283
  function createProtocolRegistry() {
794
284
  const providers = createMap();
795
- /**
796
- * Register a protocol provider.
797
- *
798
- * @param version - The protocol version ('v1' or 'v2')
799
- * @param provider - The protocol provider instance
800
- */
801
285
  const register = (version, provider) => {
802
286
  if (!provider) {
803
287
  throw createError(`Cannot register null/undefined provider for ${version}`);
804
288
  }
805
289
  providers.set(version, provider);
806
290
  };
807
- /**
808
- * Unregister a protocol provider.
809
- *
810
- * @param version - The protocol version to unregister
811
- */
812
291
  const unregister = (version) => {
813
292
  providers.delete(version);
814
293
  };
815
- /**
816
- * Get a registered protocol provider.
817
- *
818
- * Returns undefined for 'none' since it requires no provider.
819
- *
820
- * @param version - The protocol version to retrieve
821
- * @returns The provider if registered, otherwise undefined
822
- */
823
294
  const get = (version) => {
824
295
  if (version === 'none') {
825
296
  return undefined;
826
297
  }
827
298
  return providers.get(version);
828
299
  };
829
- /**
830
- * Check if a protocol provider is registered.
831
- *
832
- * The 'none' protocol is always considered available.
833
- *
834
- * @param version - The protocol version to check
835
- * @returns True if the provider is registered (or 'none')
836
- */
837
300
  const has = (version) => {
838
301
  if (version === 'none') {
839
302
  return true;
840
303
  }
841
304
  return providers.has(version);
842
305
  };
843
- /**
844
- * Get all supported protocol versions.
845
- *
846
- * Returns versions that have registered providers plus 'none'.
847
- *
848
- * @returns Array of supported protocol versions
849
- */
850
306
  const getSupportedVersions = () => {
851
307
  const versions = ['none'];
852
308
  if (providers.has('v1')) {
@@ -866,20 +322,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
866
322
  });
867
323
  }
868
324
 
869
- /**
870
- * Merges multiple channel contracts into a single contract
871
- *
872
- * @param contracts - The contracts to merge
873
- * @returns A single merged contract containing all accepted and provided actions
874
- *
875
- * @example Merging channel contracts
876
- * ```typescript
877
- * const contract1 = { accepted: [{ type: 'a' }], provided: [{ type: 'b' }] }
878
- * const contract2 = { accepted: [{ type: 'c' }], provided: [{ type: 'd' }] }
879
- * const merged = mergeContracts(contract1, contract2)
880
- * // merged = { accepted: [{ type: 'a' }, { type: 'c' }], emitted: [{ type: 'b' }, { type: 'd' }] }
881
- * ```
882
- */
883
325
  function mergeContracts(...contracts) {
884
326
  const mergedContract = {
885
327
  accepted: [],
@@ -916,38 +358,9 @@ var HyperfrontendFeaturesHostee = (function (exports) {
916
358
  info: 1,
917
359
  debug: 0,
918
360
  };
919
- /**
920
- * Validates whether a given string is a valid log level.
921
- *
922
- * @param level - The log level to validate
923
- * @returns True if the level is valid, false otherwise
924
- *
925
- * @example Validating log levels
926
- * ```typescript
927
- * isValidLogLevel('error') // => true
928
- * isValidLogLevel('verbose') // => false
929
- * ```
930
- */
931
361
  function isValidLogLevel(level) {
932
362
  return logLevels.includes(level);
933
363
  }
934
- /**
935
- * Creates a log level configuration manager for controlling logging behavior.
936
- * Provides methods to get, set, and evaluate log levels based on priority.
937
- *
938
- * @param level - The initial log level (defaults to 'error')
939
- * @returns A configuration object with log level management methods
940
- * @throws {Error} When the provided level is not a valid log level
941
- *
942
- * @example Managing log levels with priority checks
943
- * ```typescript
944
- * const config = createLogLevelConfig('warn')
945
- * config.shouldLog('error') // => true (error >= warn)
946
- * config.shouldLog('debug') // => false (debug < warn)
947
- * config.setLogLevel('debug')
948
- * config.shouldLog('debug') // => true
949
- * ```
950
- */
951
364
  function createLogLevelConfig(level = 'error') {
952
365
  if (!isValidLogLevel(level)) {
953
366
  throw createError('Cannot create log level configuration with a valid default log level');
@@ -999,18 +412,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
999
412
  },
1000
413
  ];
1001
414
 
1002
- /**
1003
- * Gets the keys from an iterable target based on its data type.
1004
- *
1005
- * @param target - The target to get the keys from.
1006
- * @param dataType - The data type of the target.
1007
- * @returns The keys from the iterable target.
1008
- *
1009
- * @example Extracting keys from object
1010
- * ```typescript
1011
- * getKeysFromIterable({ a: 1, b: 2 }, 'object') // ['a', 'b']
1012
- * ```
1013
- */
1014
415
  const getKeysFromIterable = (target, dataType) => {
1015
416
  if (dataType === 'array')
1016
417
  dataType = Array.name;
@@ -1022,21 +423,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1022
423
  return iterableClass.getKeys(target);
1023
424
  };
1024
425
 
1025
- /**
1026
- * Returns the data type of the target.
1027
- * Uses native `typeof` operator, however, makes distinction between `null`, `array`, and `object`.
1028
- * Also, when classes are registered via `registerClass`, it checks if objects are instance of any known registered class.
1029
- *
1030
- * @param target - The target to get the data type of.
1031
- * @returns The data type of the target.
1032
- *
1033
- * @example Determining data types
1034
- * ```typescript
1035
- * getType([1, 2]) // 'array'
1036
- * getType({ a: 1 }) // 'object'
1037
- * getType(null) // 'null'
1038
- * ```
1039
- */
1040
426
  const getType = (target) => {
1041
427
  if (target === null)
1042
428
  return 'null';
@@ -1052,17 +438,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1052
438
  return nativeDataType;
1053
439
  };
1054
440
 
1055
- /**
1056
- * Returns a list of iterable data types. By default 'array' and 'object' are included.,
1057
- * but can be extended by using `registerIterableClass`.
1058
- *
1059
- * @returns Array of iterable data types.
1060
- *
1061
- * @example Listing registered iterable types
1062
- * ```typescript
1063
- * getIterableTypes() // ['array', 'object', ...registered types]
1064
- * ```
1065
- */
1066
441
  const getIterableTypes = () => registeredIterableClasses.map(({ classRef }) => {
1067
442
  const name = classRef.name;
1068
443
  if (name === Object.name)
@@ -1072,109 +447,19 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1072
447
  return name;
1073
448
  });
1074
449
 
1075
- /**
1076
- * Checks if the provided data type is registered as an iterable type.
1077
- *
1078
- * @param dataType - The data type to check
1079
- * @returns `true` if the data type is iterable, otherwise `false`
1080
- *
1081
- * @example Checking iterable types
1082
- * ```typescript
1083
- * isIterableType('array') // true
1084
- * isIterableType('object') // true
1085
- * isIterableType('string') // false
1086
- * ```
1087
- */
1088
450
  const isIterableType = (dataType) => getIterableTypes().includes(dataType);
1089
451
 
1090
- /**
1091
- * Checks if the target is iterable.
1092
- *
1093
- * @param target - The target to check.
1094
- * @returns `true` if the target is iterable, `false` otherwise.
1095
- *
1096
- * @example Checking if value is iterable
1097
- * ```typescript
1098
- * isIterable([1, 2]) // true
1099
- * isIterable({ a: 1 }) // true
1100
- * isIterable('string') // false
1101
- * ```
1102
- */
1103
452
  const isIterable = (target) => isIterableType(getType(target));
1104
453
 
1105
- /**
1106
- * Safe copies of Date built-in via factory function and static methods.
1107
- *
1108
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/date
1109
- */
1110
- /* eslint-disable jsdoc/require-param */
1111
454
  const _Date = globalThis.Date;
1112
- const _Reflect$4 = globalThis.Reflect;
1113
- /**
1114
- * (Safe copy) Creates a new Date using the captured Date constructor.
1115
- * Use this instead of `new Date()`. Accepts all standard Date constructor signatures.
1116
- *
1117
- * @returns A new Date instance.
1118
- *
1119
- * @example Creating Date instances
1120
- * ```typescript
1121
- * const now = createDate()
1122
- * const fromTimestamp = createDate(1704067200000)
1123
- * const fromString = createDate('2024-01-01T00:00:00Z')
1124
- * const fromParts = createDate(2024, 0, 1, 12, 30, 0) // Jan 1, 2024 12:30:00
1125
- * ```
1126
- */
455
+ const _Reflect$5 = globalThis.Reflect;
1127
456
  function createDate(...args) {
1128
- return _Reflect$4.construct(_Date, args);
1129
- }
1130
- /**
1131
- * (Safe copy) Returns the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC.
1132
- *
1133
- * @example
1134
- * ```typescript
1135
- * const timestamp = dateNow()
1136
- * // => 1704067200000 (example timestamp)
1137
- * ```
1138
- */
457
+ return _Reflect$5.construct(_Date, args);
458
+ }
1139
459
  const dateNow = _Date.now;
1140
- /**
1141
- * (Safe copy) Parses a string representation of a date.
1142
- *
1143
- * @example
1144
- * ```typescript
1145
- * const timestamp = dateParse('2024-01-01T00:00:00Z')
1146
- * // => 1704067200000
1147
- * ```
1148
- */
1149
460
  const dateParse = _Date.parse;
1150
- /**
1151
- * (Safe copy) Returns the number of milliseconds in a Date object since January 1, 1970 UTC.
1152
- *
1153
- * @example
1154
- * ```typescript
1155
- * const timestamp = dateUTC(2024, 0, 1, 12, 0, 0)
1156
- * // => 1704110400000 (Jan 1, 2024 12:00:00 UTC)
1157
- * ```
1158
- */
1159
461
  const dateUTC = _Date.UTC;
1160
462
 
1161
- /* eslint-disable @typescript-eslint/no-explicit-any */
1162
- /**
1163
- * Creates a wrapper function that only executes the wrapped function if the condition function returns true.
1164
- *
1165
- * @param func - The function to be conditionally executed.
1166
- * @param conditionFunc - A function that returns a boolean, determining if `func` should be executed.
1167
- * @returns A wrapped version of `func` that executes conditionally.
1168
- *
1169
- * @example Conditional logging based on flag
1170
- * ```typescript
1171
- * let enabled = false
1172
- * const conditionalLog = createConditionalExecutionFunction(console.log, () => enabled)
1173
- * conditionalLog('test') // does nothing
1174
- * enabled = true
1175
- * conditionalLog('test') // logs 'test'
1176
- * ```
1177
- */
1178
463
  function createConditionalExecutionFunction(func, conditionFunc) {
1179
464
  return function (...args) {
1180
465
  if (conditionFunc()) {
@@ -1183,77 +468,19 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1183
468
  };
1184
469
  }
1185
470
 
1186
- /* eslint-disable @typescript-eslint/no-explicit-any */
1187
- /**
1188
- * Creates a wrapper function that silently ignores any errors thrown by the wrapped void function.
1189
- * This function is specifically for wrapping functions that do not return a value (void functions).
1190
- * Exceptions are swallowed without any logging or handling.
1191
- *
1192
- * @param func - The void function to be wrapped.
1193
- * @returns A wrapped version of the input function that ignores errors.
1194
- *
1195
- * @example Safely parsing invalid JSON
1196
- * ```typescript
1197
- * const safeParse = createErrorIgnoringFunction(() => JSON.parse('invalid'))
1198
- * safeParse() // silently fails without throwing
1199
- * ```
1200
- */
1201
471
  function createErrorIgnoringFunction(func) {
1202
472
  return function (...args) {
1203
473
  try {
1204
474
  func(...args);
1205
475
  }
1206
476
  catch {
1207
- // Deliberately swallowing/ignoring the exception
1208
477
  }
1209
478
  };
1210
479
  }
1211
480
 
1212
- /* eslint-disable @typescript-eslint/no-unused-vars */
1213
- /**
1214
- * A no-operation function (noop) that does nothing regardless of the arguments passed.
1215
- * It is designed to be as permissive as possible in its typing without using the `Function` keyword.
1216
- *
1217
- * @param args - Any arguments passed to the function (ignored)
1218
- *
1219
- * @example Using noop as fallback callback
1220
- * ```typescript
1221
- * const callback = condition ? handleEvent : noop
1222
- * callback() // safely does nothing if condition is false
1223
- * ```
1224
- */
1225
481
  const noop = (...args) => {
1226
- // Intentionally does nothing
1227
482
  };
1228
483
 
1229
- /**
1230
- * Creates a logger instance with configurable log level filtering.
1231
- * Each log function is wrapped to respect the current log level setting.
1232
- *
1233
- * @param error - Function to handle error-level logs (required)
1234
- * @param warn - Function to handle warning-level logs (optional, defaults to noop)
1235
- * @param log - Function to handle standard logs (optional, defaults to noop)
1236
- * @param info - Function to handle info-level logs (optional, defaults to noop)
1237
- * @param debug - Function to handle debug-level logs (optional, defaults to noop)
1238
- * @returns A frozen logger object with log methods, level control, channel, and timing helpers
1239
- * @throws {ErrorLevelFn} When any provided log function is invalid
1240
- *
1241
- * @example Creating a logger with log level filtering
1242
- * ```typescript
1243
- * const logger = createLogger(console.error, console.warn, console.log)
1244
- * logger.setLogLevel('warn')
1245
- * logger.warn('Connection timeout') // logs
1246
- * logger.info('Request complete') // suppressed (below 'warn' level)
1247
- * ```
1248
- *
1249
- * @example Channeling and timing
1250
- * ```typescript
1251
- * const logger = createLogger(console.error, console.warn, console.log, console.info, console.debug)
1252
- * logger.setLogLevel('debug')
1253
- * const build = logger.channel('build')
1254
- * await build.timedAsync('bundle', async () => bundle())
1255
- * ```
1256
- */
1257
484
  function createLogger$1(error, warn = noop, log = noop, info = noop, debug = noop) {
1258
485
  if (notValidLogFn(error)) {
1259
486
  throw createError(notFnMsg('error'));
@@ -1288,20 +515,11 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1288
515
  };
1289
516
  return createPrefixedLogger(core, '');
1290
517
  }
1291
- /**
1292
- * Creates a Logger that prepends `[fullPrefix]` to every log call. When `fullPrefix`
1293
- * is empty, returns a Logger that delegates directly to the core functions.
1294
- *
1295
- * @param core - Shared level-aware log functions and level controls.
1296
- * @param fullPrefix - Channel chain joined with `:`, or `''` for the root logger.
1297
- * @returns A frozen Logger that emits with the resolved prefix.
1298
- */
1299
518
  function createPrefixedLogger(core, fullPrefix) {
1300
519
  const tag = fullPrefix ? `[${fullPrefix}]` : '';
1301
520
  const prefixed = (fn) => {
1302
521
  if (!tag)
1303
522
  return fn;
1304
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1305
523
  return (...data) => fn(tag, ...data);
1306
524
  };
1307
525
  const instance = freeze({
@@ -1322,14 +540,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1322
540
  });
1323
541
  return instance;
1324
542
  }
1325
- /**
1326
- * Times a sync call, logging completion at debug level or failure at error level.
1327
- *
1328
- * @param logger - The logger used to emit the timing message.
1329
- * @param label - Human-readable label for the timed operation.
1330
- * @param fn - The synchronous operation to invoke.
1331
- * @returns The value returned by `fn`.
1332
- */
1333
543
  function runTimed(logger, label, fn) {
1334
544
  const start = dateNow();
1335
545
  try {
@@ -1344,15 +554,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1344
554
  throw error;
1345
555
  }
1346
556
  }
1347
- /**
1348
- * Times an async call, logging completion at debug level or failure at error level.
1349
- * On rejection with an `Error` carrying a stack, the stack is also dumped at debug level.
1350
- *
1351
- * @param logger - The logger used to emit the timing message.
1352
- * @param label - Human-readable label for the timed operation.
1353
- * @param fn - The async operation to invoke.
1354
- * @returns The value resolved by `fn`'s promise.
1355
- */
1356
557
  async function runTimedAsync(logger, label, fn) {
1357
558
  const start = dateNow();
1358
559
  try {
@@ -1370,144 +571,42 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1370
571
  throw error;
1371
572
  }
1372
573
  }
1373
- /**
1374
- * Extracts a human-readable message from an unknown thrown value.
1375
- *
1376
- * @param error - The unknown value caught from a try/catch or rejected promise.
1377
- * @returns The error's `message` when it is an `Error`, otherwise its string coercion.
1378
- */
1379
574
  function describeError(error) {
1380
575
  return error instanceof Error ? error.message : String(error);
1381
576
  }
1382
- /**
1383
- * Validates whether a given value is a valid log function.
1384
- *
1385
- * @param fn - The value to validate
1386
- * @returns True if the value is not a function (invalid), false if it is valid
1387
- */
1388
577
  function notValidLogFn(fn) {
1389
578
  return getType(fn) !== 'function' && fn !== noop;
1390
579
  }
1391
- /**
1392
- * Generates an error message for invalid log function parameters.
1393
- *
1394
- * @param label - The name of the log function that failed validation
1395
- * @returns A formatted error message string
1396
- */
1397
580
  function notFnMsg(label) {
1398
581
  return `Cannot create a logger when ${label} is not a function`;
1399
582
  }
1400
583
 
1401
- /**
1402
- * Safe copies of Console built-in methods.
1403
- *
1404
- * These references are captured at module initialization time to protect against
1405
- * prototype pollution attacks. Import only what you need for tree-shaking.
1406
- *
1407
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/console
1408
- */
1409
584
  const _console = globalThis.console;
1410
- /**
1411
- * (Safe copy) Outputs a message to the console.
1412
- */
1413
585
  const log = _console.log.bind(_console);
1414
- /**
1415
- * (Safe copy) Outputs a warning message to the console.
1416
- */
1417
586
  const warn = _console.warn.bind(_console);
1418
- /**
1419
- * (Safe copy) Outputs an error message to the console.
1420
- */
1421
587
  const error = _console.error.bind(_console);
1422
- /**
1423
- * (Safe copy) Outputs an informational message to the console.
1424
- */
1425
588
  const info = _console.info.bind(_console);
1426
- /**
1427
- * (Safe copy) Outputs a debug message to the console.
1428
- */
1429
589
  const debug = _console.debug.bind(_console);
1430
- /**
1431
- * (Safe copy) Outputs a stack trace to the console.
1432
- */
1433
590
  _console.trace.bind(_console);
1434
- /**
1435
- * (Safe copy) Displays an interactive listing of the properties of a specified object.
1436
- */
1437
591
  _console.dir.bind(_console);
1438
- /**
1439
- * (Safe copy) Displays tabular data as a table.
1440
- */
1441
592
  _console.table.bind(_console);
1442
- /**
1443
- * (Safe copy) Writes an error message to the console if the assertion is false.
1444
- */
1445
593
  _console.assert.bind(_console);
1446
- /**
1447
- * (Safe copy) Clears the console.
1448
- */
1449
594
  _console.clear.bind(_console);
1450
- /**
1451
- * (Safe copy) Logs the number of times that this particular call to count() has been called.
1452
- */
1453
595
  _console.count.bind(_console);
1454
- /**
1455
- * (Safe copy) Resets the counter used with console.count().
1456
- */
1457
596
  _console.countReset.bind(_console);
1458
- /**
1459
- * (Safe copy) Creates a new inline group in the console.
1460
- */
1461
597
  _console.group.bind(_console);
1462
- /**
1463
- * (Safe copy) Creates a new inline group in the console that is initially collapsed.
1464
- */
1465
598
  _console.groupCollapsed.bind(_console);
1466
- /**
1467
- * (Safe copy) Exits the current inline group.
1468
- */
1469
599
  _console.groupEnd.bind(_console);
1470
- /**
1471
- * (Safe copy) Starts a timer with a name specified as an input parameter.
1472
- */
1473
600
  _console.time.bind(_console);
1474
- /**
1475
- * (Safe copy) Stops a timer that was previously started.
1476
- */
1477
601
  _console.timeEnd.bind(_console);
1478
- /**
1479
- * (Safe copy) Logs the current value of a timer that was previously started.
1480
- */
1481
602
  _console.timeLog.bind(_console);
1482
603
 
1483
604
  const logger = createLogger$1(error, warn, log, info, debug);
1484
605
 
1485
606
  const DEFAULT_PREFIX = '[nexus]';
1486
- /**
1487
- * Creates a logger instance configured for nexus.
1488
- *
1489
- * If a custom logger is provided, it will be used directly.
1490
- * Otherwise, a new logger will be created using the logging library.
1491
- *
1492
- * @param options - Logger configuration options
1493
- * @returns Logger instance
1494
- *
1495
- * @example Configuring logger options
1496
- * ```typescript
1497
- * const logger = createLogger({ level: 'debug', prefix: '[my-channel]' })
1498
- * logger.debug('Channel initialized')
1499
- * ```
1500
- */
1501
607
  function createLogger(options = {}) {
1502
608
  return createLoggerInternal(options);
1503
609
  }
1504
- /**
1505
- * Internal helper to create a logger with given options.
1506
- *
1507
- * @param options - Logger configuration options
1508
- * @returns Configured logger instance
1509
- * @internal
1510
- */
1511
610
  const createLoggerInternal = (options) => {
1512
611
  const { level = 'error', prefix = DEFAULT_PREFIX, customLogger } = options;
1513
612
  if (customLogger)
@@ -1518,31 +617,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1518
617
  return nexusLogger;
1519
618
  };
1520
619
 
1521
- /**
1522
- * Safe WeakSet factory for protected weak set construction.
1523
- *
1524
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/weak-set
1525
- */
1526
- /* eslint-disable workspace/lib-require-jsdoc-example */
1527
620
  const _WeakSet = globalThis.WeakSet;
1528
- const _Reflect$3 = globalThis.Reflect;
1529
- /**
1530
- * (Safe copy) Creates a new WeakSet using the captured WeakSet constructor.
1531
- * Use this instead of `new WeakSet()`.
1532
- *
1533
- * @param iterable - Optional iterable of values.
1534
- * @returns A new WeakSet instance.
1535
- */
1536
- const createWeakSet = (iterable) => _Reflect$3.construct(_WeakSet, iterable ? [iterable] : []);
1537
-
1538
- /**
1539
- * Checks whether an object has circular references using WeakSet.
1540
- * Safe for use with frozen objects since it only reads, never mutates.
1541
- *
1542
- * @param value - The value to check
1543
- * @param seen - WeakSet of already-seen references
1544
- * @returns True if circular reference detected
1545
- */
621
+ const _Reflect$4 = globalThis.Reflect;
622
+ const createWeakSet = (iterable) => _Reflect$4.construct(_WeakSet, iterable ? [iterable] : []);
623
+
1546
624
  function hasCircular(value, seen) {
1547
625
  if (!isIterable(value))
1548
626
  return false;
@@ -1559,36 +637,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1559
637
  }
1560
638
  return false;
1561
639
  }
1562
- /**
1563
- * Asserts that the given value does not contain circular references.
1564
- * Throws an Error if a circular reference is detected.
1565
- *
1566
- * Uses WeakSet-based cycle detection that works safely with frozen objects.
1567
- *
1568
- * @param value - The value to check for circular references
1569
- * @param paramName - Name of the parameter for error messaging
1570
- * @throws {Error} if circular reference is detected
1571
- *
1572
- * @example Checking for circular references
1573
- * ```typescript
1574
- * const config = { a: 1, b: 2 }
1575
- * assertNoCircularRef(config, 'config') // OK
1576
- *
1577
- * const circular: Record<string, unknown> = { a: 1 }
1578
- * circular.self = circular
1579
- * assertNoCircularRef(circular, 'config') // Throws Error
1580
- * ```
1581
- */
1582
640
  function assertNoCircularRef(value, paramName) {
1583
641
  if (hasCircular(value, createWeakSet())) {
1584
642
  throw createError(`Circular reference detected in parameter "${paramName}"`);
1585
643
  }
1586
644
  }
1587
645
 
1588
- /**
1589
- * Default channel settings.
1590
- * Accept any origin, queue messages, inherit contract from broker.
1591
- */
1592
646
  const DEFAULT_CHANNEL_SETTINGS = freeze({
1593
647
  origin: '*',
1594
648
  queueMessages: true,
@@ -1596,23 +650,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1596
650
  contract: undefined,
1597
651
  });
1598
652
 
1599
- /**
1600
- * Gracefully closes an active channel connection.
1601
- *
1602
- * - Only works if channel is currently active
1603
- * - Sets channel state to inactive
1604
- * - Optionally notifies the target window
1605
- * - Fires 'close' event to subscribers
1606
- *
1607
- * @param channel - Channel internals with state and dependencies
1608
- * @param notify - Whether to notify target window (default: true)
1609
- *
1610
- * @example Gracefully closing a connection
1611
- * ```typescript
1612
- * disconnect(channel, true) // Close and notify target
1613
- * disconnect(channel, false) // Close silently
1614
- * ```
1615
- */
1616
653
  function disconnect(channel, notify = true) {
1617
654
  const state = channel.getState();
1618
655
  if (!state.active) {
@@ -1627,22 +664,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1627
664
  channel.notifyEvent('close');
1628
665
  }
1629
666
 
1630
- /**
1631
- * Cancels a pending connection request.
1632
- *
1633
- * - If channel is closed, sends CANCEL_CONNECTION
1634
- * - If channel is already open, calls disconnect instead
1635
- * - Fires 'cancel' event to subscribers
1636
- *
1637
- * @param channel - Channel internals with state and dependencies
1638
- * @param notify - Whether to notify target window (default: true)
1639
- *
1640
- * @example Canceling a pending connection
1641
- * ```typescript
1642
- * cancel(channel, true) // Cancel and notify target
1643
- * cancel(channel, false) // Cancel silently
1644
- * ```
1645
- */
1646
667
  function cancel(channel, notify = true) {
1647
668
  const state = channel.getState();
1648
669
  if (state.active) {
@@ -1657,19 +678,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1657
678
  channel.notifyEvent('cancel');
1658
679
  }
1659
680
 
1660
- /**
1661
- * Clears all queued messages from the channel.
1662
- * Returns a new state object with empty queue (immutable update).
1663
- *
1664
- * @param state - Current channel state
1665
- * @returns New state with cleared message queue
1666
- *
1667
- * @example Clearing all queued messages
1668
- * ```typescript
1669
- * const clearedState = clearQueue(channelState)
1670
- * // => { ...channelState, queuedMessages: [] }
1671
- * ```
1672
- */
1673
681
  function clearQueue(state) {
1674
682
  return freeze({
1675
683
  ...state,
@@ -1677,21 +685,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1677
685
  });
1678
686
  }
1679
687
 
1680
- /**
1681
- * Adds a message to the channel's queue.
1682
- * Returns a new state object with the message appended (immutable update).
1683
- *
1684
- * @param state - Current channel state
1685
- * @param message - Message to queue
1686
- * @returns New state with message added to queue
1687
- *
1688
- * @example Adding a message to the queue
1689
- * ```typescript
1690
- * const message = { type: 'data', payload: { userId: 123 } }
1691
- * const updatedState = queueMessage(channelState, message)
1692
- * // => { ...channelState, queuedMessages: [...existingMessages, message] }
1693
- * ```
1694
- */
1695
688
  function queueMessage(state, message) {
1696
689
  return freeze({
1697
690
  ...state,
@@ -1699,33 +692,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1699
692
  });
1700
693
  }
1701
694
 
1702
- /**
1703
- * Queues a message for delivery when the channel opens.
1704
- *
1705
- * Messages are stored in the channel state and will be sent
1706
- * automatically when the channel becomes active via the flush operation.
1707
- *
1708
- * @param channel - Channel internals with state and dependencies
1709
- * @param message - Message to queue
1710
- *
1711
- * @example Queueing a message
1712
- * ```typescript
1713
- * queue(channel, { type: 'GREETING', data: 'Hello' })
1714
- * ```
1715
- */
1716
695
  function queue(channel, message) {
1717
696
  const state = channel.getState();
1718
697
  const newState = queueMessage(state, message);
1719
698
  channel.updateState(newState);
1720
699
  }
1721
700
 
1722
- /**
1723
- * Action types that should always be sent in plaintext.
1724
- *
1725
- * Handshake actions must remain unencrypted because:
1726
- * - Security negotiation happens during handshake
1727
- * - Both parties need to read handshake messages before security is established
1728
- */
1729
701
  const PLAINTEXT_ACTION_TYPES = createSet([
1730
702
  ACTION_TYPES.REQUEST_CONNECTION,
1731
703
  ACTION_TYPES.ACCEPT_CONNECTION,
@@ -1734,26 +706,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1734
706
  ACTION_TYPES.CANCEL_CONNECTION_ACKNOWLEDGED,
1735
707
  ACTION_TYPES.OPEN_CONNECTION,
1736
708
  ]);
1737
- /**
1738
- * Sends a raw action to the channel's target window.
1739
- *
1740
- * This function routes actions through the security transport when:
1741
- * - The channel has a security transport configured
1742
- * - The security transport is ready
1743
- * - The action type is not a handshake action (handshakes are always plaintext)
1744
- *
1745
- * For secure protocols (v1/v2), the action is encrypted and sent as Uint8Array.
1746
- * For 'none' protocol or handshake actions, the action is sent as plain object.
1747
- *
1748
- * @param channel - Channel internals with state and dependencies
1749
- * @param action - Action to send
1750
- *
1751
- * @example Sending an action to the target window
1752
- * ```typescript
1753
- * const action = channel.actions.requestConnection(processId)
1754
- * sendAction(channel, action)
1755
- * ```
1756
- */
1757
709
  function sendAction(channel, action) {
1758
710
  const state = channel.getState();
1759
711
  if (!action || typeof action.type !== 'string') {
@@ -1768,29 +720,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1768
720
  state.target.postMessage(action, '*');
1769
721
  }
1770
722
 
1771
- /**
1772
- * Sends a typed message through an active channel.
1773
- *
1774
- * Message routing behavior:
1775
- * - If channel is closed and queueMessages is enabled, queues the message
1776
- * - If channel is closed and queueMessages is disabled, throws error
1777
- * - If security transport exists but is not ready, queues the message
1778
- * - If channel is open and security is ready (or protocol is 'none'), sends message
1779
- *
1780
- * For secure protocols (v1/v2), the message is routed through the security
1781
- * transport which encrypts and sends as Uint8Array via postMessage.
1782
- *
1783
- * @param channel - Channel internals with state and dependencies
1784
- * @param message - Message to send with type and data
1785
- *
1786
- * @throws {Error} If channel is closed and queueing is disabled
1787
- * @throws {Error} If message type is not accepted in channel contract
1788
- *
1789
- * @example Sending a typed message
1790
- * ```typescript
1791
- * send(channel, { type: 'USER_ACTION', data: { userId: 123 } })
1792
- * ```
1793
- */
1794
723
  function send(channel, message) {
1795
724
  const state = channel.getState();
1796
725
  if (!state.active) {
@@ -1813,24 +742,11 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1813
742
  if (!emittedTypes.includes(message.type)) {
1814
743
  throw createError(`Cannot send message to ${state.name} channel. Message type '${message.type}' is not in the emitted actions of channel contract.`);
1815
744
  }
1816
- const action = channel.actions.newMessage(message.data);
745
+ const action = channel.actions.newMessage(message);
1817
746
  sendAction(channel, action);
1818
747
  channel.notifyMessage(message);
1819
748
  }
1820
749
 
1821
- /**
1822
- * Sends all queued messages and clears the queue.
1823
- *
1824
- * Called automatically when a channel opens if queueMessages is enabled.
1825
- * Messages are sent in FIFO order.
1826
- *
1827
- * @param channel - Channel internals with state and dependencies
1828
- *
1829
- * @example Flushing queued messages
1830
- * ```typescript
1831
- * flush(channel) // Sends all queued messages
1832
- * ```
1833
- */
1834
750
  function flush(channel) {
1835
751
  const state = channel.getState();
1836
752
  for (const message of state.queuedMessages) {
@@ -1847,20 +763,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1847
763
  channel.updateState(newState);
1848
764
  }
1849
765
 
1850
- /**
1851
- * Initiates the connection handshake for a channel.
1852
- *
1853
- * - If channel is already open, does nothing
1854
- * - If channel has a scheduled activation (pending connection), accepts it
1855
- * - Otherwise, sends REQUEST_CONNECTION to initiate handshake
1856
- *
1857
- * @param channel - Channel internals with state and dependencies
1858
- *
1859
- * @example Initiating a connection
1860
- * ```typescript
1861
- * connect(channel) // Sends REQUEST_CONNECTION or accepts pending
1862
- * ```
1863
- */
1864
766
  function connect(channel) {
1865
767
  const state = channel.getState();
1866
768
  if (state.active) {
@@ -1902,24 +804,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1902
804
  channel.sendAction(requestAction);
1903
805
  }
1904
806
 
1905
- /**
1906
- * Immediately destroys a channel and removes it from the broker.
1907
- *
1908
- * - Sets channel to inactive immediately
1909
- * - Optionally notifies the target window
1910
- * - Removes channel from all registries
1911
- * - Fires 'destroy' event to subscribers
1912
- * - This is irreversible - channel cannot be reconnected
1913
- *
1914
- * @param channel - Channel internals with state and dependencies
1915
- * @param notify - Whether to notify target window (default: true)
1916
- *
1917
- * @example Destroying a channel
1918
- * ```typescript
1919
- * destroy(channel, true) // Destroy and notify target
1920
- * destroy(channel, false) // Destroy silently
1921
- * ```
1922
- */
1923
807
  function destroy(channel, notify = true) {
1924
808
  channel.updateState({ active: false });
1925
809
  if (notify) {
@@ -1931,22 +815,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1931
815
  }
1932
816
  }
1933
817
 
1934
- /**
1935
- * Activates a channel by setting it as active and recording connection details.
1936
- * Returns a new state object (immutable update).
1937
- *
1938
- * @param state - Current channel state
1939
- * @param origin - Origin of the connected channel
1940
- * @param contract - Negotiated channel contract
1941
- * @returns New state with channel activated
1942
- *
1943
- * @example Activating a channel with contract
1944
- * ```typescript
1945
- * const contract = { accepted: [{ type: 'message' }] }
1946
- * const activeState = activate(channelState, 'https://example.com', contract)
1947
- * // => { ...channelState, active: true, origin: 'https://example.com', ... }
1948
- * ```
1949
- */
1950
818
  function activate(state, origin, contract) {
1951
819
  const acceptedActions = (contract.accepted || []).map((action) => action.type);
1952
820
  return freeze({
@@ -1960,21 +828,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
1960
828
  });
1961
829
  }
1962
830
 
1963
- /**
1964
- * Creates the initial state for a new channel.
1965
- * All collections are empty, all optional fields are null.
1966
- *
1967
- * @param name - Channel name/identifier
1968
- * @param target - Target window for communication
1969
- * @param settings - Channel settings (queueMessages, debug, logger, etc.)
1970
- * @returns Fresh channel state object
1971
- *
1972
- * @example Creating initial channel state
1973
- * ```typescript
1974
- * const state = createInitialState('my-channel', targetWindow, { queueMessages: true })
1975
- * // => { id: '...', name: 'my-channel', active: false, queuedMessages: [], ... }
1976
- * ```
1977
- */
1978
831
  function createInitialState(name, target, settings) {
1979
832
  return freeze({
1980
833
  id: uuidV4(),
@@ -2000,26 +853,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2000
853
  });
2001
854
  }
2002
855
 
2003
- /**
2004
- * Implementation of subscribeToEvents that handles both overload signatures.
2005
- *
2006
- * @param channel - The channel internals object
2007
- * @param eventOrHandler - Either an event name or a handler function
2008
- * @param handler - Handler function when event name is provided
2009
- * @returns Unsubscribe function to remove the handler
2010
- *
2011
- * @example Subscribing to all events with cleanup
2012
- * ```typescript
2013
- * const unsubscribe = subscribeToEvents(channel, (event, data) => {
2014
- * if (event === 'open') {
2015
- * console.log('Channel opened:', data)
2016
- * }
2017
- * })
2018
- *
2019
- * // Cleanup when no longer needed
2020
- * unsubscribe()
2021
- * ```
2022
- */
2023
856
  function subscribeToEvents(channel, eventOrHandler, handler) {
2024
857
  const isEventSpecific = typeof eventOrHandler === 'string' && typeof handler === 'function';
2025
858
  let wrappedHandler;
@@ -2051,26 +884,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2051
884
  };
2052
885
  }
2053
886
 
2054
- /**
2055
- * Subscribes to incoming messages on the channel.
2056
- *
2057
- * Handler will be called with each message received from the target window.
2058
- *
2059
- * @param channel - Channel internals with state and dependencies
2060
- * @param handler - Message handler function
2061
- * @returns Unsubscribe function to remove the handler
2062
- *
2063
- * @throws {Error} If handler is not a function
2064
- *
2065
- * @example Subscribing to channel messages
2066
- * ```typescript
2067
- * const unsubscribe = subscribeToMessages(channel, (message) => {
2068
- * console.log('Message:', message.type, message.data)
2069
- * })
2070
- *
2071
- * // Later: unsubscribe()
2072
- * ```
2073
- */
2074
887
  function subscribeToMessages(channel, handler) {
2075
888
  if (typeof handler !== 'function') {
2076
889
  throw createError('Expected callback function.');
@@ -2085,32 +898,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2085
898
  };
2086
899
  }
2087
900
 
2088
- /**
2089
- * Logs a channel event in a structured format.
2090
- *
2091
- * @param logger - Logger instance to use
2092
- * @param event - Type of channel event that occurred
2093
- * @param data - Additional data associated with the event
2094
- */
2095
901
  function logEvent(logger, event, data) {
2096
902
  logger.debug(`Channel event:`, event, data);
2097
903
  }
2098
904
 
2099
- /**
2100
- * Notifies all event subscribers of a channel event.
2101
- *
2102
- * Calls each subscribed event handler with the event type, optional data, and channel JSON.
2103
- * Errors in handlers are caught and logged to prevent breaking other handlers.
2104
- *
2105
- * @param channel - Channel internals with state and dependencies
2106
- * @param event - Event type that occurred
2107
- * @param data - Optional event data
2108
- *
2109
- * @example Notifying subscribers of an event
2110
- * ```typescript
2111
- * notifyEvent(channel, 'open', { timestamp: Date.now() })
2112
- * ```
2113
- */
2114
905
  function notifyEvent(channel, event, data) {
2115
906
  const state = channel.getState();
2116
907
  if (state.logger) {
@@ -2137,20 +928,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2137
928
  }
2138
929
  }
2139
930
 
2140
- /**
2141
- * Notifies all message subscribers of an incoming message.
2142
- *
2143
- * Calls each subscribed message handler with the message data.
2144
- * Errors in handlers are caught and logged to prevent breaking other handlers.
2145
- *
2146
- * @param channel - Channel internals with state and dependencies
2147
- * @param message - Message that was received
2148
- *
2149
- * @example Notifying subscribers of a message
2150
- * ```typescript
2151
- * notifyMessage(channel, { type: 'USER_ACTION', data: { userId: 123 } })
2152
- * ```
2153
- */
2154
931
  function notifyMessage(channel, message) {
2155
932
  const state = channel.getState();
2156
933
  for (const handler of state.messageSubscriptions) {
@@ -2165,26 +942,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2165
942
  }
2166
943
  }
2167
944
 
2168
- /**
2169
- * Creates a new message channel.
2170
- *
2171
- * Uses functional programming with closures for encapsulation.
2172
- * Returns a public handle with methods while keeping state private.
2173
- *
2174
- * @param config - Channel configuration (name, target, settings)
2175
- * @param deps - Dependencies (action creators, process manager, cleanup)
2176
- * @returns Channel handle with public API
2177
- *
2178
- * @example Creating and using a channel
2179
- * ```typescript
2180
- * const channel = createChannel(
2181
- * { name: 'my-channel', target: childWindow },
2182
- * { actions, processManager, cleanup }
2183
- * )
2184
- * channel.connect()
2185
- * channel.send('greet', { message: 'Hello!' })
2186
- * ```
2187
- */
2188
945
  function createChannel(config, deps) {
2189
946
  assertNoCircularRef(config.settings, 'config.settings');
2190
947
  const settings = { ...DEFAULT_CHANNEL_SETTINGS, ...config.settings };
@@ -2220,6 +977,7 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2220
977
  getName: () => state.name,
2221
978
  getTarget: () => state.target,
2222
979
  isActive: () => state.active,
980
+ getAcceptedTypes: () => state.acceptedActions,
2223
981
  toJSON: () => ({
2224
982
  id: state.id,
2225
983
  name: state.name,
@@ -2288,72 +1046,18 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2288
1046
  return freeze(handle);
2289
1047
  }
2290
1048
 
2291
- /**
2292
- * Adds a channel to the registry, making it available for lookup
2293
- * by window, ID, and name.
2294
- *
2295
- * @param registry - The channel registry instance
2296
- * @param channel - Channel to register (must have id, name, target)
2297
- * @throws {Error} Error if channel is invalid
2298
- *
2299
- * @example Registering a channel
2300
- * ```typescript
2301
- * const registry = createRegistry()
2302
- * add(registry, { id: 'ch-1', name: 'main', target: iframe.contentWindow })
2303
- * ```
2304
- */
2305
1049
  function add(registry, channel) {
2306
1050
  registry.add(channel);
2307
1051
  }
2308
1052
 
2309
- /**
2310
- * Finds a channel by its target window.
2311
- * Uses WeakMap for O(1) lookup that doesn't prevent garbage collection.
2312
- *
2313
- * @param registry - The channel registry instance
2314
- * @param target - The window to look up
2315
- * @returns Channel if found, undefined otherwise
2316
- */
2317
1053
  function getByWindow(registry, target) {
2318
1054
  return registry.getByWindow(target);
2319
1055
  }
2320
1056
 
2321
- /**
2322
- * Removes a channel from the registry, making it unavailable
2323
- * for all lookup methods.
2324
- *
2325
- * @param registry - The channel registry instance
2326
- * @param channel - Channel to unregister
2327
- */
2328
1057
  function remove(registry, channel) {
2329
1058
  registry.remove(channel);
2330
1059
  }
2331
1060
 
2332
- /**
2333
- * Adds a channel to the broker.
2334
- *
2335
- * @param state - Current broker state
2336
- * @param registry - Channel registry for storing and retrieving channels
2337
- * @param processManager - Process ID manager for tracking communication processes
2338
- * @param actions - Action creators from broker for managing channel lifecycle
2339
- * @param name - Unique identifier for the channel
2340
- * @param target - Target window to communicate with
2341
- * @param settings - Optional configuration settings for the channel
2342
- * @returns The created or existing channel
2343
- *
2344
- * @example Registering a channel with the broker
2345
- * ```typescript
2346
- * const channel = addChannel(
2347
- * brokerState,
2348
- * registry,
2349
- * processManager,
2350
- * actions,
2351
- * 'widget-channel',
2352
- * iframe.contentWindow,
2353
- * { timeout: 5000 }
2354
- * )
2355
- * ```
2356
- */
2357
1061
  function addChannel(state, registry, processManager, actions, name, target, settings = {}) {
2358
1062
  assertNoCircularRef(settings, 'settings');
2359
1063
  const existing = getByWindow(registry, target);
@@ -2380,43 +1084,14 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2380
1084
  return channel;
2381
1085
  }
2382
1086
 
2383
- /**
2384
- * Finds a channel by its unique ID.
2385
- * Uses Map for O(1) lookup.
2386
- *
2387
- * @param registry - The channel registry instance
2388
- * @param id - The channel ID (UUID) to look up
2389
- * @returns Channel if found, undefined otherwise
2390
- */
2391
1087
  function getById(registry, id) {
2392
1088
  return registry.getById(id);
2393
1089
  }
2394
1090
 
2395
- /**
2396
- * Finds a channel by its name.
2397
- * Uses Map for O(1) lookup.
2398
- *
2399
- * @param registry - The channel registry instance
2400
- * @param name - The channel name to look up
2401
- * @returns Channel if found, undefined otherwise
2402
- */
2403
1091
  function getByName(registry, name) {
2404
1092
  return registry.getByName(name);
2405
1093
  }
2406
1094
 
2407
- /**
2408
- * Gets a channel by reference (id, name, or window)
2409
- *
2410
- * @param registry - Channel registry containing all registered channels
2411
- * @param reference - Channel identifier (id, name, or window object)
2412
- * @returns The channel if found, null otherwise
2413
- *
2414
- * @example Retrieving channels by name or window
2415
- * ```typescript
2416
- * const channelByName = getChannel(registry, 'widget-channel')
2417
- * const channelByWindow = getChannel(registry, iframe.contentWindow)
2418
- * ```
2419
- */
2420
1095
  function getChannel(registry, reference) {
2421
1096
  if (typeof reference === 'object' && reference !== null) {
2422
1097
  const channel = getByWindow(registry, reference);
@@ -2429,64 +1104,20 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2429
1104
  return null;
2430
1105
  }
2431
1106
 
2432
- /**
2433
- * Returns all registered channels as an array.
2434
- * The order is not guaranteed.
2435
- *
2436
- * @param registry - The channel registry instance
2437
- * @returns Array of all registered channels
2438
- *
2439
- * @example Listing registered channels
2440
- * ```typescript
2441
- * const registry = createRegistry()
2442
- * const channels = getAll(registry)
2443
- * channels.forEach(ch => console.log(ch.name))
2444
- * ```
2445
- */
2446
1107
  function getAll(registry) {
2447
1108
  return registry.getAll();
2448
1109
  }
2449
1110
 
2450
- /**
2451
- * Lists all channels in JSON format
2452
- *
2453
- * @param registry - Channel registry containing all registered channels
2454
- * @returns Array of channel JSON representations
2455
- *
2456
- * @example Listing all channels as JSON
2457
- * ```typescript
2458
- * const channels = listChannels(registry)
2459
- * // => [{ id: 'abc-123', name: 'widget', state: 'connected' }, ...]
2460
- * ```
2461
- */
2462
1111
  function listChannels(registry) {
2463
1112
  const channels = getAll(registry);
2464
1113
  return channels.map((channel) => channel.toJSON());
2465
1114
  }
2466
1115
 
2467
- /**
2468
- * Removes a channel from the broker
2469
- *
2470
- * @param registry - Channel registry from which to remove the channel
2471
- * @param channel - The channel instance to cleanup and remove
2472
- *
2473
- * @example Removing a channel from the broker
2474
- * ```typescript
2475
- * const channel = getChannel(registry, 'widget-channel')
2476
- * if (channel) {
2477
- * removeChannel(registry, channel)
2478
- * }
2479
- * ```
2480
- */
2481
1116
  function removeChannel(registry, channel) {
2482
1117
  channel.destroy(false);
2483
1118
  remove(registry, channel);
2484
1119
  }
2485
1120
 
2486
- /**
2487
- * Default broker settings
2488
- * Used when settings are partially provided
2489
- */
2490
1121
  const defaultBrokerSettings = freeze({
2491
1122
  whitelist: freeze([]),
2492
1123
  blacklist: freeze([]),
@@ -2494,21 +1125,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2494
1125
  logLevel: 'error',
2495
1126
  });
2496
1127
 
2497
- /**
2498
- * Creates a router map for action types to handlers.
2499
- *
2500
- * @param handlers - Map of action types to handler functions
2501
- * @returns Router map
2502
- *
2503
- * @example Creating a router for action handlers
2504
- * ```typescript
2505
- * const router = createRouter({
2506
- * 'OPEN': handleOpen,
2507
- * 'CLOSE': handleClose,
2508
- * 'MESSAGE': handleMessage,
2509
- * })
2510
- * ```
2511
- */
2512
1128
  function createRouter(handlers) {
2513
1129
  const router = createMap();
2514
1130
  entries(handlers).forEach(([type, handler]) => {
@@ -2517,21 +1133,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2517
1133
  return router;
2518
1134
  }
2519
1135
 
2520
- /**
2521
- * Applies a security policy to a connection request.
2522
- *
2523
- * @param policy - The security policy function
2524
- * @param event - The MessageEvent to validate
2525
- * @param logger - Logger instance for error reporting
2526
- * @returns true if policy allows connection, false otherwise
2527
- *
2528
- * @example Validating connection requests with security policy
2529
- * ```typescript
2530
- * const policy = (event) => event.origin === 'https://trusted.example.com'
2531
- * const allowed = applyPolicy(policy, messageEvent, logger)
2532
- * // => true or false
2533
- * ```
2534
- */
2535
1136
  function applyPolicy(policy, event, logger) {
2536
1137
  try {
2537
1138
  const result = policy(event);
@@ -2543,27 +1144,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2543
1144
  }
2544
1145
  }
2545
1146
 
2546
- /**
2547
- * Handles ACCEPT_CONNECTION action.
2548
- * Completes connection handshake from the initiator's side.
2549
- *
2550
- * @param context - Routing context with state, registry, actions, and logger
2551
- * @param message - Message event containing the ACCEPT_CONNECTION action
2552
- *
2553
- * @remarks
2554
- * Side Effects:
2555
- * - Activates the channel
2556
- * - Extracts negotiated security protocol (if present)
2557
- * - Stores negotiated protocol in channel state
2558
- * - Sends OPEN_CONNECTION to complete handshake (with security confirmation)
2559
- * - Terminates process after activation
2560
- * - Fires 'open' lifecycle event
2561
- *
2562
- * @example Three-way handshake acceptance
2563
- * Second step of three-way handshake:
2564
- * Initiator <- ACCEPT (this handler) <- Responder
2565
- * Initiator -> OPEN -> Responder
2566
- */
2567
1147
  function handleAccept(context, message) {
2568
1148
  const { state, processManager, logger } = context;
2569
1149
  const action = message.data;
@@ -2626,33 +1206,22 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2626
1206
  channel.notifyEvent('open', { origin: message.origin, contract });
2627
1207
  }
2628
1208
 
2629
- /**
2630
- * Handles CANCEL_CONNECTION action.
2631
- * Processes connection cancellation request.
2632
- *
2633
- * @param context - Routing context with state, registry, actions, and logger
2634
- * @param message - Message event containing the CANCEL_CONNECTION action
2635
- *
2636
- * @remarks
2637
- * Side Effects:
2638
- * - Cancels pending connection
2639
- * - Sends CANCEL_CONNECTION_ACKNOWLEDGED response
2640
- * - Terminates process
2641
- * - Fires 'cancel' lifecycle event
2642
- *
2643
- * @example Cancellation flow during connection
2644
- * Cancel flow (before connection completes):
2645
- * Side A -> CANCEL_CONNECTION
2646
- * Side B <- CANCEL (this handler)
2647
- * Side B -> CANCEL_ACKNOWLEDGED
2648
- * Both sides fire 'cancel' event
2649
- */
1209
+ function resolveChannel(registry, message) {
1210
+ const source = message.source;
1211
+ if (source) {
1212
+ const channel = registry.getByWindow(source);
1213
+ if (channel) {
1214
+ return channel;
1215
+ }
1216
+ }
1217
+ return registry.getById(message.data.senderId);
1218
+ }
1219
+
2650
1220
  function handleCancel(context, message) {
2651
1221
  const { state, registry, processManager } = context;
2652
1222
  const action = message.data;
2653
- const senderId = action['senderId'];
2654
1223
  const processId = action['processId'];
2655
- const channel = (getById(registry, senderId) || processManager.get(processId));
1224
+ const channel = (resolveChannel(registry, message) || processManager.get(processId));
2656
1225
  if (!channel) {
2657
1226
  return;
2658
1227
  }
@@ -2666,24 +1235,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2666
1235
  channel.notifyEvent('cancel', { notify: true });
2667
1236
  }
2668
1237
 
2669
- /**
2670
- * Handles CANCEL_CONNECTION_ACKNOWLEDGED action.
2671
- * Completes cancellation on initiator's side and notifies cancel event.
2672
- *
2673
- * @param context - Routing context with state, registry, actions, and logger
2674
- * @param message - Message event containing the CANCEL_CONNECTION_ACKNOWLEDGED action
2675
- *
2676
- * @remarks
2677
- * Side Effects:
2678
- * - Terminates the connection process
2679
- * - Fires 'cancel' lifecycle event on initiator's side
2680
- *
2681
- * @example Initiator-side cancellation acknowledgment
2682
- * Cancellation acknowledgment (initiator side):
2683
- * Initiator -> CANCEL_CONNECTION
2684
- * Initiator <- CANCEL_ACKNOWLEDGED (this handler)
2685
- * Initiator fires 'cancel' event
2686
- */
2687
1238
  function handleCancelAcknowledged(context, message) {
2688
1239
  const { processManager } = context;
2689
1240
  const action = message.data;
@@ -2696,36 +1247,14 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2696
1247
  channel.notifyEvent('cancel', { notify: false });
2697
1248
  }
2698
1249
 
2699
- /**
2700
- * Handles CLOSE_CONNECTION action.
2701
- * Gracefully closes an open connection.
2702
- *
2703
- * @param context - Routing context with state, registry, actions, and logger
2704
- * @param message - Message event containing the CLOSE_CONNECTION action
2705
- *
2706
- * @remarks
2707
- * Side Effects:
2708
- * - Deactivates the channel
2709
- * - Sends CLOSE_CONNECTION_ACKNOWLEDGED response
2710
- * - Terminates process
2711
- * - Fires 'close' lifecycle event
2712
- *
2713
- * @example Graceful disconnect flow
2714
- * Disconnect flow:
2715
- * Side A -> CLOSE_CONNECTION (initiates)
2716
- * Side B <- CLOSE_CONNECTION (this handler)
2717
- * Side B -> CLOSE_ACKNOWLEDGED
2718
- * Both sides fire 'close' event
2719
- */
2720
1250
  function handleClose(context, message) {
2721
1251
  const { state, registry, processManager } = context;
2722
1252
  const action = message.data;
2723
- const senderId = action.senderId;
2724
1253
  if (!('processId' in action)) {
2725
1254
  return;
2726
1255
  }
2727
1256
  const processId = action.processId;
2728
- const channel = getById(registry, senderId);
1257
+ const channel = resolveChannel(registry, message);
2729
1258
  if (!channel || !channel.isActive()) {
2730
1259
  return;
2731
1260
  }
@@ -2739,18 +1268,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2739
1268
  channel.notifyEvent('close', { notify: true });
2740
1269
  }
2741
1270
 
2742
- /**
2743
- * Handles CLOSE_CONNECTION_ACKNOWLEDGED action.
2744
- * Completes close on initiator's side and notifies close event.
2745
- *
2746
- * @param context - Routing context with state, registry, actions, and logger
2747
- * @param message - Message event containing the CLOSE_CONNECTION_ACKNOWLEDGED action
2748
- *
2749
- * @example Handling close acknowledgment
2750
- * ```typescript
2751
- * handleCloseAcknowledged(routingContext, closeAcknowledgedEvent)
2752
- * ```
2753
- */
2754
1271
  function handleCloseAcknowledged(context, message) {
2755
1272
  const { processManager } = context;
2756
1273
  const action = message.data;
@@ -2763,25 +1280,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2763
1280
  channel.notifyEvent('close', { notify: false });
2764
1281
  }
2765
1282
 
2766
- /**
2767
- * Handles DENY_CONNECTION action.
2768
- * Processes connection denial from remote broker.
2769
- *
2770
- * @param context - Routing context with state, registry, actions, and logger
2771
- * @param message - Message event containing the DENY_CONNECTION action
2772
- *
2773
- * @remarks
2774
- * Side Effects:
2775
- * - Terminates the connection process
2776
- * - Fires 'deny' lifecycle event with error details
2777
- *
2778
- * @example Connection denial during handshake
2779
- * Denial flow (during handshake):
2780
- * Initiator -> REQUEST_CONNECTION
2781
- * Responder validates and rejects
2782
- * Initiator <- DENY_CONNECTION (this handler)
2783
- * Initiator fires 'deny' event
2784
- */
2785
1283
  function handleDeny(context, message) {
2786
1284
  const { processManager } = context;
2787
1285
  const action = message.data;
@@ -2795,55 +1293,15 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2795
1293
  channel.notifyEvent('deny', { error, origin: message.origin });
2796
1294
  }
2797
1295
 
2798
- /**
2799
- * Handles DESTROY_CONNECTION action.
2800
- * Immediately destroys a connection without handshake.
2801
- *
2802
- * @param context - Routing context with state, registry, actions, and logger
2803
- * @param message - Message event containing the DESTROY_CONNECTION action
2804
- *
2805
- * @remarks
2806
- * Side Effects:
2807
- * - Immediately destroys channel (no acknowledgment)
2808
- * - Removes channel from registry
2809
- * - No lifecycle event fired (forceful termination)
2810
- *
2811
- * @example Forceful connection termination
2812
- * Forceful termination (e.g., window unload):
2813
- * channel.destroy()
2814
- * -> DESTROY_CONNECTION sent
2815
- * -> Remote receives (this handler)
2816
- * -> Channel immediately removed
2817
- */
2818
1296
  function handleDestroy(context, message) {
2819
1297
  const { registry } = context;
2820
- const action = message.data;
2821
- const senderId = action.senderId;
2822
- const channel = getById(registry, senderId);
1298
+ const channel = resolveChannel(registry, message);
2823
1299
  if (!channel) {
2824
1300
  return;
2825
1301
  }
2826
1302
  channel.destroy(false);
2827
1303
  }
2828
1304
 
2829
- /**
2830
- * Handles INVALID_REQUEST action.
2831
- * Processes error responses from remote broker.
2832
- *
2833
- * @param context - Routing context with state, registry, actions, and logger
2834
- * @param message - Message event containing the INVALID_REQUEST action
2835
- *
2836
- * @remarks
2837
- * Side Effects:
2838
- * - Fires 'invalid' lifecycle event with error details
2839
- *
2840
- * @example Handling protocol violations
2841
- * Protocol violation detected:
2842
- * Initiator sends malformed action
2843
- * Responder detects violation
2844
- * Initiator <- INVALID_REQUEST (this handler)
2845
- * Initiator fires 'invalid' event with reason
2846
- */
2847
1305
  function handleInvalid(context, message) {
2848
1306
  const { processManager } = context;
2849
1307
  const action = message.data;
@@ -2887,67 +1345,18 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2887
1345
  additionalProperties: additionalProperties
2888
1346
  };
2889
1347
 
2890
- /**
2891
- * Safe copies of JSON built-in methods.
2892
- *
2893
- * These references are captured at module initialization time to protect against
2894
- * prototype pollution attacks. Import only what you need for tree-shaking.
2895
- *
2896
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/json
2897
- */
2898
1348
  const _JSON = globalThis.JSON;
2899
- /**
2900
- * (Safe copy) Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
2901
- */
2902
1349
  const stringify = _JSON.stringify;
2903
1350
 
2904
- /**
2905
- * Safe copies of Number built-in methods and constants.
2906
- *
2907
- * These references are captured at module initialization time to protect against
2908
- * prototype pollution attacks. Import only what you need for tree-shaking.
2909
- *
2910
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/number
2911
- */
2912
1351
  const _Number = globalThis.Number;
2913
1352
  const _parseInt = globalThis.parseInt;
2914
1353
  const _isNaN = globalThis.isNaN;
2915
1354
  const _isFinite = globalThis.isFinite;
2916
- /**
2917
- * (Safe copy) Determines whether the passed value is an integer.
2918
- */
2919
1355
  const isInteger = _Number.isInteger;
2920
- /**
2921
- * (Safe copy) Parses a string and returns an integer.
2922
- */
2923
1356
  const parseInt = _parseInt;
2924
- /**
2925
- * (Safe copy) Global isNaN function (coerces to number first, less strict than Number.isNaN).
2926
- */
2927
1357
  const globalIsNaN = _isNaN;
2928
- /**
2929
- * (Safe copy) Global isFinite function (coerces to number first, less strict than Number.isFinite).
2930
- */
2931
1358
  const globalIsFinite = _isFinite;
2932
1359
 
2933
- /**
2934
- * Creates a new validation context.
2935
- *
2936
- * @param rootSchema - The root schema being validated against
2937
- * @param validator - The schema validator function
2938
- * @param collectAllErrors - Whether to collect all errors (default: true)
2939
- * @param strictPatterns - Whether to report errors for invalid regex patterns (default: false)
2940
- * @param patternSafetyChecker - Optional pattern safety checker for ReDoS detection
2941
- * @returns A new validation context
2942
- * @example Creating validation context
2943
- * ```typescript
2944
- * const schema = { type: 'string' }
2945
- * const ctx = createValidationContext(schema, validateSchema)
2946
- * // ctx.path === ''
2947
- * // ctx.errors === []
2948
- * // ctx.collectAllErrors === true
2949
- * ```
2950
- */
2951
1360
  function createValidationContext(rootSchema, validator, collectAllErrors = true, strictPatterns = false, patternSafetyChecker) {
2952
1361
  const definitions = createMap();
2953
1362
  if (rootSchema.definitions) {
@@ -2966,21 +1375,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2966
1375
  validate: validator,
2967
1376
  };
2968
1377
  }
2969
- /**
2970
- * Creates a child context with updated path.
2971
- *
2972
- * @param ctx - Parent context
2973
- * @param segment - Path segment to append
2974
- * @returns New context with updated path
2975
- * @example Creating child context with path
2976
- * ```typescript
2977
- * const ctx = createValidationContext(schema, validate)
2978
- * const childCtx = pushPath(ctx, 'items')
2979
- * // childCtx.path === '/items'
2980
- * const nestedCtx = pushPath(childCtx, 0)
2981
- * // nestedCtx.path === '/items/0'
2982
- * ```
2983
- */
2984
1378
  function pushPath(ctx, segment) {
2985
1379
  const escapedSegment = String(segment).replace(/~/g, '~0').replace(/\//g, '~1');
2986
1380
  return {
@@ -2988,22 +1382,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
2988
1382
  path: `${ctx.path}/${escapedSegment}`,
2989
1383
  };
2990
1384
  }
2991
- /**
2992
- * Adds a validation error to the context.
2993
- *
2994
- * @param ctx - Validation context
2995
- * @param message - Human-readable error message
2996
- * @param instance - The failing value
2997
- * @param code - Optional error code for programmatic handling
2998
- * @param params - Optional additional parameters
2999
- * @example Adding validation error
3000
- * ```typescript
3001
- * const ctx = createValidationContext(schema, validate)
3002
- * addError(ctx, 'Value must be a string', 42, 'type', { expected: 'string' })
3003
- * // ctx.errors[0].message === 'Value must be a string'
3004
- * // ctx.errors[0].code === 'type'
3005
- * ```
3006
- */
3007
1385
  function addError(ctx, message, instance, code, params) {
3008
1386
  ctx.errors.push({
3009
1387
  message,
@@ -3013,42 +1391,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3013
1391
  params,
3014
1392
  });
3015
1393
  }
3016
- /**
3017
- * Checks if we should continue validation after an error.
3018
- *
3019
- * @param ctx - Validation context
3020
- * @returns true if we should continue, false if we should stop
3021
- * @example Checking error collection mode
3022
- * ```typescript
3023
- * const ctx = createValidationContext(schema, validate, true) // collectAllErrors: true
3024
- * addError(ctx, 'First error', 'value', 'error')
3025
- * shouldContinue(ctx) // => true (keep collecting errors)
3026
- *
3027
- * const ctx2 = createValidationContext(schema, validate, false) // collectAllErrors: false
3028
- * addError(ctx2, 'First error', 'value', 'error')
3029
- * shouldContinue(ctx2) // => false (stop at first error)
3030
- * ```
3031
- */
3032
1394
  function shouldContinue(ctx) {
3033
1395
  return ctx.collectAllErrors || ctx.errors.length === 0;
3034
1396
  }
3035
1397
 
3036
- /**
3037
- * Performs deep equality check for JSON values.
3038
- *
3039
- * Used for enum validation and uniqueItems validation.
3040
- *
3041
- * @param a - First value to compare
3042
- * @param b - Second value to compare
3043
- * @returns true if values are deeply equal, false otherwise
3044
- * @example Comparing values for equality
3045
- * ```typescript
3046
- * isEqual({ name: 'Alice' }, { name: 'Alice' }) // => true
3047
- * isEqual([1, 2, 3], [1, 2, 3]) // => true
3048
- * isEqual({ a: 1 }, { a: 2 }) // => false
3049
- * isEqual([1, 2], [2, 1]) // => false (order matters)
3050
- * ```
3051
- */
3052
1398
  function isEqual(a, b) {
3053
1399
  if (a === b)
3054
1400
  return true;
@@ -3083,21 +1429,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3083
1429
  return false;
3084
1430
  }
3085
1431
 
3086
- /**
3087
- * Validates array length and uniqueItems constraints.
3088
- *
3089
- * @param instance - Array being validated
3090
- * @param schema - Schema containing array bounds
3091
- * @param ctx - Validation context
3092
- * @returns true if validation passes, false otherwise
3093
- * @example Validating array constraints
3094
- * ```typescript
3095
- * const schema = { minItems: 2, maxItems: 5, uniqueItems: true }
3096
- * validateArrayBounds([1, 2, 3], schema, ctx) // => true
3097
- * validateArrayBounds([1], schema, ctx) // => false (too few items)
3098
- * validateArrayBounds([1, 1, 2], schema, ctx) // => false (duplicates)
3099
- * ```
3100
- */
3101
1432
  function validateArrayBounds(instance, schema, ctx) {
3102
1433
  let valid = true;
3103
1434
  if (schema.minItems !== undefined && instance.length < schema.minItems) {
@@ -3133,23 +1464,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3133
1464
  return valid;
3134
1465
  }
3135
1466
 
3136
- /**
3137
- * Validates 'allOf' keyword - all schemas must match.
3138
- *
3139
- * @param instance - Value being validated
3140
- * @param schema - Schema containing the allOf constraint
3141
- * @param ctx - Validation context
3142
- * @returns true if validation passes, false otherwise
3143
- * @example Validating allOf composition
3144
- * ```typescript
3145
- * { type: 'object', required: ['name'] },
3146
- * { type: 'object', required: ['email'] }
3147
- * ]
3148
- * }
3149
- * validateAllOf({ name: 'Alice', email: 'alice@example.com' }, schema, ctx) // => true
3150
- * validateAllOf({ name: 'Alice' }, schema, ctx) // => false (missing email)
3151
- * ```
3152
- */
3153
1467
  function validateAllOf(instance, schema, ctx) {
3154
1468
  const allOf = schema.allOf;
3155
1469
  if (!allOf || allOf.length === 0) {
@@ -3158,7 +1472,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3158
1472
  let valid = true;
3159
1473
  for (let i = 0; i < allOf.length; i++) {
3160
1474
  const subSchema = allOf[i];
3161
- /* istanbul ignore if -- defensive null check for sparse arrays */
3162
1475
  if (!subSchema)
3163
1476
  continue;
3164
1477
  if (!ctx.validate(instance, subSchema, ctx)) {
@@ -3169,26 +1482,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3169
1482
  }
3170
1483
  return valid;
3171
1484
  }
3172
- /**
3173
- * Validates 'anyOf' keyword - at least one schema must match.
3174
- *
3175
- * @param instance - Value being validated
3176
- * @param schema - Schema containing the anyOf constraint
3177
- * @param ctx - Validation context
3178
- * @returns true if validation passes, false otherwise
3179
- * @example Validating anyOf composition
3180
- * ```typescript
3181
- * const schema = {
3182
- * anyOf: [
3183
- * { type: 'string' },
3184
- * { type: 'number' }
3185
- * ]
3186
- * }
3187
- * validateAnyOf('hello', schema, ctx) // => true
3188
- * validateAnyOf(42, schema, ctx) // => true
3189
- * validateAnyOf(true, schema, ctx) // => false (neither string nor number)
3190
- * ```
3191
- */
3192
1485
  function validateAnyOf(instance, schema, ctx) {
3193
1486
  const anyOf = schema.anyOf;
3194
1487
  if (!anyOf || anyOf.length === 0) {
@@ -3204,26 +1497,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3204
1497
  addError(ctx, 'Value does not match any of the allowed schemas (anyOf)', instance, 'anyOf');
3205
1498
  return false;
3206
1499
  }
3207
- /**
3208
- * Validates 'oneOf' keyword - exactly one schema must match.
3209
- *
3210
- * @param instance - Value being validated
3211
- * @param schema - Schema containing the oneOf constraint
3212
- * @param ctx - Validation context
3213
- * @returns true if validation passes, false otherwise
3214
- * @example Validating oneOf composition
3215
- * ```typescript
3216
- * const schema = {
3217
- * oneOf: [
3218
- * { type: 'integer' },
3219
- * { minimum: 5 }
3220
- * ]
3221
- * }
3222
- * validateOneOf(3, schema, ctx) // => true (matches first only)
3223
- * validateOneOf(10, schema, ctx) // => false (matches both)
3224
- * validateOneOf('hi', schema, ctx) // => false (matches neither)
3225
- * ```
3226
- */
3227
1500
  function validateOneOf(instance, schema, ctx) {
3228
1501
  const oneOf = schema.oneOf;
3229
1502
  if (!oneOf || oneOf.length === 0) {
@@ -3252,20 +1525,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3252
1525
  }
3253
1526
  return false;
3254
1527
  }
3255
- /**
3256
- * Validates 'not' keyword - schema must NOT match.
3257
- *
3258
- * @param instance - Value being validated
3259
- * @param schema - Schema containing the not constraint
3260
- * @param ctx - Validation context
3261
- * @returns true if validation passes, false otherwise
3262
- * @example Validating not constraint
3263
- * ```typescript
3264
- * const schema = { not: { type: 'string' } }
3265
- * validateNot(42, schema, ctx) // => true (not a string)
3266
- * validateNot('hello', schema, ctx) // => false (is a string)
3267
- * ```
3268
- */
3269
1528
  function validateNot(instance, schema, ctx) {
3270
1529
  const not = schema.not;
3271
1530
  if (!not) {
@@ -3280,58 +1539,31 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3280
1539
  return true;
3281
1540
  }
3282
1541
 
3283
- /**
3284
- * Validates object 'dependencies' keyword.
3285
- *
3286
- * @param instance - Object being validated
3287
- * @param schema - Schema containing the dependencies constraint
3288
- * @param ctx - Validation context
3289
- * @returns true if validation passes, false otherwise
3290
- * @example Validating dependent properties
3291
- * ```typescript
3292
- * const schema = {
3293
- * dependencies: {
3294
- * creditCard: ['billingAddress'], // if creditCard present, billingAddress required
3295
- * name: { required: ['email'] } // if name present, email required via schema
3296
- * }
3297
- * }
3298
- * validateDependencies({ creditCard: '1234', billingAddress: '123 Main St' }, schema, ctx) // => true
3299
- * validateDependencies({ creditCard: '1234' }, schema, ctx) // => false (missing billingAddress)
3300
- * ```
3301
- */
3302
1542
  function validateDependencies(instance, schema, ctx) {
3303
1543
  if (!schema.dependencies) {
3304
1544
  return true;
3305
1545
  }
3306
1546
  let valid = true;
3307
1547
  for (const [key, dependency] of entries(schema.dependencies)) {
3308
- /* istanbul ignore next -- key presence check */
3309
1548
  if (!hasOwn(instance, key)) {
3310
1549
  continue;
3311
1550
  }
3312
- /* istanbul ignore next -- dependency type check */
3313
1551
  if (isArray(dependency)) {
3314
1552
  for (const requiredKey of dependency) {
3315
- /* istanbul ignore next -- required key check */
3316
1553
  if (!hasOwn(instance, requiredKey)) {
3317
1554
  addError(ctx, `Property '${key}' requires property '${requiredKey}' to also be present`, instance, 'dependencies', {
3318
1555
  property: key,
3319
- /* istanbul ignore next -- required key assignment */
3320
1556
  required: requiredKey,
3321
1557
  });
3322
1558
  valid = false;
3323
- /* istanbul ignore if -- early exit tested in validate.spec.ts */
3324
1559
  if (!shouldContinue(ctx))
3325
1560
  return false;
3326
1561
  }
3327
1562
  }
3328
1563
  }
3329
1564
  else {
3330
- /* istanbul ignore next -- schema dependency validation */
3331
1565
  if (!ctx.validate(instance, dependency, ctx)) {
3332
- /* istanbul ignore next -- failure path */
3333
1566
  valid = false;
3334
- /* istanbul ignore if -- early exit tested in validate.spec.ts */
3335
1567
  if (!shouldContinue(ctx))
3336
1568
  return false;
3337
1569
  }
@@ -3340,20 +1572,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3340
1572
  return valid;
3341
1573
  }
3342
1574
 
3343
- /**
3344
- * Validates enum constraint.
3345
- *
3346
- * @param instance - Value being validated
3347
- * @param schema - Schema containing the enum constraint
3348
- * @param ctx - Validation context
3349
- * @returns true if validation passes, false otherwise
3350
- * @example Validating enum values
3351
- * ```typescript
3352
- * const schema = { enum: ['draft', 'published', 'archived'] }
3353
- * validateEnum('published', schema, ctx) // => true
3354
- * validateEnum('deleted', schema, ctx) // => false (not in enum)
3355
- * ```
3356
- */
3357
1575
  function validateEnum(instance, schema, ctx) {
3358
1576
  if (!schema.enum) {
3359
1577
  return true;
@@ -3370,77 +1588,24 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3370
1588
  return false;
3371
1589
  }
3372
1590
 
3373
- /**
3374
- * Safe RegExp factory for protected regex construction.
3375
- *
3376
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/regexp
3377
- */
3378
- /* eslint-disable workspace/lib-require-jsdoc-example */
3379
1591
  const _RegExp = globalThis.RegExp;
3380
- const _Reflect$2 = globalThis.Reflect;
3381
- /**
3382
- * (Safe copy) Creates a new RegExp using the captured RegExp constructor.
3383
- * Use this instead of `new RegExp()`.
3384
- *
3385
- * @param pattern - The pattern string or RegExp to copy.
3386
- * @param flags - Optional flags string.
3387
- * @returns A new RegExp instance.
3388
- */
3389
- const createRegExp = (pattern, flags) => _Reflect$2.construct(_RegExp, [pattern, flags]);
3390
-
3391
- /**
3392
- * Safe copies of URL built-ins via factory functions.
3393
- *
3394
- * Provides safe references to URL and URLSearchParams.
3395
- * These references are captured at module initialization time to protect against
3396
- * prototype pollution attacks. Import only what you need for tree-shaking.
3397
- *
3398
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/url
3399
- */
1592
+ const _Reflect$3 = globalThis.Reflect;
1593
+ const createRegExp = (pattern, flags) => _Reflect$3.construct(_RegExp, [pattern, flags]);
1594
+
3400
1595
  const _URL = globalThis.URL;
3401
- const _Reflect$1 = globalThis.Reflect;
3402
- /**
3403
- * (Safe copy) Creates a new URL using the captured URL constructor.
3404
- * Use this instead of `new URL()`.
3405
- *
3406
- * @param url - The URL string to parse.
3407
- * @param base - Optional base URL for relative URLs.
3408
- * @returns A new URL instance.
3409
- *
3410
- * @example Creating URL instances
3411
- * ```typescript
3412
- * const absolute = createURL('https://example.com/path?query=1')
3413
- * const relative = createURL('/api/users', 'https://example.com')
3414
- * // => URL { href: 'https://example.com/api/users' }
3415
- * ```
3416
- */
3417
- const createURL = (url, base) => _Reflect$1.construct(_URL, [url, base]);
3418
- /**
3419
- * (Safe copy) Creates an object URL for the given object.
3420
- * Use this instead of `URL.createObjectURL()`.
3421
- *
3422
- * Note: This is a browser-only API. In Node.js environments, this will throw.
3423
- */
1596
+ const _Reflect$2 = globalThis.Reflect;
1597
+ const createURL = (url, base) => _Reflect$2.construct(_URL, [url, base]);
3424
1598
  typeof _URL.createObjectURL === 'function'
3425
1599
  ? _URL.createObjectURL.bind(_URL)
3426
1600
  : () => {
3427
1601
  throw new Error('URL.createObjectURL is not available in this environment');
3428
1602
  };
3429
- /**
3430
- * (Safe copy) Revokes an object URL previously created with createObjectURL.
3431
- * Use this instead of `URL.revokeObjectURL()`.
3432
- *
3433
- * Note: This is a browser-only API. In Node.js environments, this will throw.
3434
- */
3435
1603
  typeof _URL.revokeObjectURL === 'function'
3436
1604
  ? _URL.revokeObjectURL.bind(_URL)
3437
1605
  : () => {
3438
1606
  throw new Error('URL.revokeObjectURL is not available in this environment');
3439
1607
  };
3440
1608
 
3441
- /**
3442
- * Format validators for common string formats.
3443
- */
3444
1609
  const formatValidators = {
3445
1610
  'date-time': (v) => {
3446
1611
  if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(v))
@@ -3530,7 +1695,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3530
1695
  try {
3531
1696
  createURL(v);
3532
1697
  return true;
3533
- /* istanbul ignore next -- URL constructor always throws for invalid URI */
3534
1698
  }
3535
1699
  catch {
3536
1700
  return false;
@@ -3539,11 +1703,9 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3539
1703
  'uri-reference': (v) => {
3540
1704
  try {
3541
1705
  createURL(v, 'http://example.com');
3542
- /* istanbul ignore next -- success path just returns true */
3543
1706
  return true;
3544
1707
  }
3545
1708
  catch {
3546
- /* istanbul ignore next -- URL constructor is very permissive with base URL */
3547
1709
  return false;
3548
1710
  }
3549
1711
  },
@@ -3552,7 +1714,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3552
1714
  },
3553
1715
  regex: (v) => {
3554
1716
  try {
3555
- // eslint-disable-next-line workspace/no-unsafe-regex -- intentionally validating user-provided regex patterns
3556
1717
  createRegExp(v);
3557
1718
  return true;
3558
1719
  }
@@ -3570,21 +1731,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3570
1731
  return segments.every((seg) => validSegment.test(seg));
3571
1732
  },
3572
1733
  };
3573
- /**
3574
- * Validates string format constraint.
3575
- *
3576
- * @param instance - String being validated
3577
- * @param schema - Schema containing the format constraint
3578
- * @param ctx - Validation context
3579
- * @returns true if validation passes, false otherwise
3580
- * @example Validating string formats
3581
- * ```typescript
3582
- * validateFormat('user@example.com', { format: 'email' }, ctx) // => true
3583
- * validateFormat('invalid-email', { format: 'email' }, ctx) // => false
3584
- * validateFormat('2024-01-15', { format: 'date' }, ctx) // => true
3585
- * validateFormat('192.168.1.1', { format: 'ipv4' }, ctx) // => true
3586
- * ```
3587
- */
3588
1734
  function validateFormat(instance, schema, ctx) {
3589
1735
  if (!schema.format) {
3590
1736
  return true;
@@ -3602,27 +1748,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3602
1748
  return true;
3603
1749
  }
3604
1750
 
3605
- /**
3606
- * Validates array 'items' keyword.
3607
- *
3608
- * @param instance - Array being validated
3609
- * @param schema - Schema containing the items constraint
3610
- * @param ctx - Validation context
3611
- * @returns true if validation passes, false otherwise
3612
- * @example Single schema for all items
3613
- * ```typescript
3614
- * const schema = { items: { type: 'string' } }
3615
- * validateItems(['a', 'b', 'c'], schema, ctx) // => true
3616
- * validateItems(['a', 1, 'c'], schema, ctx) // => false (1 is not a string)
3617
- * ```
3618
- *
3619
- * @example Tuple validation
3620
- * ```typescript
3621
- * const schema = { items: [{ type: 'string' }, { type: 'number' }] }
3622
- * validateItems(['name', 42], schema, ctx) // => true
3623
- * validateItems([42, 'name'], schema, ctx) // => false (wrong types)
3624
- * ```
3625
- */
3626
1751
  function validateItems(instance, schema, ctx) {
3627
1752
  const items = schema.items;
3628
1753
  if (items === undefined) {
@@ -3632,13 +1757,11 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3632
1757
  if (isArray(items)) {
3633
1758
  for (let i = 0; i < items.length && i < instance.length; i++) {
3634
1759
  const itemSchema = items[i];
3635
- /* istanbul ignore if -- defensive null check for sparse arrays */
3636
1760
  if (!itemSchema)
3637
1761
  continue;
3638
1762
  const itemCtx = pushPath(ctx, i);
3639
1763
  if (!ctx.validate(instance[i], itemSchema, itemCtx)) {
3640
1764
  valid = false;
3641
- /* istanbul ignore if -- early exit already tested in validate.spec.ts */
3642
1765
  if (!shouldContinue(ctx))
3643
1766
  return false;
3644
1767
  }
@@ -3661,24 +1784,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3661
1784
  }
3662
1785
  return valid;
3663
1786
  }
3664
- /**
3665
- * Validates 'additionalItems' keyword for tuple arrays.
3666
- *
3667
- * @param instance - Array being validated
3668
- * @param schema - Schema containing the additionalItems constraint
3669
- * @param ctx - Validation context
3670
- * @param startIndex - Index from which to start checking additional items
3671
- * @returns true if validation passes, false otherwise
3672
- */
3673
1787
  function validateAdditionalItems(instance, schema, ctx, startIndex) {
3674
1788
  const additionalItems = schema.additionalItems;
3675
- /* istanbul ignore if -- default case handled in items.spec.ts */
3676
1789
  if (additionalItems === undefined) {
3677
1790
  return true;
3678
1791
  }
3679
- /* istanbul ignore next -- additionalItems initialization and branching */
3680
1792
  let valid = true;
3681
- /* istanbul ignore next -- additionalItems branching */
3682
1793
  if (additionalItems === false) {
3683
1794
  if (instance.length > startIndex) {
3684
1795
  addError(ctx, `Array has too many items. Expected at most ${startIndex}, got ${instance.length}`, instance, 'additionalItems', {
@@ -3691,10 +1802,8 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3691
1802
  else if (typeof additionalItems === 'object') {
3692
1803
  for (let i = startIndex; i < instance.length; i++) {
3693
1804
  const itemCtx = pushPath(ctx, i);
3694
- /* istanbul ignore else -- validation failure tested in items.spec.ts */
3695
1805
  if (!ctx.validate(instance[i], additionalItems, itemCtx)) {
3696
1806
  valid = false;
3697
- /* istanbul ignore if -- early exit tested in validate.spec.ts */
3698
1807
  if (!shouldContinue(ctx))
3699
1808
  return false;
3700
1809
  }
@@ -3703,22 +1812,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3703
1812
  return valid;
3704
1813
  }
3705
1814
 
3706
- /**
3707
- * Validates number range and multipleOf constraints.
3708
- *
3709
- * @param instance - Number being validated
3710
- * @param schema - Schema containing number constraints
3711
- * @param ctx - Validation context
3712
- * @returns true if validation passes, false otherwise
3713
- * @example Validating number constraints
3714
- * ```typescript
3715
- * const schema = { minimum: 0, maximum: 100, multipleOf: 5 }
3716
- * validateNumberBounds(50, schema, ctx) // => true
3717
- * validateNumberBounds(-1, schema, ctx) // => false (below minimum)
3718
- * validateNumberBounds(101, schema, ctx) // => false (above maximum)
3719
- * validateNumberBounds(17, schema, ctx) // => false (not multiple of 5)
3720
- * ```
3721
- */
3722
1815
  function validateNumberBounds(instance, schema, ctx) {
3723
1816
  let valid = true;
3724
1817
  if (schema.minimum !== undefined) {
@@ -3765,21 +1858,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3765
1858
  return valid;
3766
1859
  }
3767
1860
 
3768
- /**
3769
- * Validates object bounds constraints (minProperties, maxProperties).
3770
- *
3771
- * @param instance - Object being validated
3772
- * @param schema - Schema containing object bounds
3773
- * @param ctx - Validation context
3774
- * @returns true if validation passes, false otherwise
3775
- * @example Validating object property counts
3776
- * ```typescript
3777
- * const schema = { minProperties: 1, maxProperties: 3 }
3778
- * validateObjectBounds({ a: 1, b: 2 }, schema, ctx) // => true
3779
- * validateObjectBounds({}, schema, ctx) // => false (no properties)
3780
- * validateObjectBounds({ a: 1, b: 2, c: 3, d: 4 }, schema, ctx) // => false (too many)
3781
- * ```
3782
- */
3783
1861
  function validateObjectBounds(instance, schema, ctx) {
3784
1862
  let valid = true;
3785
1863
  const propertyCount = keys(instance).length;
@@ -3804,25 +1882,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3804
1882
  return valid;
3805
1883
  }
3806
1884
 
3807
- /**
3808
- * Validates object 'patternProperties' keyword.
3809
- *
3810
- * @param instance - Object being validated
3811
- * @param schema - Schema containing the patternProperties constraint
3812
- * @param ctx - Validation context
3813
- * @returns true if validation passes, false otherwise
3814
- * @example Validating pattern properties
3815
- * ```typescript
3816
- * const schema = {
3817
- * patternProperties: {
3818
- * '^x-': { type: 'string' }, // extension properties must be strings
3819
- * '^\\d+$': { type: 'number' } // numeric keys must have number values
3820
- * }
3821
- * }
3822
- * validatePatternProperties({ 'x-custom': 'value', '42': 100 }, schema, ctx) // => true
3823
- * validatePatternProperties({ 'x-custom': 123 }, schema, ctx) // => false (should be string)
3824
- * ```
3825
- */
3826
1885
  function validatePatternProperties(instance, schema, ctx) {
3827
1886
  if (!schema.patternProperties) {
3828
1887
  return true;
@@ -3830,7 +1889,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3830
1889
  let valid = true;
3831
1890
  const patterns = [];
3832
1891
  for (const [pattern, patternSchema] of entries(schema.patternProperties)) {
3833
- /* istanbul ignore if -- patternSafetyChecker branch tested in validate.spec.ts */
3834
1892
  if (ctx.patternSafetyChecker) {
3835
1893
  const safetyResult = ctx.patternSafetyChecker(pattern);
3836
1894
  if (!safetyResult.safe) {
@@ -3845,21 +1903,15 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3845
1903
  }
3846
1904
  }
3847
1905
  try {
3848
- // eslint-disable-next-line workspace/no-unsafe-regex -- Pattern safety validated above when safePatterns enabled
3849
1906
  patterns.push({ regex: createRegExp(pattern), schema: patternSchema });
3850
1907
  }
3851
1908
  catch (e) {
3852
- /* istanbul ignore next -- strictPatterns mode verified in validate.spec.ts */
3853
1909
  if (ctx.strictPatterns) {
3854
- /* istanbul ignore next -- error reporting for invalid regex */
3855
1910
  addError(ctx, `Invalid regex pattern in patternProperties: ${pattern}`, instance, 'patternProperties', {
3856
- /* istanbul ignore next -- error message extraction */
3857
1911
  pattern,
3858
- /* istanbul ignore next -- ternary expression */
3859
1912
  error: e instanceof Error ? e.message : 'Invalid regex',
3860
1913
  });
3861
1914
  valid = false;
3862
- /* istanbul ignore if -- early exit tested in validate.spec.ts */
3863
1915
  if (!shouldContinue(ctx))
3864
1916
  return false;
3865
1917
  }
@@ -3880,25 +1932,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3880
1932
  return valid;
3881
1933
  }
3882
1934
 
3883
- /**
3884
- * Validates object 'properties' keyword.
3885
- *
3886
- * @param instance - Object being validated
3887
- * @param schema - Schema containing the properties constraint
3888
- * @param ctx - Validation context
3889
- * @returns true if validation passes, false otherwise
3890
- * @example Validating object properties
3891
- * ```typescript
3892
- * const schema = {
3893
- * properties: {
3894
- * name: { type: 'string' },
3895
- * age: { type: 'integer' }
3896
- * }
3897
- * }
3898
- * validateProperties({ name: 'Alice', age: 30 }, schema, ctx) // => true
3899
- * validateProperties({ name: 123 }, schema, ctx) // => false (name should be string)
3900
- * ```
3901
- */
3902
1935
  function validateProperties(instance, schema, ctx) {
3903
1936
  if (!schema.properties) {
3904
1937
  return true;
@@ -3916,20 +1949,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3916
1949
  }
3917
1950
  return valid;
3918
1951
  }
3919
- /**
3920
- * Validates object 'required' keyword.
3921
- *
3922
- * @param instance - Object being validated
3923
- * @param schema - Schema containing the required constraint
3924
- * @param ctx - Validation context
3925
- * @returns true if validation passes, false otherwise
3926
- * @example Validating required properties
3927
- * ```typescript
3928
- * const schema = { required: ['name', 'email'] }
3929
- * validateRequired({ name: 'Alice', email: 'alice@example.com' }, schema, ctx) // => true
3930
- * validateRequired({ name: 'Alice' }, schema, ctx) // => false (missing email)
3931
- * ```
3932
- */
3933
1952
  function validateRequired(instance, schema, ctx) {
3934
1953
  if (!schema.required) {
3935
1954
  return true;
@@ -3945,38 +1964,18 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3945
1964
  }
3946
1965
  return valid;
3947
1966
  }
3948
- /**
3949
- * Validates object 'additionalProperties' keyword.
3950
- *
3951
- * @param instance - Object being validated
3952
- * @param schema - Schema containing the additionalProperties constraint
3953
- * @param ctx - Validation context
3954
- * @returns true if validation passes, false otherwise
3955
- * @example Validating additional properties
3956
- * ```typescript
3957
- * const schema = {
3958
- * properties: { name: { type: 'string' } },
3959
- * additionalProperties: false
3960
- * }
3961
- * validateAdditionalProperties({ name: 'Alice' }, schema, ctx) // => true
3962
- * validateAdditionalProperties({ name: 'Alice', extra: 1 }, schema, ctx) // => false
3963
- * ```
3964
- */
3965
1967
  function validateAdditionalProperties(instance, schema, ctx) {
3966
1968
  const additionalProperties = schema.additionalProperties;
3967
1969
  if (additionalProperties === undefined) {
3968
1970
  return true;
3969
1971
  }
3970
- /* istanbul ignore next -- definedKeys initialization */
3971
1972
  const definedKeys = createSet();
3972
- /* istanbul ignore next -- schema.properties may not exist */
3973
1973
  if (schema.properties) {
3974
1974
  for (const key of keys(schema.properties)) {
3975
1975
  definedKeys.add(key);
3976
1976
  }
3977
1977
  }
3978
1978
  const patterns = [];
3979
- /* istanbul ignore next -- patternProperties may not always be present */
3980
1979
  if (schema.patternProperties) {
3981
1980
  for (const pattern of keys(schema.patternProperties)) {
3982
1981
  if (ctx.patternSafetyChecker) {
@@ -3986,12 +1985,9 @@ var HyperfrontendFeaturesHostee = (function (exports) {
3986
1985
  }
3987
1986
  }
3988
1987
  try {
3989
- // eslint-disable-next-line workspace/no-unsafe-regex -- Pattern safety validated above when safePatterns enabled
3990
1988
  patterns.push(createRegExp(pattern));
3991
- /* istanbul ignore next -- invalid regex patterns handled in patternProperties validator */
3992
1989
  }
3993
1990
  catch {
3994
- // Invalid regex, skip
3995
1991
  }
3996
1992
  }
3997
1993
  }
@@ -4008,7 +2004,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4008
2004
  property: key,
4009
2005
  });
4010
2006
  valid = false;
4011
- /* istanbul ignore if -- early exit tested in validate.spec.ts */
4012
2007
  if (!shouldContinue(ctx))
4013
2008
  return false;
4014
2009
  }
@@ -4016,7 +2011,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4016
2011
  const propCtx = pushPath(ctx, key);
4017
2012
  if (!ctx.validate(instance[key], additionalProperties, propCtx)) {
4018
2013
  valid = false;
4019
- /* istanbul ignore if -- early exit tested in validate.spec.ts */
4020
2014
  if (!shouldContinue(ctx))
4021
2015
  return false;
4022
2016
  }
@@ -4025,21 +2019,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4025
2019
  return valid;
4026
2020
  }
4027
2021
 
4028
- /**
4029
- * Validates string length and pattern constraints.
4030
- *
4031
- * @param instance - String being validated
4032
- * @param schema - Schema containing string constraints
4033
- * @param ctx - Validation context
4034
- * @returns true if validation passes, false otherwise
4035
- * @example Validating string constraints
4036
- * ```typescript
4037
- * const schema = { minLength: 3, maxLength: 10, pattern: '^[a-z]+$' }
4038
- * validateStringBounds('hello', schema, ctx) // => true
4039
- * validateStringBounds('hi', schema, ctx) // => false (too short)
4040
- * validateStringBounds('Hello', schema, ctx) // => false (contains uppercase)
4041
- * ```
4042
- */
4043
2022
  function validateStringBounds(instance, schema, ctx) {
4044
2023
  let valid = true;
4045
2024
  if (schema.minLength !== undefined && instance.length < schema.minLength) {
@@ -4075,7 +2054,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4075
2054
  }
4076
2055
  }
4077
2056
  try {
4078
- // eslint-disable-next-line workspace/no-unsafe-regex -- Pattern safety validated above when safePatterns enabled
4079
2057
  const regex = createRegExp(schema.pattern);
4080
2058
  if (!regex.test(instance)) {
4081
2059
  addError(ctx, `String does not match pattern: ${schema.pattern}`, instance, 'pattern', {
@@ -4087,16 +2065,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4087
2065
  }
4088
2066
  }
4089
2067
  catch (e) {
4090
- /* istanbul ignore next -- strictPatterns mode verified in validate.spec.ts */
4091
2068
  if (ctx.strictPatterns) {
4092
- /* istanbul ignore next -- error reporting for invalid regex */
4093
2069
  addError(ctx, `Invalid regex pattern: ${schema.pattern}`, instance, 'pattern', {
4094
2070
  pattern: schema.pattern,
4095
- /* istanbul ignore next -- error message extraction ternary */
4096
2071
  error: e instanceof Error ? e.message : 'Invalid regex',
4097
2072
  });
4098
2073
  valid = false;
4099
- /* istanbul ignore if -- early exit tested in validate.spec.ts */
4100
2074
  if (!shouldContinue(ctx))
4101
2075
  return false;
4102
2076
  }
@@ -4105,9 +2079,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4105
2079
  return valid;
4106
2080
  }
4107
2081
 
4108
- /**
4109
- * Type checking functions for JSON Schema types.
4110
- */
4111
2082
  const typeCheckers = {
4112
2083
  string: (v) => typeof v === 'string',
4113
2084
  number: (v) => typeof v === 'number' && globalIsFinite(v),
@@ -4117,12 +2088,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4117
2088
  object: (v) => v !== null && typeof v === 'object' && !isArray(v),
4118
2089
  null: (v) => v === null,
4119
2090
  };
4120
- /**
4121
- * Gets the actual JSON type of a value for error messages.
4122
- *
4123
- * @param value - The value to get the type of
4124
- * @returns The JSON type as a string
4125
- */
4126
2091
  function getActualType(value) {
4127
2092
  if (value === null)
4128
2093
  return 'null';
@@ -4131,28 +2096,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4131
2096
  const t = typeof value;
4132
2097
  if (t === 'number') {
4133
2098
  const num = value;
4134
- /* istanbul ignore next -- NaN/Infinity edge case */
4135
2099
  if (!globalIsFinite(num))
4136
2100
  return 'number';
4137
2101
  return isInteger(num) ? 'integer' : 'number';
4138
2102
  }
4139
2103
  return t;
4140
2104
  }
4141
- /**
4142
- * Validates the 'type' keyword.
4143
- *
4144
- * @param instance - Value being validated
4145
- * @param schema - Schema containing the type constraint
4146
- * @param ctx - Validation context
4147
- * @returns true if validation passes, false otherwise
4148
- * @example Validating type constraints
4149
- * ```typescript
4150
- * validateType('hello', { type: 'string' }, ctx) // => true
4151
- * validateType(42, { type: 'integer' }, ctx) // => true
4152
- * validateType('42', { type: 'integer' }, ctx) // => false
4153
- * validateType(null, { type: ['string', 'null'] }, ctx) // => true (union type)
4154
- * ```
4155
- */
4156
2105
  function validateType(instance, schema, ctx) {
4157
2106
  const schemaType = schema.type;
4158
2107
  if (schemaType === undefined) {
@@ -4161,11 +2110,9 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4161
2110
  const types = isArray(schemaType) ? schemaType : [schemaType];
4162
2111
  for (const type of types) {
4163
2112
  const checker = typeCheckers[type];
4164
- /* istanbul ignore if -- defensive check for unknown type */
4165
2113
  if (checker && checker(instance)) {
4166
2114
  return true;
4167
2115
  }
4168
- /* istanbul ignore if -- defensive fallback for integer/number coercion */
4169
2116
  if (type === 'number' && typeCheckers['integer']?.(instance)) {
4170
2117
  return true;
4171
2118
  }
@@ -4179,24 +2126,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4179
2126
  return false;
4180
2127
  }
4181
2128
 
4182
- /**
4183
- * Resolves a $ref JSON Pointer to its target schema.
4184
- *
4185
- * @param ref - The $ref string (e.g., '#/definitions/Address')
4186
- * @param ctx - Validation context containing root schema and definitions
4187
- * @returns The resolved schema, or undefined if not found
4188
- * @example Resolving schema references
4189
- * ```typescript
4190
- * const rootSchema = {
4191
- * definitions: {
4192
- * Address: { type: 'object', properties: { street: { type: 'string' } } }
4193
- * }
4194
- * }
4195
- * const ctx = createValidationContext(rootSchema, validate)
4196
- * resolveRef('#/definitions/Address', ctx)
4197
- * // => { type: 'object', properties: { street: { type: 'string' } } }
4198
- * ```
4199
- */
4200
2129
  function resolveRef(ref, ctx) {
4201
2130
  const cached = ctx.definitions.get(ref);
4202
2131
  if (cached) {
@@ -4231,21 +2160,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4231
2160
  return undefined;
4232
2161
  }
4233
2162
 
4234
- /**
4235
- * Validates a value against a JSON Schema.
4236
- *
4237
- * @param instance - The value to validate
4238
- * @param schema - The JSON Schema to validate against
4239
- * @param options - Validation options
4240
- * @returns Validation result with valid flag and any errors
4241
- *
4242
- * @example Basic validation
4243
- * ```typescript
4244
- * const schema = { type: 'string', minLength: 1 }
4245
- * const result = validate('hello', schema)
4246
- * console.log(result.valid) // true
4247
- * ```
4248
- */
4249
2163
  function validate(instance, schema, options) {
4250
2164
  let patternSafetyChecker;
4251
2165
  const ctx = createValidationContext(schema, validateSchema, true, false, patternSafetyChecker);
@@ -4255,25 +2169,9 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4255
2169
  errors: ctx.errors,
4256
2170
  };
4257
2171
  }
4258
- /**
4259
- * Internal recursive validation function.
4260
- *
4261
- * @param instance - Value being validated
4262
- * @param schema - Schema to validate against
4263
- * @param ctx - Validation context
4264
- * @returns true if validation passes, false otherwise
4265
- * @example Internal recursive validation
4266
- * ```typescript
4267
- * const schema = { type: 'object', properties: { count: { type: 'integer' } } }
4268
- * const ctx = createValidationContext(schema, validateSchema)
4269
- * validateSchema({ count: 5 }, schema, ctx) // => true
4270
- * validateSchema({ count: 'five' }, schema, ctx) // => false
4271
- * ```
4272
- */
4273
2172
  function validateSchema(instance, schema, ctx) {
4274
2173
  if (schema.$ref) {
4275
2174
  const resolved = resolveRef(schema.$ref, ctx);
4276
- /* istanbul ignore if -- $ref resolution failures are tested in resolve-ref.spec.ts */
4277
2175
  if (!resolved) {
4278
2176
  return true;
4279
2177
  }
@@ -4330,35 +2228,26 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4330
2228
  }
4331
2229
  if (!validateRequired(obj, schema, ctx)) {
4332
2230
  valid = false;
4333
- /* istanbul ignore if -- early exit tested elsewhere */
4334
2231
  if (!shouldContinue(ctx))
4335
2232
  return false;
4336
2233
  }
4337
- /* istanbul ignore next -- patternProperties validation */
4338
2234
  if (!validatePatternProperties(obj, schema, ctx)) {
4339
2235
  valid = false;
4340
- /* istanbul ignore next -- early exit tested elsewhere */
4341
2236
  if (!shouldContinue(ctx))
4342
2237
  return false;
4343
2238
  }
4344
- /* istanbul ignore next -- additionalProperties validation */
4345
2239
  if (!validateAdditionalProperties(obj, schema, ctx)) {
4346
2240
  valid = false;
4347
- /* istanbul ignore next -- early exit tested elsewhere */
4348
2241
  if (!shouldContinue(ctx))
4349
2242
  return false;
4350
2243
  }
4351
- /* istanbul ignore next -- objectBounds validation */
4352
2244
  if (!validateObjectBounds(obj, schema, ctx)) {
4353
2245
  valid = false;
4354
- /* istanbul ignore next -- early exit tested elsewhere */
4355
2246
  if (!shouldContinue(ctx))
4356
2247
  return false;
4357
2248
  }
4358
- /* istanbul ignore next -- dependencies validation */
4359
2249
  if (!validateDependencies(obj, schema, ctx)) {
4360
2250
  valid = false;
4361
- /* istanbul ignore next -- early exit tested elsewhere */
4362
2251
  if (!shouldContinue(ctx))
4363
2252
  return false;
4364
2253
  }
@@ -4386,51 +2275,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4386
2275
  return valid;
4387
2276
  }
4388
2277
 
4389
- /**
4390
- * Creates a reusable validator function from a JSON Schema.
4391
- *
4392
- * @param schema - JSON Schema to validate against
4393
- * @param options - Validation options
4394
- * @returns A function that validates data against the schema
4395
- *
4396
- * @example Creating reusable validator
4397
- * ```typescript
4398
- * const schema = {
4399
- * type: 'object',
4400
- * properties: {
4401
- * name: { type: 'string' },
4402
- * age: { type: 'integer', minimum: 0 }
4403
- * },
4404
- * required: ['name']
4405
- * }
4406
- *
4407
- * const validateUser = createValidator(schema)
4408
- * const result = validateUser({ name: 'Alice', age: 30 })
4409
- * console.log(result.valid) // true
4410
- * ```
4411
- */
4412
2278
  function createValidator$1(schema, options) {
4413
2279
  return (data) => validate(data, schema);
4414
2280
  }
4415
2281
 
4416
- /**
4417
- * Creates a validator function from a JSON schema.
4418
- * Returns a function that validates data against the schema.
4419
- *
4420
- * @param schema - JSON Schema to validate against
4421
- * @returns Validator function that returns validation results
4422
- *
4423
- * @example Creating a schema validator
4424
- * ```typescript
4425
- * const validateUser = createValidator({
4426
- * type: 'object',
4427
- * properties: { name: { type: 'string' } },
4428
- * required: ['name']
4429
- * })
4430
- * const result = validateUser({ name: 'Alice' })
4431
- * // => { valid: true, errors: [] }
4432
- * ```
4433
- */
4434
2282
  function createValidator(schema) {
4435
2283
  const validator = createValidator$1(schema);
4436
2284
  return (data) => {
@@ -4446,47 +2294,19 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4446
2294
  };
4447
2295
  }
4448
2296
 
4449
- /* istanbul ignore next -- validator initialization happens at module load */
4450
2297
  const validateMessageData = createValidator(messageSchema);
4451
- /**
4452
- * Validates a user message against the message schema.
4453
- *
4454
- * @param message - The message to validate
4455
- * @returns Validation result with any errors
4456
- */
4457
2298
  function validateMessage(message) {
4458
2299
  return validateMessageData(message);
4459
2300
  }
4460
2301
 
4461
- /**
4462
- * Handles NEW_MESSAGE action.
4463
- * Routes messages to appropriate channel.
4464
- *
4465
- * @param context - Routing context with state, registry, actions, and logger
4466
- * @param message - Message event containing the NEW_MESSAGE action
4467
- *
4468
- * @remarks
4469
- * Side Effects:
4470
- * - Validates message type against contract
4471
- * - Invokes channel message handlers if validation passes
4472
- * - Logs and ignores invalid messages
4473
- *
4474
- * @example Routing user messages
4475
- * User message flow:
4476
- * channel.send('USER_LOGIN', {userId: 123})
4477
- * -> NEW_MESSAGE action sent
4478
- * -> Received by remote broker (this handler)
4479
- * -> Routed to channel's onMessage handlers
4480
- */
4481
2302
  function handleMessage(context, message) {
4482
2303
  const { state, registry, logger } = context;
4483
2304
  const action = message.data;
4484
- const senderId = action.senderId;
4485
2305
  if (!isActionWithData(action)) {
4486
2306
  return;
4487
2307
  }
4488
2308
  const messageData = action.data;
4489
- const channel = getById(registry, senderId);
2309
+ const channel = resolveChannel(registry, message);
4490
2310
  if (!channel || !channel.isActive()) {
4491
2311
  return;
4492
2312
  }
@@ -4495,29 +2315,13 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4495
2315
  logger.info(`${state.name} ignored message from ${channel.getName()}`);
4496
2316
  return;
4497
2317
  }
2318
+ if (!channel.getAcceptedTypes().includes(messageData.type)) {
2319
+ logger.info(`${state.name} dropped message type '${messageData.type}' not accepted by the ${channel.getName()} channel contract`);
2320
+ return;
2321
+ }
4498
2322
  channel.notifyMessage(messageData);
4499
2323
  }
4500
2324
 
4501
- /**
4502
- * Handles OPEN_CONNECTION action.
4503
- * Completes handshake on responder's side and notifies open event.
4504
- *
4505
- * @param context - Routing context with state, registry, actions, and logger
4506
- * @param message - Message event containing the OPEN_CONNECTION action
4507
- *
4508
- * @remarks
4509
- * Side Effects:
4510
- * - Terminates the connection process
4511
- * - Extracts security confirmation (if present)
4512
- * - Marks security as ready if security is active
4513
- * - Fires 'open' lifecycle event on responder's side
4514
- * - Fires 'security-ready' event if security transport is active
4515
- *
4516
- * @example Completing the three-way handshake
4517
- * Final step of three-way handshake:
4518
- * Responder receives OPEN (this handler) from Initiator
4519
- * Both sides now have active connection
4520
- */
4521
2325
  function handleOpen(context, message) {
4522
2326
  const { state, processManager, logger } = context;
4523
2327
  const action = message.data;
@@ -4545,33 +2349,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4545
2349
  channel.notifyEvent('open', { origin: message.origin });
4546
2350
  }
4547
2351
 
4548
- /**
4549
- * Protocol negotiation logic for security handshake.
4550
- *
4551
- * Implements the negotiation algorithm that determines the best
4552
- * security protocol to use between two communicating parties.
4553
- *
4554
- * @module security/negotiation/negotiate
4555
- */
4556
- /**
4557
- * Negotiates the best security protocol between initiator and responder.
4558
- *
4559
- * The algorithm iterates through the initiator's supported protocols
4560
- * (in preference order) and selects the first one that the responder
4561
- * also supports. If no overlap is found, falls back to 'none'.
4562
- *
4563
- * @param request - The initiator's security negotiation request
4564
- * @param responderSupported - Protocols supported by the responder
4565
- * @returns The negotiation result with the selected protocol
4566
- *
4567
- * @example Negotiating security protocol
4568
- * ```typescript
4569
- * const request = { supported: ['v2', 'v1', 'none'], preferred: 'v2' }
4570
- * const responderSupported = ['v1', 'none']
4571
- * const result = negotiateProtocol(request, responderSupported)
4572
- * // result.negotiated === 'v1' (first match from initiator's list)
4573
- * ```
4574
- */
4575
2352
  function negotiateProtocol(request, responderSupported) {
4576
2353
  for (const protocol of request.supported) {
4577
2354
  if (responderSupported.includes(protocol)) {
@@ -4586,55 +2363,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4586
2363
  isPreferred: request.preferred === 'none',
4587
2364
  };
4588
2365
  }
4589
- /**
4590
- * Creates a security negotiation response for the responder.
4591
- *
4592
- * Builds a response object containing the negotiated protocol
4593
- * and optional public parameters for protocol initialization.
4594
- *
4595
- * @param negotiated - The negotiated protocol version
4596
- * @param publicParams - Optional public parameters (e.g., key exchange hints)
4597
- * @returns A security negotiation response object
4598
- *
4599
- * @example Creating responder response
4600
- * ```typescript
4601
- * const response = createSecurityResponse('v2', { hint: 'value' })
4602
- * // { negotiated: 'v2', publicParams: { hint: 'value' } }
4603
- * ```
4604
- */
4605
2366
  function createSecurityResponse(negotiated, publicParams) {
4606
2367
  const response = { negotiated };
4607
2368
  return freeze(response);
4608
2369
  }
4609
2370
 
4610
- /**
4611
- * Default supported security protocols for the responder.
4612
- * Includes 'none' as fallback for backward compatibility.
4613
- */
4614
2371
  const DEFAULT_RESPONDER_SUPPORTED = ['none'];
4615
- /**
4616
- * Handles REQUEST_CONNECTION action.
4617
- * Creates or retrieves channel and initiates connection handshake.
4618
- *
4619
- * @param context - Routing context with state, registry, actions, and logger
4620
- * @param message - Message event containing the REQUEST_CONNECTION action
4621
- *
4622
- * @remarks
4623
- * Side Effects:
4624
- * - Creates new channel if not found in registry
4625
- * - Tracks process ID for handshake completion
4626
- * - Negotiates security protocol if security data present
4627
- * - Sends ACCEPT_CONNECTION if validation passes
4628
- * - Sends DENY_CONNECTION if contract or security policy fails
4629
- *
4630
- * @example Processing connection requests
4631
- * Incoming action triggers:
4632
- * 1. Channel lookup/creation
4633
- * 2. Contract validation
4634
- * 3. Security policy check
4635
- * 4. Security protocol negotiation (if applicable)
4636
- * 5. ACCEPT_CONNECTION response (or DENY if validation fails)
4637
- */
4638
2372
  function handleRequest(context, message) {
4639
2373
  const { state, registry, processManager, actions, logger } = context;
4640
2374
  const action = message.data;
@@ -4719,22 +2453,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4719
2453
  });
4720
2454
  }
4721
2455
 
4722
- /**
4723
- * Security error handling utilities.
4724
- *
4725
- * Provides functions for handling, categorizing, and emitting security-related
4726
- * errors during message encryption/decryption operations.
4727
- *
4728
- * @module security/errors
4729
- */
4730
- /**
4731
- * Security error class with additional metadata for programmatic handling.
4732
- *
4733
- * @example Creating security error
4734
- * ```typescript
4735
- * throw new SecurityError('Decryption failed', 'decryption_failed', originalError)
4736
- * ```
4737
- */
4738
2456
  class SecurityError extends Error {
4739
2457
  code;
4740
2458
  originalCause;
@@ -4746,25 +2464,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4746
2464
  setPrototypeOf(this, SecurityError.prototype);
4747
2465
  }
4748
2466
  }
4749
- /**
4750
- * Creates security error event data from an error.
4751
- *
4752
- * Converts various error types into a standardized SecurityErrorEventData
4753
- * structure for emitting via channel events.
4754
- *
4755
- * @param error - The error to convert
4756
- * @returns Standardized security error event data
4757
- *
4758
- * @example Converting errors to event data
4759
- * ```typescript
4760
- * try {
4761
- * decrypt(payload)
4762
- * } catch (error) {
4763
- * const eventData = createSecurityErrorEventData(error)
4764
- * channel.notifyEvent('security-error', eventData)
4765
- * }
4766
- * ```
4767
- */
4768
2467
  function createSecurityErrorEventData(error) {
4769
2468
  if (error instanceof SecurityError) {
4770
2469
  return {
@@ -4786,17 +2485,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4786
2485
  code: 'unknown',
4787
2486
  };
4788
2487
  }
4789
- /**
4790
- * Categorizes an error into a security error code.
4791
- *
4792
- * Analyzes the error message to determine the appropriate category.
4793
- * This is used when errors from network-protocol are caught.
4794
- *
4795
- * @param error - The error to categorize
4796
- * @returns The appropriate security error code
4797
- *
4798
- * @internal
4799
- */
4800
2488
  function categorizeError(error) {
4801
2489
  const message = error.message.toLowerCase();
4802
2490
  if (message.includes('decrypt') || message.includes('invalid key') || message.includes('corrupted') || message.includes('cipher')) {
@@ -4813,21 +2501,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4813
2501
  }
4814
2502
  return 'unknown';
4815
2503
  }
4816
- /**
4817
- * Logs a security error with appropriate formatting.
4818
- *
4819
- * Uses logger.error for actual errors and logger.warn for
4820
- * retryable/expected failures.
4821
- *
4822
- * @param logger - Logger instance to use for output
4823
- * @param channelName - Name of the channel where error occurred
4824
- * @param error - The security error event data containing message, code, and optional cause
4825
- *
4826
- * @example Logging security errors
4827
- * ```typescript
4828
- * logSecurityError(logger, 'my-channel', errorData)
4829
- * ```
4830
- */
4831
2504
  function logSecurityError(logger, channelName, error) {
4832
2505
  const prefix = `${channelName} security error:`;
4833
2506
  if (error.code === 'unknown') {
@@ -4838,37 +2511,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4838
2511
  }
4839
2512
  }
4840
2513
 
4841
- /**
4842
- * Route encrypted messages through security transport.
4843
- *
4844
- * Handles Uint8Array payloads received via postMessage, routing them
4845
- * through the appropriate channel's security transport for decryption.
4846
- *
4847
- * @module broker/routing/route-encrypted-message
4848
- */
4849
- /**
4850
- * Routes an encrypted message to the appropriate channel for decryption.
4851
- *
4852
- * This function handles Uint8Array payloads received via postMessage:
4853
- * 1. Identifies the target channel based on message origin
4854
- * 2. Routes the encrypted payload through the channel's security transport
4855
- * 3. The security transport decrypts and invokes the registered receive handler
4856
- *
4857
- * If no matching channel is found or the channel has no security transport,
4858
- * the message is silently dropped (with optional debug logging).
4859
- *
4860
- * @param context - Routing context with state, registry, actions, and logger
4861
- * @param router - Message router for handling decrypted actions
4862
- * @param event - Message event containing the encrypted Uint8Array payload
4863
- *
4864
- * @example Routing encrypted payloads
4865
- * ```typescript
4866
- * // In broker's onMessage handler:
4867
- * if (event.data instanceof Uint8Array) {
4868
- * routeEncryptedMessage(routingContext, router, event)
4869
- * }
4870
- * ```
4871
- */
4872
2514
  function routeEncryptedMessage(context, router, event) {
4873
2515
  const { state, registry, logger } = context;
4874
2516
  const origin = event?.origin;
@@ -4905,19 +2547,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4905
2547
  channel.notifyEvent('security-error', errorData);
4906
2548
  }
4907
2549
  }
4908
- /**
4909
- * Finds a channel by origin in the registry.
4910
- *
4911
- * Since encrypted messages don't contain senderId, we must match
4912
- * by origin. This works because each channel has a unique target window
4913
- * and thus a unique origin.
4914
- *
4915
- * @param registry - Channel registry to search
4916
- * @param origin - Origin of the message sender
4917
- * @returns The matching channel handle, or undefined if not found
4918
- *
4919
- * @internal
4920
- */
4921
2550
  function findChannelByOrigin(registry, origin) {
4922
2551
  const allChannels = getAll(registry);
4923
2552
  for (const channel of allChannels) {
@@ -4936,30 +2565,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4936
2565
  return undefined;
4937
2566
  }
4938
2567
 
4939
- /**
4940
- * Logs an action in a structured format.
4941
- *
4942
- * @param logger - Logger instance
4943
- * @param action - Action to log
4944
- * @param direction - Direction of action ('sent' or 'received')
4945
- */
4946
2568
  function logAction(logger, action, direction) {
4947
2569
  logger.debug(`Action ${direction}:`, action.type, action);
4948
2570
  }
4949
2571
 
4950
- /**
4951
- * Routes a message to the appropriate handler.
4952
- *
4953
- * @param router - Handler map containing action type to handler mappings
4954
- * @param context - Routing context with state, registry, actions, and logger
4955
- * @param message - Incoming message event containing the action to route
4956
- *
4957
- * @example Routing actions to handlers
4958
- * ```typescript
4959
- * const router = createRouter({ 'MESSAGE': handleMessage })
4960
- * routeMessage(router, routingContext, incomingEvent)
4961
- * ```
4962
- */
4963
2572
  function routeMessage(router, context, message) {
4964
2573
  const { logger } = context;
4965
2574
  try {
@@ -4982,26 +2591,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
4982
2591
  }
4983
2592
  }
4984
2593
 
4985
- /**
4986
- * Filters message origin against whitelist/blacklist
4987
- *
4988
- * @param origin - The origin to check
4989
- * @param whitelist - List of allowed origins (takes precedence)
4990
- * @param blacklist - List of blocked origins
4991
- * @returns true if origin is allowed, false otherwise
4992
- *
4993
- * @example Filtering with a whitelist
4994
- * ```typescript
4995
- * filterOrigin('https://app.example.com', ['https://app.example.com'])
4996
- * // => true
4997
- * ```
4998
- *
4999
- * @example Filtering with a blacklist
5000
- * ```typescript
5001
- * filterOrigin('https://untrusted.com', [], ['https://untrusted.com'])
5002
- * // => false
5003
- * ```
5004
- */
5005
2594
  function filterOrigin(origin, whitelist = [], blacklist = []) {
5006
2595
  if (whitelist && whitelist.length > 0) {
5007
2596
  return whitelist.includes(origin);
@@ -5012,53 +2601,21 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5012
2601
  return true;
5013
2602
  }
5014
2603
 
5015
- /**
5016
- * Validates that a security policy is a function
5017
- *
5018
- * @param policy - The policy to validate
5019
- * @throws {Error} If policy is not a function
5020
- *
5021
- * @example Valid policy function
5022
- * ```typescript
5023
- * validatePolicy((event) => event.origin === 'https://trusted.com')
5024
- * // No error thrown
5025
- * ```
5026
- *
5027
- * @example Invalid policy throws
5028
- * ```typescript
5029
- * validatePolicy('not-a-function')
5030
- * // Throws: Security policy must be a function...
5031
- * ```
5032
- */
5033
2604
  function validatePolicy(policy) {
5034
2605
  if (typeof policy !== 'function') {
5035
2606
  throw createError('Security policy must be a function that returns true or false.');
5036
2607
  }
5037
2608
  }
5038
2609
 
5039
- /**
5040
- * Creates a message broker instance
5041
- *
5042
- * @param config - Broker configuration
5043
- * @param config.name - Unique name for the broker instance
5044
- * @param config.contract - Channel contract defining message protocols
5045
- * @param config.settings - Optional configuration overrides for broker behavior
5046
- * @returns Broker handle with public API
5047
- *
5048
- * @example Creating a message broker
5049
- * ```typescript
5050
- * const broker = createBroker({
5051
- * name: 'app-broker',
5052
- * contract: { messages: { ping: {}, pong: {} } },
5053
- * settings: { logLevel: 'warn' },
5054
- * })
5055
- * ```
5056
- */
5057
2610
  function createBroker(config) {
5058
2611
  assertNoCircularRef(config.contract, 'config.contract');
5059
2612
  assertNoCircularRef(config.settings, 'config.settings');
5060
2613
  validateName(config.name);
5061
2614
  validateContract$1(config.contract);
2615
+ const brokerWindow = config.window ?? (typeof window !== 'undefined' ? window : undefined);
2616
+ if (!brokerWindow) {
2617
+ throw createError('Cannot create broker: no window is available. Pass an explicit `window` in the broker config when running outside a browser environment.');
2618
+ }
5062
2619
  const mergedSettings = {
5063
2620
  ...defaultBrokerSettings,
5064
2621
  ...config.settings,
@@ -5072,7 +2629,7 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5072
2629
  const state = {
5073
2630
  id: uuidV4(),
5074
2631
  name: config.name,
5075
- window: window,
2632
+ window: brokerWindow,
5076
2633
  contract: config.contract,
5077
2634
  settings: mergedSettings,
5078
2635
  logger,
@@ -5125,10 +2682,7 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5125
2682
  }
5126
2683
  routeMessage(router, routingContext, event);
5127
2684
  };
5128
- /* istanbul ignore next -- environment detection for non-browser contexts */
5129
- if (typeof window !== 'undefined') {
5130
- window.addEventListener('message', onMessage);
5131
- }
2685
+ brokerWindow.addEventListener('message', onMessage);
5132
2686
  const broker = {
5133
2687
  id: state.id,
5134
2688
  name: state.name,
@@ -5197,10 +2751,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5197
2751
  return freeze(broker);
5198
2752
  }
5199
2753
 
5200
- /**
5201
- * Default contract allowing any message type.
5202
- * Useful for development and prototyping.
5203
- */
5204
2754
  const DEFAULT_CONTRACT = freeze({
5205
2755
  emitted: freeze([
5206
2756
  { type: 'MESSAGE', description: 'Generic message' },
@@ -5214,49 +2764,36 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5214
2764
  { type: 'ACK', description: 'Acknowledgment' },
5215
2765
  ]),
5216
2766
  });
5217
- /**
5218
- * Singleton broker instance with sensible defaults.
5219
- *
5220
- * Features:
5221
- * - Generic contract accepting MESSAGE, DATA, EVENT action types
5222
- * - No security restrictions (whitelist/blacklist)
5223
- * - Debug mode off by default
5224
- *
5225
- * @example
5226
- * ```typescript
5227
- * import { broker } from '@hyperfrontend/nexus'
5228
- *
5229
- * // Create a channel
5230
- * const channel = broker.addChannel('my-channel', targetWindow)
5231
- * channel.connect()
5232
- * channel.send('MESSAGE', { hello: 'world' })
5233
- * ```
5234
- */
5235
- createBroker({
5236
- name: 'default-broker',
5237
- contract: DEFAULT_CONTRACT,
2767
+
2768
+ const _Reflect$1 = globalThis.Reflect;
2769
+ const get = _Reflect$1.get;
2770
+ const has = _Reflect$1.has;
2771
+ const ownKeys = _Reflect$1.ownKeys;
2772
+ const getOwnPropertyDescriptor = _Reflect$1.getOwnPropertyDescriptor;
2773
+
2774
+ let instance = null;
2775
+ function resolveBroker() {
2776
+ if (!instance) {
2777
+ instance = createBroker({
2778
+ name: 'default-broker',
2779
+ contract: DEFAULT_CONTRACT,
2780
+ });
2781
+ }
2782
+ return instance;
2783
+ }
2784
+ new Proxy({}, {
2785
+ get: (_target, property) => get(resolveBroker(), property),
2786
+ has: (_target, property) => has(resolveBroker(), property),
2787
+ ownKeys: () => ownKeys(resolveBroker()),
2788
+ getOwnPropertyDescriptor: (_target, property) => {
2789
+ const descriptor = getOwnPropertyDescriptor(resolveBroker(), property);
2790
+ return descriptor ? { ...descriptor, configurable: true } : undefined;
2791
+ },
5238
2792
  });
5239
2793
 
5240
- // note: Runtime validation shared by the host/hostee factories and the config loader.
5241
- /**
5242
- * Narrows an unknown value to a non-null object.
5243
- *
5244
- * @param value - The value to test.
5245
- * @returns `true` when the value is a non-null, non-array object.
5246
- */
5247
2794
  function isRecord(value) {
5248
2795
  return typeof value === 'object' && value !== null && !isArray(value);
5249
2796
  }
5250
- /**
5251
- * Collects every problem with a single action list (`emitted` or `accepted`).
5252
- *
5253
- * Each malformed entry contributes its own message, distinguishing a non-object
5254
- * entry from one missing a usable `type`, so the caller can report them all at once.
5255
- *
5256
- * @param actions - The candidate action list.
5257
- * @param field - The field name, used to locate problems in messages.
5258
- * @param issues - The running list of human-readable problems, appended to in place.
5259
- */
5260
2797
  function collectActionListIssues(actions, field, issues) {
5261
2798
  if (!isArray(actions)) {
5262
2799
  issues.push(`"${field}" must be an array.`);
@@ -5270,14 +2807,21 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5270
2807
  if (typeof action['type'] !== 'string' || action['type'].length === 0) {
5271
2808
  issues.push(`"${field}[${index}]" must have a non-empty string "type".`);
5272
2809
  }
2810
+ if (action['respondsWith'] !== undefined && (typeof action['respondsWith'] !== 'string' || action['respondsWith'].length === 0)) {
2811
+ issues.push(`"${field}[${index}]" has a "respondsWith" that must be a non-empty string.`);
2812
+ }
2813
+ });
2814
+ }
2815
+ function collectRespondsWithIssues(actions, field, other, otherField, issues) {
2816
+ actions.forEach((action, index) => {
2817
+ if (action.respondsWith === undefined) {
2818
+ return;
2819
+ }
2820
+ if (!other.some((candidate) => candidate.type === action.respondsWith)) {
2821
+ issues.push(`"${field}[${index}]" responds with "${action.respondsWith}", but "${otherField}" has no action of that type.`);
2822
+ }
5273
2823
  });
5274
2824
  }
5275
- /**
5276
- * Names the kind of an unexpected value for an error message.
5277
- *
5278
- * @param value - The value to describe.
5279
- * @returns A short label such as `null`, `an array`, or `a number`.
5280
- */
5281
2825
  function describeType(value) {
5282
2826
  if (value === null) {
5283
2827
  return 'null';
@@ -5287,22 +2831,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5287
2831
  }
5288
2832
  return `a ${typeof value}`;
5289
2833
  }
5290
- /**
5291
- * Validates an unknown value as a {@link FeatureContract}.
5292
- *
5293
- * Reports every malformed action at once rather than stopping at the first, so a
5294
- * single error message lists all the problems to fix.
5295
- *
5296
- * @param contract - The candidate contract, typically parsed from disk.
5297
- * @returns The validated contract, typed.
5298
- * @throws {Error} When the value is not an object, or any action is malformed.
5299
- *
5300
- * @example Validating a parsed contract file
5301
- * ```typescript
5302
- * const contract = validateContract(parse(readFileSync('clock.contract.json', 'utf8')))
5303
- * contract.emitted.forEach((action) => console.log(action.type))
5304
- * ```
5305
- */
5306
2834
  function validateContract(contract) {
5307
2835
  if (!isRecord(contract)) {
5308
2836
  throw createError(`Invalid contract: expected an object with "emitted" and "accepted" arrays, but got ${describeType(contract)}.`);
@@ -5310,6 +2838,12 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5310
2838
  const issues = [];
5311
2839
  collectActionListIssues(contract['emitted'], 'emitted', issues);
5312
2840
  collectActionListIssues(contract['accepted'], 'accepted', issues);
2841
+ if (issues.length === 0) {
2842
+ const emitted = contract['emitted'];
2843
+ const accepted = contract['accepted'];
2844
+ collectRespondsWithIssues(emitted, 'emitted', accepted, 'accepted', issues);
2845
+ collectRespondsWithIssues(accepted, 'accepted', emitted, 'emitted', issues);
2846
+ }
5313
2847
  if (issues.length > 0) {
5314
2848
  throw createError(`Invalid contract:\n${issues.map((issue) => ` - ${issue}`).join('\n')}`);
5315
2849
  }
@@ -5319,47 +2853,29 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5319
2853
  };
5320
2854
  }
5321
2855
 
5322
- /**
5323
- * Internal control message types carried on the feature channel and hidden from consumers.
5324
- */
2856
+ const CONTROL_PREFIX = '__hf:';
5325
2857
  const ControlType = freeze({
5326
- /** Hostee-to-host liveness beat. */
5327
2858
  Beat: '__hf:beat',
5328
- /** Hostee-to-host content-size announcement. */
5329
2859
  Size: '__hf:size',
2860
+ Request: '__hf:request',
2861
+ Response: '__hf:response',
5330
2862
  });
5331
- /**
5332
- * Extends a feature contract so the channel may also send and receive control traffic.
5333
- *
5334
- * @param contract - The consumer-facing feature contract.
5335
- * @returns A contract that additionally permits the reserved control types.
5336
- *
5337
- * @example Building a broker contract that carries the control plane
5338
- * ```typescript
5339
- * const broker = createBroker({ name, contract: withControlContract(contract) })
5340
- * ```
5341
- */
2863
+ function isControlType(type) {
2864
+ return type.startsWith(CONTROL_PREFIX);
2865
+ }
5342
2866
  function withControlContract(contract) {
5343
- // note: Fresh action literals per direction — sharing references across emitted/accepted trips nexus's circular-reference guard, which flags any repeated object.
2867
+ const controlActions = () => [
2868
+ { type: ControlType.Beat },
2869
+ { type: ControlType.Size },
2870
+ { type: ControlType.Request },
2871
+ { type: ControlType.Response },
2872
+ ];
5344
2873
  return {
5345
- emitted: [...contract.emitted, { type: ControlType.Beat }, { type: ControlType.Size }],
5346
- accepted: [...contract.accepted, { type: ControlType.Beat }, { type: ControlType.Size }],
2874
+ emitted: [...contract.emitted, ...controlActions()],
2875
+ accepted: [...contract.accepted, ...controlActions()],
5347
2876
  };
5348
2877
  }
5349
2878
 
5350
- /**
5351
- * Creates an {@link EventEmitter} backed by a plain registry.
5352
- *
5353
- * @returns A frozen emitter instance.
5354
- *
5355
- * @example Subscribing and emitting
5356
- * ```typescript
5357
- * const emitter = createEventEmitter()
5358
- * const off = emitter.on('open', () => console.log('opened'))
5359
- * emitter.emit('open')
5360
- * off()
5361
- * ```
5362
- */
5363
2879
  function createEventEmitter() {
5364
2880
  const registry = {};
5365
2881
  const on = (event, handler) => {
@@ -5375,111 +2891,111 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5375
2891
  return freeze({ on, emit });
5376
2892
  }
5377
2893
 
5378
- /**
5379
- * Safe Promise factory and bound static methods.
5380
- *
5381
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/promise
5382
- */
5383
- /* eslint-disable workspace/lib-require-jsdoc-example */
5384
2894
  const _Promise = globalThis.Promise;
5385
2895
  const _Reflect = globalThis.Reflect;
5386
- /**
5387
- * (Safe copy) Creates a new Promise using the captured Promise constructor.
5388
- * Use this instead of `new Promise()`.
5389
- *
5390
- * @param executor - The executor function.
5391
- * @returns A new Promise instance.
5392
- */
5393
2896
  const createPromise = (executor) => _Reflect.construct(_Promise, [executor]);
5394
- /**
5395
- * (Safe copy) Returns a Promise that resolves with the given value.
5396
- */
5397
- _Promise.resolve.bind(_Promise);
5398
- /**
5399
- * (Safe copy) Returns a Promise that rejects with the given reason.
5400
- */
5401
- _Promise.reject.bind(_Promise);
5402
- /**
5403
- * (Safe copy) Returns a Promise that resolves when all promises resolve.
5404
- */
2897
+ const promiseResolve = _Promise.resolve.bind(_Promise);
2898
+ const promiseReject = _Promise.reject.bind(_Promise);
5405
2899
  _Promise.all.bind(_Promise);
5406
- /**
5407
- * (Safe copy) Returns a Promise that resolves/rejects with the first settled promise.
5408
- */
5409
2900
  _Promise.race.bind(_Promise);
5410
- /**
5411
- * (Safe copy) Returns a Promise that resolves when all promises settle.
5412
- */
5413
2901
  _Promise.allSettled.bind(_Promise);
5414
- /**
5415
- * (Safe copy) Returns a Promise that resolves with the first fulfilled promise.
5416
- */
5417
2902
  _Promise.any.bind(_Promise);
5418
- /**
5419
- * (Safe copy) Creates a Promise along with its resolve and reject functions.
5420
- * Note: Available only in ES2024+ environments.
5421
- */
5422
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5423
2903
  _Promise.withResolvers?.bind(_Promise);
5424
2904
 
5425
- /**
5426
- * Safe copies of Timer/Scheduling built-in functions.
5427
- *
5428
- * These references are captured at module initialization time to protect against
5429
- * prototype pollution attacks. Import only what you need for tree-shaking.
5430
- *
5431
- * @module @hyperfrontend/immutable-api-utils/built-in-copy/timers
5432
- */
2905
+ const _setTimeout = globalThis.setTimeout;
5433
2906
  const _setInterval = globalThis.setInterval;
2907
+ const _clearTimeout = globalThis.clearTimeout;
5434
2908
  const _clearInterval = globalThis.clearInterval;
5435
- /**
5436
- * (Safe copy) Repeatedly calls a function with a fixed time delay between each call.
5437
- *
5438
- * @param callback - Function to call at each interval.
5439
- * @param delay - Time in milliseconds between calls.
5440
- * @param args - Additional arguments to pass to the callback.
5441
- * @returns A numeric ID for the interval.
5442
- *
5443
- * @example Setting an interval
5444
- * ```typescript
5445
- * let count = 0
5446
- * const intervalId = setInterval(() => {
5447
- * count++
5448
- * if (count >= 5) clearInterval(intervalId)
5449
- * }, 1000)
5450
- * ```
5451
- */
2909
+ const setTimeout = (callback, delay, ...args) => _setTimeout(callback, delay, ...args);
5452
2910
  const setInterval = (callback, delay, ...args) => _setInterval(callback, delay, ...args);
5453
- /**
5454
- * (Safe copy) Cancels a timed, repeating action previously established by setInterval.
5455
- *
5456
- * @param id - The identifier of the interval to cancel.
5457
- *
5458
- * @example Canceling an interval
5459
- * ```typescript
5460
- * const intervalId = setInterval(() => console.log('tick'), 1000)
5461
- * // Stop after some condition
5462
- * clearInterval(intervalId)
5463
- * ```
5464
- */
2911
+ const clearTimeout = (id) => {
2912
+ _clearTimeout(id);
2913
+ };
5465
2914
  const clearInterval = (id) => {
5466
2915
  _clearInterval(id);
5467
2916
  };
5468
2917
 
5469
- // note: Baked-in liveness — the feature emits a beat on a fixed cadence with no consumer involvement, and the host monitors these to detect a hung or crashed feature.
2918
+ const DEFAULT_TIMEOUT_MS = 30000;
2919
+ function createRequestPeer(origin, send) {
2920
+ let pending = {};
2921
+ const handlers = {};
2922
+ let nextCorrelation = 0;
2923
+ const take = (correlationId) => {
2924
+ const entry = pending[correlationId];
2925
+ if (entry) {
2926
+ clearTimeout(entry.timer);
2927
+ delete pending[correlationId];
2928
+ }
2929
+ return entry;
2930
+ };
2931
+ const respond = (request, outcome) => send(ControlType.Response, { correlationId: request.correlationId, from: origin, innerType: request.innerType, ...outcome });
2932
+ const answer = (request) => {
2933
+ const handler = handlers[request.innerType];
2934
+ if (!handler) {
2935
+ respond(request, { ok: false, error: `No handler is registered for '${request.innerType}'.` });
2936
+ return;
2937
+ }
2938
+ promiseResolve()
2939
+ .then(() => handler(request.payload))
2940
+ .then((payload) => respond(request, { ok: true, payload }), (error) => respond(request, { ok: false, error: error instanceof Error ? error.message : `${error}` }));
2941
+ };
2942
+ const settle = (response) => {
2943
+ const entry = take(response.correlationId);
2944
+ if (!entry) {
2945
+ return;
2946
+ }
2947
+ if (response.ok) {
2948
+ entry.resolve(response.payload);
2949
+ return;
2950
+ }
2951
+ entry.reject(createError(response.error ?? `Request '${response.innerType}' failed.`));
2952
+ };
2953
+ const dispatch = (type, data) => {
2954
+ const envelope = (typeof data === 'object' ? data : null);
2955
+ if (!envelope || envelope.from === origin) {
2956
+ return;
2957
+ }
2958
+ if (type === ControlType.Request) {
2959
+ answer(envelope);
2960
+ return;
2961
+ }
2962
+ if (type === ControlType.Response) {
2963
+ settle(envelope);
2964
+ }
2965
+ };
2966
+ const request = (type, data, options) => createPromise((resolve, reject) => {
2967
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
2968
+ const correlationId = `${origin}-${(nextCorrelation += 1)}`;
2969
+ const timer = setTimeout(() => {
2970
+ delete pending[correlationId];
2971
+ reject(createError(`Request '${type}' timed out after ${timeoutMs}ms.`));
2972
+ }, timeoutMs);
2973
+ pending[correlationId] = { resolve, reject, timer };
2974
+ send(ControlType.Request, { correlationId, from: origin, innerType: type, payload: data });
2975
+ });
2976
+ const handle = (type, handler) => {
2977
+ if (handlers[type]) {
2978
+ throw createError(`A handler for '${type}' is already registered.`);
2979
+ }
2980
+ handlers[type] = handler;
2981
+ return () => {
2982
+ if (handlers[type] === handler) {
2983
+ delete handlers[type];
2984
+ }
2985
+ };
2986
+ };
2987
+ const rejectAll = (reason) => {
2988
+ const failed = values(pending);
2989
+ pending = {};
2990
+ for (const entry of failed) {
2991
+ clearTimeout(entry.timer);
2992
+ entry.reject(createError(reason));
2993
+ }
2994
+ };
2995
+ return freeze({ request, handle, dispatch, rejectAll });
2996
+ }
2997
+
5470
2998
  const BEAT_INTERVAL_MS = 1000;
5471
- /**
5472
- * Creates the hostee-side heartbeat emitter.
5473
- *
5474
- * @param send - The control-channel send function (receives the reserved beat type).
5475
- * @returns A start/stop handle for the beat loop.
5476
- *
5477
- * @example Pulsing the host while connected
5478
- * ```typescript
5479
- * const heartbeat = createHeartbeatEmitter((type) => channel.send(type))
5480
- * heartbeat.start()
5481
- * ```
5482
- */
5483
2999
  function createHeartbeatEmitter(send) {
5484
3000
  let timer;
5485
3001
  return {
@@ -5496,24 +3012,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5496
3012
  };
5497
3013
  }
5498
3014
 
5499
- /**
5500
- * Observes an element for size changes and triggers a callback when resized.
5501
- *
5502
- * @param element - The element to observe for resize events
5503
- * @param callback - The function to call when the element is resized
5504
- * @returns A cleanup function to stop observing the element
5505
- *
5506
- * @example Observing element resize
5507
- * ```typescript
5508
- * const container = document.getElementById('resizable-panel')
5509
- * const stopObserving = onElementResize(container, (rect) => {
5510
- * console.log(`New size: ${rect.width}x${rect.height}`)
5511
- * })
5512
- *
5513
- * // Stop observing when done
5514
- * stopObserving()
5515
- * ```
5516
- */
5517
3015
  function onElementResize(element, callback) {
5518
3016
  const resizeObserver = new ResizeObserver((entries) => {
5519
3017
  for (const entry of entries) {
@@ -5530,25 +3028,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5530
3028
  };
5531
3029
  }
5532
3030
 
5533
- /**
5534
- * Converts a CSS object into a CSS string suitable for inline styles or style sheets.
5535
- * Automatically converts camelCase properties to kebab-case.
5536
- *
5537
- * @param cssObj - The CSS object with property-value pairs
5538
- * @returns A CSS string representation
5539
- *
5540
- * @example Converting style object to CSS
5541
- * ```typescript
5542
- * const styles = {
5543
- * backgroundColor: '#f0f0f0',
5544
- * fontSize: '14px',
5545
- * marginTop: '8px'
5546
- * }
5547
- *
5548
- * cssObjectToString(styles)
5549
- * // => 'background-color: #f0f0f0; font-size: 14px; margin-top: 8px; '
5550
- * ```
5551
- */
5552
3031
  function cssObjectToString(cssObj) {
5553
3032
  const errors = [];
5554
3033
  const cssString = entries(cssObj).reduce((prev, [property, value]) => {
@@ -5568,24 +3047,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5568
3047
  return cssString;
5569
3048
  }
5570
3049
 
5571
- /**
5572
- * Validates whether a string is a valid CSS selector by attempting to query with it.
5573
- *
5574
- * @param selector - The CSS selector string to validate
5575
- * @returns True if the selector is valid, false otherwise
5576
- *
5577
- * @example Validating CSS selectors
5578
- * ```typescript
5579
- * isValidCssSelector('.my-class')
5580
- * // => true
5581
- *
5582
- * isValidCssSelector('#header nav > ul')
5583
- * // => true
5584
- *
5585
- * isValidCssSelector('[invalid')
5586
- * // => false
5587
- * ```
5588
- */
5589
3050
  function isValidCssSelector(selector) {
5590
3051
  try {
5591
3052
  document.createDocumentFragment().querySelector(selector);
@@ -5596,31 +3057,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5596
3057
  }
5597
3058
  }
5598
3059
 
5599
- /**
5600
- * Generates a CSS rule string from a given selector and style declaration.
5601
- *
5602
- * This function takes a CSS selector and either a string or a CSSStyleDeclaration object
5603
- * representing the styles to be applied. It validates the selector and converts the CSS
5604
- * object to a string if needed. The function then constructs and returns a valid
5605
- * CSS rule as a string.
5606
- *
5607
- * @param selector - The CSS selector to which the styles will be applied
5608
- * @param css - The styles to apply, either as a string or CSSStyleDeclaration object
5609
- * @returns A string representing a complete CSS rule
5610
- * @throws {Error} When the selector is invalid or the css argument is not a valid string or object
5611
- *
5612
- * @example With style object
5613
- * ```typescript
5614
- * cssRule('.button', { padding: '8px 16px', borderRadius: '4px' })
5615
- * // => '.button{padding: 8px 16px; border-radius: 4px}'
5616
- * ```
5617
- *
5618
- * @example With CSS string
5619
- * ```typescript
5620
- * cssRule('.button:hover', 'background-color: #007bff; color: white')
5621
- * // => '.button:hover{background-color: #007bff; color: white}'
5622
- * ```
5623
- */
5624
3060
  function cssRule(selector, css) {
5625
3061
  if (!isValidCssSelector(selector)) {
5626
3062
  throw createError('A valid css select must be provided');
@@ -5634,23 +3070,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5634
3070
  return `${selector}{${css}}`;
5635
3071
  }
5636
3072
 
5637
- /**
5638
- * Creates CSS rules from a styles object, converting each selector-style pair into CSS rule strings.
5639
- *
5640
- * @param styles - An object mapping CSS selectors to style objects
5641
- * @returns A string containing all CSS rules separated by newlines
5642
- *
5643
- * @example Creating CSS rules from object
5644
- * ```typescript
5645
- * const styles = {
5646
- * '.card': { padding: '16px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)' },
5647
- * '.card-title': { fontSize: '18px', fontWeight: 'bold' }
5648
- * }
5649
- *
5650
- * cssRules(styles)
5651
- * // => '.card{padding: 16px; box-shadow: 0 2px 4px rgba(0,0,0,0.1)}\n.card-title{font-size: 18px; font-weight: bold}'
5652
- * ```
5653
- */
5654
3073
  function cssRules(styles) {
5655
3074
  if (getType(styles) !== 'object')
5656
3075
  return '';
@@ -5663,33 +3082,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5663
3082
  const labels = createSet();
5664
3083
  const labeledStylesheets = createMap();
5665
3084
  const stylesheetLabels = createWeakMap();
5666
- /**
5667
- * Adds a new stylesheet to the document with optional label.
5668
- *
5669
- * @param css - The CSS rules to be added in the new stylesheet
5670
- * @param label - Optional label for the new stylesheet
5671
- * @returns A tuple where the first item is the created HTMLStyleElement, and the second item is a cleanup function
5672
- * @throws {Error} When css is not a string or StyleMap, is empty, or a stylesheet with the same label already exists
5673
- *
5674
- * @example CSS string
5675
- * ```typescript
5676
- * const [styleElement, removeStyles] = addStylesheet(`
5677
- * .modal { display: flex; align-items: center; }
5678
- * .modal-overlay { background: rgba(0, 0, 0, 0.5); }
5679
- * `, 'modal-styles')
5680
- *
5681
- * // Remove when done
5682
- * removeStyles()
5683
- * ```
5684
- *
5685
- * @example StyleMap object
5686
- * ```typescript
5687
- * const [styleElement, removeStyles] = addStylesheet({
5688
- * '.button': { backgroundColor: '#3498db', padding: '10px 20px' },
5689
- * '.button:hover': { backgroundColor: '#2980b9' },
5690
- * })
5691
- * ```
5692
- */
5693
3085
  function addStylesheet(css, label) {
5694
3086
  if (getType(css) === 'object') {
5695
3087
  css = cssRules(css);
@@ -5704,23 +3096,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5704
3096
  const removeCallback = () => removeStylesheet(style);
5705
3097
  return [style, removeCallback];
5706
3098
  }
5707
- /**
5708
- * Removes a stylesheet from the document.
5709
- *
5710
- * @param {string | HTMLStyleElement} ref - The label or the HTMLStyleElement of the stylesheet to be removed.
5711
- *
5712
- * @example By label
5713
- * ```typescript
5714
- * addStylesheet('.theme { color: red; }', 'theme-styles')
5715
- * removeStylesheet('theme-styles')
5716
- * ```
5717
- *
5718
- * @example By element reference
5719
- * ```typescript
5720
- * const [styleElement] = addStylesheet('.custom { margin: 0; }')
5721
- * removeStylesheet(styleElement)
5722
- * ```
5723
- */
5724
3099
  function removeStylesheet(ref) {
5725
3100
  const isLabel = getType(ref) === 'string';
5726
3101
  let style;
@@ -5738,7 +3113,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5738
3113
  stylesheets.delete(style);
5739
3114
  }
5740
3115
  catch {
5741
- /** Swallow any errors */
5742
3116
  }
5743
3117
  try {
5744
3118
  labels.delete(label);
@@ -5746,35 +3120,13 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5746
3120
  stylesheetLabels.delete(style);
5747
3121
  }
5748
3122
  catch {
5749
- /** Swallow any errors */
5750
3123
  }
5751
3124
  }
5752
3125
 
5753
- // note: The feature page resets its own body so the embedded UI fills the iframe edge-to-edge with a transparent backdrop; the host cannot touch the cross-origin body itself.
5754
3126
  const BODY_RESET_CSS = 'html,body{margin:0;padding:0;background:transparent}';
5755
- /**
5756
- * Neutralizes the feature page's body so the embedded UI is neither clipped nor padded.
5757
- *
5758
- * @example Resetting the body when a feature initializes
5759
- * ```typescript
5760
- * applyBodyReset()
5761
- * ```
5762
- */
5763
3127
  function applyBodyReset() {
5764
3128
  addStylesheet(BODY_RESET_CSS);
5765
3129
  }
5766
- /**
5767
- * Creates the hostee-side content-size announcer.
5768
- *
5769
- * @param send - The control-channel send function (receives the reserved size type).
5770
- * @returns A start/stop handle for the size-announcement loop.
5771
- *
5772
- * @example Announcing size to the host while connected
5773
- * ```typescript
5774
- * const announcer = createSizeAnnouncer((type, data) => channel.send(type, data))
5775
- * announcer.start()
5776
- * ```
5777
- */
5778
3130
  function createSizeAnnouncer(send) {
5779
3131
  let cleanup;
5780
3132
  const announce = () => send(ControlType.Size, { width: document.body.scrollWidth, height: document.body.scrollHeight });
@@ -5795,18 +3147,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5795
3147
  };
5796
3148
  }
5797
3149
 
5798
- // note: The host connects from a parent window (embedded iframe) or an opener window (popup/standalone); a top-level document has neither.
5799
- /**
5800
- * Resolves the window the host is expected to message the feature from.
5801
- *
5802
- * @param win - The feature's own window (`globalThis.window` in production).
5803
- * @returns The parent or opener window, or `null` when running top-level.
5804
- *
5805
- * @example Resolving the host window
5806
- * ```typescript
5807
- * const hostWindow = resolveHostWindow(window)
5808
- * ```
5809
- */
5810
3150
  function resolveHostWindow(win) {
5811
3151
  if (win.parent !== win) {
5812
3152
  return win.parent;
@@ -5816,23 +3156,10 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5816
3156
  }
5817
3157
  return null;
5818
3158
  }
5819
- /**
5820
- * Wires a hostee channel into the emitter and assembles the public handle.
5821
- *
5822
- * @param broker - The nexus broker for this feature.
5823
- * @param hostWindow - The resolved host window, or `null` when unembedded.
5824
- * @param emitter - The subscription registry backing `handle.on`.
5825
- * @returns The frozen {@link FeatureHandle}.
5826
- *
5827
- * @example Assembling a feature handle around a broker
5828
- * ```typescript
5829
- * const handle = createFeatureHandle(broker, resolveHostWindow(window), emitter)
5830
- * await handle.ready()
5831
- * ```
5832
- */
5833
3159
  function createFeatureHandle(broker, hostWindow, emitter) {
5834
3160
  let channel = null;
5835
3161
  let opened = false;
3162
+ const requests = createRequestPeer('feature', (type, data) => channel?.send(type, data));
5836
3163
  if (hostWindow) {
5837
3164
  const activeChannel = broker.addChannel('host', hostWindow);
5838
3165
  channel = activeChannel;
@@ -5849,14 +3176,25 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5849
3176
  emitter.emit('close');
5850
3177
  heartbeat.stop();
5851
3178
  announcer.stop();
3179
+ requests.rejectAll('The host channel closed before the host responded.');
5852
3180
  });
5853
3181
  activeChannel.on('deny', (data) => emitter.emit('error', data));
5854
3182
  activeChannel.on('invalid', (data) => emitter.emit('error', data));
5855
- activeChannel.onMessage((message) => emitter.emit(message.type, message.data));
3183
+ activeChannel.onMessage((message) => {
3184
+ if (isControlType(message.type)) {
3185
+ requests.dispatch(message.type, message.data);
3186
+ return;
3187
+ }
3188
+ emitter.emit(message.type, message.data);
3189
+ });
5856
3190
  activeChannel.connect();
5857
3191
  }
5858
3192
  return freeze({
5859
3193
  send: (type, data) => channel?.send(type, data),
3194
+ request: (type, data, options) => channel
3195
+ ? requests.request(type, data, options)
3196
+ : promiseReject(createError(`Cannot send request '${type}': the feature is not connected to a host.`)),
3197
+ handle: requests.handle,
5860
3198
  on: emitter.on,
5861
3199
  ready: () => createPromise((resolve) => {
5862
3200
  if (opened) {
@@ -5869,22 +3207,6 @@ var HyperfrontendFeaturesHostee = (function (exports) {
5869
3207
  });
5870
3208
  }
5871
3209
 
5872
- /**
5873
- * Initializes a feature app on the hostee side and waits for the host connection.
5874
- *
5875
- * Creates a nexus broker for the feature, resolves the host window, and returns
5876
- * a handle for messaging and lifecycle.
5877
- *
5878
- * @param options - Feature name and contract.
5879
- * @returns A handle exposing `send`, `on`, `ready`, and `close`.
5880
- *
5881
- * @example Initializing a clock feature
5882
- * ```typescript
5883
- * const feature = createFeature({ name: 'clock', contract })
5884
- * feature.ready().then(() => feature.send('timeUpdated', { time: Date.now() }))
5885
- * feature.on('setTimezone', (data) => console.log(data))
5886
- * ```
5887
- */
5888
3210
  function createFeature(options) {
5889
3211
  const contract = withControlContract(validateContract(options.contract));
5890
3212
  const emitter = createEventEmitter();