@hile/message-ipc 4.0.1 → 4.0.3

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 (3) hide show
  1. package/AI.md +40 -25
  2. package/README.md +13 -6
  3. package/package.json +3 -3
package/AI.md CHANGED
@@ -32,13 +32,14 @@ Message handler file:
32
32
 
33
33
  ```ts
34
34
  // src/messages/ping.msg.ts
35
- import { defineMessage } from '@hile/message-loader'
35
+ import { defineMicroMessage } from '@hile/micro'
36
36
 
37
- export default defineMessage(async ({ data, params }) => {
37
+ export default defineMicroMessage(async ({ data, params, invocation }) => {
38
38
  return {
39
39
  type: 'pong',
40
40
  data,
41
41
  params,
42
+ requestId: invocation.context.values.requestId,
42
43
  timestamp: Date.now(),
43
44
  }
44
45
  })
@@ -71,7 +72,11 @@ export default defineService('micro.app', async (shutdown) => {
71
72
  Caller:
72
73
 
73
74
  ```ts
74
- const result = await app.call('example.service', '/ping', { hello: 'world' })
75
+ import { randomUUID } from 'node:crypto'
76
+ import { createExecutionContext } from '@hile/context'
77
+
78
+ const context = createExecutionContext({ requestId: randomUUID() })
79
+ const result = await app.call('example.service', '/ping', { hello: 'world' }, { context })
75
80
  ```
76
81
 
77
82
  ## More Examples
@@ -80,11 +85,11 @@ Streaming handler:
80
85
 
81
86
  ```ts
82
87
  // src/messages/events.msg.ts
83
- import { defineMessage } from '@hile/message-loader'
88
+ import { defineMicroMessage } from '@hile/micro'
84
89
 
85
- export default defineMessage(async function* () {
90
+ export default defineMicroMessage(async function* ({ invocation }) {
86
91
  for (let i = 0; i < 3; i++) {
87
- yield { seq: i }
92
+ yield { seq: i, requestId: invocation.context.values.requestId }
88
93
  }
89
94
  })
90
95
  ```
@@ -92,7 +97,7 @@ export default defineMessage(async function* () {
92
97
  Streaming caller:
93
98
 
94
99
  ```ts
95
- const stream = await app.stream('example.service', '/events', {})
100
+ const stream = await app.stream('example.service', '/events', {}, { context })
96
101
  for await (const chunk of stream) {
97
102
  console.log(chunk)
98
103
  }
@@ -129,12 +134,13 @@ Use the message packages for request/response messaging over WebSocket, process
129
134
 
130
135
  - Do not use `stream()` for normal single-result calls.
131
136
  - Do not rely on message IDs for business idempotency. They are transport IDs.
132
- - Do not bypass `defineMessage()` for file-loaded handlers.
137
+ - Use `defineMicroMessage()` for Micro business handlers; reserve generic `defineMessage()` for transport-neutral loaders.
138
+ - Do not pass zero, fractional, non-finite, or oversized message timeouts. Explicit timeout values must be safe integers from `1` through `2_147_483_647` milliseconds.
133
139
 
134
140
  ## Install
135
141
 
136
142
  ```bash
137
- pnpm add @hile/micro @hile/message-loader @hile/message-ws
143
+ pnpm add @hile/context @hile/micro @hile/message-loader @hile/message-ws
138
144
  ```
139
145
 
140
146
  Use transport-specific packages only when you need to build custom IPC or worker-thread bridges.
@@ -143,7 +149,8 @@ Use transport-specific packages only when you need to build custom IPC or worker
143
149
 
144
150
  ```ts
145
151
  import { defineMessage, MessageLoader } from '@hile/message-loader'
146
- import { Application, Registry, Server } from '@hile/micro'
152
+ import { createExecutionContext } from '@hile/context'
153
+ import { Application, defineMicroMessage, Registry, Server } from '@hile/micro'
147
154
  import { MessageWs } from '@hile/message-ws'
148
155
  import { MessageIpc } from '@hile/message-ipc'
149
156
  import { MessageWorkerThread } from '@hile/message-worker-thread'
@@ -151,7 +158,7 @@ import { MessageWorkerThread } from '@hile/message-worker-thread'
151
158
 
152
159
  ## Compose With
153
160
 
154
- - `@hile/context` propagates context in micro message metadata.
161
+ - Pass `ExecutionContext` explicitly in every business call or stream option; the receiver gets it in `invocation.context`.
155
162
  - `@hile/redis-idempotency` protects retryable side effects in message handlers.
156
163
  - `@hile/redis-stream-queue` is better for durable background jobs.
157
164
 
@@ -160,10 +167,14 @@ import { MessageWorkerThread } from '@hile/message-worker-thread'
160
167
  - `MessageLoader` maps `*.msg.*` files to routes using `@hile/loader`.
161
168
  - `MessageLoader.dispatch(path, data, extras?)` invokes the matched handler.
162
169
  - `MessageModem._send()` returns a `Promise`.
170
+ - `MessageModem._send()` and `_push()` use a `30_000` ms timeout when none is provided. An explicit timeout must be a safe integer from `1` through `2_147_483_647`; invalid values throw `TypeError` before a message is sent.
163
171
  - `MessageModem._stream()` returns a Node `Readable` in object mode.
172
+ - Stream `timeout` and `idleTimeout` values use the same `1` through `2_147_483_647` ms range. The stream `window` must be a safe integer from `1` through `64` and defaults to `1`.
173
+ - Each modem schedules request, total-stream, and idle-stream deadlines through one internal deadline scheduler. This reduces active Node.js timers without changing timeout, cancellation, ordering, or error semantics.
174
+ - `@hile/message-ws` keeps public `decodeMessageFrame()` payloads isolated from caller-owned input by default. Its owned WebSocket `RawData` path uses a zero-copy binary Flight payload view internally.
164
175
  - A stream request requires `exec()` to return an async iterable.
165
- - `Application.call(namespace, url, data, options?)` returns a promise.
166
- - `Application.stream(namespace, url, data, options?)` returns a readable stream.
176
+ - `Application.call(namespace, url, data, options)` requires `options.context` and returns a promise.
177
+ - `Application.stream(namespace, url, data, options)` requires `options.context` and returns a readable stream.
167
178
  - `Application.publish(topic, payload)` returns an object with `update()` and `unpublish()`.
168
179
  - `Application.subscribe(topic, callback)` returns an unsubscribe function.
169
180
  - `Registry` stores service addresses and retained config/topic state under `~/.registry`.
@@ -177,9 +188,10 @@ import { MessageWorkerThread } from '@hile/message-worker-thread'
177
188
 
178
189
  ## Verification Checklist
179
190
 
180
- - Message files default-export `defineMessage(...)`.
181
- - RPC callers use `await app.call(...)`.
191
+ - Micro message files default-export `defineMicroMessage(...)` and receive `invocation.context`.
192
+ - RPC callers use `await app.call(..., { context })`.
182
193
  - Streaming handlers are async generators.
194
+ - Custom modem timeout values use the documented safe-integer range.
183
195
  - Registry is started before application nodes need discovery.
184
196
  - Micro apps use stable namespaces and advertise reachable hosts.
185
197
 
@@ -197,10 +209,10 @@ Provider handler:
197
209
 
198
210
  ```ts
199
211
  // src/messages/charge.msg.ts
200
- import { defineMessage } from '@hile/message-loader'
212
+ import { defineMicroMessage } from '@hile/micro'
201
213
 
202
- export default defineMessage(async ({ data }) => {
203
- return { charged: true, input: data }
214
+ export default defineMicroMessage(async ({ data, invocation }) => {
215
+ return { charged: true, input: data, requestId: invocation.context.values.requestId }
204
216
  })
205
217
  ```
206
218
 
@@ -228,10 +240,14 @@ export default defineService('billing.micro', async (shutdown) => {
228
240
  Consumer:
229
241
 
230
242
  ```ts
243
+ import { randomUUID } from 'node:crypto'
244
+ import { createExecutionContext } from '@hile/context'
245
+
246
+ const context = createExecutionContext({ requestId: randomUUID(), tenantId: 't1' })
231
247
  const result = await app.call('billing', '/charge', {
232
248
  tenantId: 't1',
233
249
  amount: 100,
234
- })
250
+ }, { context })
235
251
  ```
236
252
 
237
253
  ## File Layout
@@ -251,16 +267,15 @@ Use this recipe when services communicate over Hile registry-backed RPC.
251
267
  ## Packages To Use
252
268
 
253
269
  - `@hile/micro`
254
- - `@hile/message-loader`
255
- - `@hile/context` when context must cross service boundaries
270
+ - `@hile/context` for the required explicit execution context carrier
256
271
  - `@hile/redis-idempotency` for retryable side effects
257
272
 
258
273
  ## Implementation Steps
259
274
 
260
275
  1. Start a Registry with `hile registry`.
261
276
  2. Start providers with stable namespaces.
262
- 3. Load `*.msg.ts` handlers through `app.load()`.
263
- 4. Call providers with `await app.call(namespace, url, data)`.
277
+ 3. Default-export `defineMicroMessage()` handlers and load them through `app.load()`.
278
+ 4. Create context at ingress and call providers with `await app.call(namespace, url, data, { context })`.
264
279
  5. Use `app.stream()` only for async-generator handlers.
265
280
 
266
281
  ## Failure And Cleanup Behavior
@@ -273,8 +288,8 @@ Use this recipe when services communicate over Hile registry-backed RPC.
273
288
 
274
289
  - Registry is reachable.
275
290
  - Provider namespace matches consumer call.
276
- - Handlers default-export `defineMessage()`.
277
- - Consumer code awaits `app.call(...)` directly.
291
+ - Handlers default-export `defineMicroMessage()` and consume explicit invocation context when needed.
292
+ - Consumer code awaits `app.call(..., { context })` directly.
278
293
 
279
294
 
280
295
 
package/README.md CHANGED
@@ -22,13 +22,14 @@ Message handler file:
22
22
 
23
23
  ```ts
24
24
  // src/messages/ping.msg.ts
25
- import { defineMessage } from '@hile/message-loader'
25
+ import { defineMicroMessage } from '@hile/micro'
26
26
 
27
- export default defineMessage(async ({ data, params }) => {
27
+ export default defineMicroMessage(async ({ data, params, invocation }) => {
28
28
  return {
29
29
  type: 'pong',
30
30
  data,
31
31
  params,
32
+ requestId: invocation.context.values.requestId,
32
33
  timestamp: Date.now(),
33
34
  }
34
35
  })
@@ -61,14 +62,19 @@ export default defineService('micro.app', async (shutdown) => {
61
62
  Caller:
62
63
 
63
64
  ```ts
64
- const result = await app.call('example.service', '/ping', { hello: 'world' })
65
+ import { randomUUID } from 'node:crypto'
66
+ import { createExecutionContext } from '@hile/context'
67
+
68
+ const context = createExecutionContext({ requestId: randomUUID() })
69
+ const result = await app.call('example.service', '/ping', { hello: 'world' }, { context })
65
70
  ```
66
71
 
67
72
  ## Boundaries
68
73
 
69
74
  - Do not use `stream()` for normal single-result calls.
70
75
  - Do not rely on message IDs for business idempotency. They are transport IDs.
71
- - Do not bypass `defineMessage()` for file-loaded handlers.
76
+ - Use `defineMicroMessage()` for Micro business handlers; reserve generic `defineMessage()` for transport-neutral loaders.
77
+ - Do not pass zero, fractional, non-finite, or oversized message timeouts. Explicit timeout values must be safe integers from `1` through `2_147_483_647` milliseconds.
72
78
 
73
79
  - Appending a secondary response getter to `client.request('/x', data)`
74
80
  - Returning a plain object from a handler called through `stream()`.
@@ -77,9 +83,10 @@ const result = await app.call('example.service', '/ping', { hello: 'world' })
77
83
 
78
84
  ## Verify
79
85
 
80
- - Message files default-export `defineMessage(...)`.
81
- - RPC callers use `await app.call(...)`.
86
+ - Micro message files default-export `defineMicroMessage(...)` and receive `invocation.context`.
87
+ - RPC callers use `await app.call(..., { context })`.
82
88
  - Streaming handlers are async generators.
89
+ - Custom modem timeout values use the documented safe-integer range.
83
90
  - Registry is started before application nodes need discovery.
84
91
  - Micro apps use stable namespaces and advertise reachable hosts.
85
92
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hile/message-ipc",
3
- "version": "4.0.1",
3
+ "version": "4.0.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  "vitest": "^4.0.18"
24
24
  },
25
25
  "dependencies": {
26
- "@hile/message-modem": "^4.0.1"
26
+ "@hile/message-modem": "^4.0.3"
27
27
  },
28
- "gitHead": "fe98c6f8cca2860ccbb213c575cfda44588cbd06"
28
+ "gitHead": "3ea69973f9373ddb1f7d5d37338966fd7d081d66"
29
29
  }