@flighthq/ipc 0.5.1-next.704.19c91ec → 0.5.1-next.730.f29a5aa

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @flighthq/ipc
2
2
 
3
- Inter-process message reception over an explicit host capability
3
+ Inter-process messaging over explicit operation-tight host capabilities
4
4
 
5
5
  ## Install
6
6
 
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/ipc`. The `@flighthq
13
13
  This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
14
14
 
15
15
  - [Flight project](https://github.com/flighthq/flight)
16
- - [Source for @flighthq/ipc@0.5.1-next.704.19c91ec](https://github.com/flighthq/flight/tree/19c91ec3e569d6b3b471682726465a79fba9f8cb/packages/ipc)
17
- - [License](https://github.com/flighthq/flight/blob/19c91ec3e569d6b3b471682726465a79fba9f8cb/LICENSE.md)
16
+ - [Source for @flighthq/ipc@0.5.1-next.730.f29a5aa](https://github.com/flighthq/flight/tree/f29a5aab5db192284ce5cadf08ffae2649a598ea/packages/ipc)
17
+ - [License](https://github.com/flighthq/flight/blob/f29a5aab5db192284ce5cadf08ffae2649a598ea/LICENSE.md)
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { onIpcMessage, onceIpcMessage } from './contract';
1
+ export { invokeIpc, onIpcInvoke, onIpcMessage, onceIpcMessage, sendIpcMessage, sendIpcMessageTo } from './contract';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { onIpcMessage, onceIpcMessage } from './contract';
1
+ export { invokeIpc, onIpcInvoke, onIpcMessage, onceIpcMessage, sendIpcMessage, sendIpcMessageTo } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
package/dist/ipc.d.ts CHANGED
@@ -1,4 +1,8 @@
1
- import type { HasIpcMessage } from '@flighthq/types/contract';
1
+ import type { HasIpcHandle, HasIpcInvoke, HasIpcMessage, HasIpcSend, HasIpcTargetedSend } from '@flighthq/types/contract';
2
+ export declare function invokeIpc(host: HasIpcInvoke, channel: string, ...args: readonly unknown[]): Promise<unknown>;
2
3
  export declare function onceIpcMessage(host: HasIpcMessage, channel: string, listener: (...args: readonly unknown[]) => void): () => void;
4
+ export declare function onIpcInvoke(host: HasIpcHandle, channel: string, handler: (...args: readonly unknown[]) => unknown | Promise<unknown>): () => void;
3
5
  export declare function onIpcMessage(host: HasIpcMessage, channel: string, listener: (...args: readonly unknown[]) => void): () => void;
6
+ export declare function sendIpcMessage(host: HasIpcSend, channel: string, ...args: readonly unknown[]): void;
7
+ export declare function sendIpcMessageTo<Target>(host: HasIpcTargetedSend<Target>, target: NoInfer<Target>, channel: string, ...args: readonly unknown[]): void;
4
8
  //# sourceMappingURL=ipc.d.ts.map
package/dist/ipc.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAkB9D,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,GAC9C,MAAM,IAAI,CAiBZ;AAID,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,GAC9C,MAAM,IAAI,CAEZ"}
1
+ {"version":3,"file":"ipc.d.ts","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,UAAU,EACV,kBAAkB,EACnB,MAAM,0BAA0B,CAAC;AAYlC,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5G;AAOD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,GAC9C,MAAM,IAAI,CAiBZ;AAGD,wBAAgB,WAAW,CACzB,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GACnE,MAAM,IAAI,CAEZ;AAID,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,GAC9C,MAAM,IAAI,CAEZ;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAEnG;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EACrC,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAChC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EACvB,OAAO,EAAE,MAAM,EACf,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,GAC1B,IAAI,CAEN"}
package/dist/ipc.js CHANGED
@@ -1,13 +1,15 @@
1
- // Inter-process message reception, over the explicitly supplied host. Every operation takes its host and
2
- // reads `host.ipc.message` directly: there is no resolver, no sentinel, no installed-backend state and
3
- // no "no provider" runtime arm, because the `HasIpcMessage` witness is what guarantees the slot exists.
4
- // A caller without a provider cannot call these at all — that is a compile error, not a false answer.
1
+ // Inter-process messaging over explicitly supplied, operation-tight Host capabilities. Every operation
2
+ // reads its own slot directly: there is no aggregate backend, resolver, sentinel, installed state, or
3
+ // "no provider" runtime arm. A caller without the exact witness cannot compile the call.
5
4
  //
6
5
  // ★ THE WHOLE AMBIENT FAMILY IS GONE — getIpcBackend / setIpcBackend / installIpcHostBackend /
7
6
  // resetIpcBackendForTest / observeIpcHostResult / explainIpcBackend / explainIpcOperation /
8
7
  // hasIpcBackend / hasIpcOperation, plus the module-scoped _custom/_host/_hostConflict/_hostObservation/
9
8
  // _sentinel/_listeners registry. The sentinel in particular answered every operation, so a caller could
10
9
  // not tell an installed backend from nothing at all.
10
+ export function invokeIpc(host, channel, ...args) {
11
+ return host.ipc.invoke.invoke(channel, args);
12
+ }
11
13
  // Subscribes to messages on `channel` for the NEXT message only, then releases the subscription.
12
14
  // Returns the unsubscribe, so a caller that never receives a message can still stop listening.
13
15
  //
@@ -34,9 +36,19 @@ export function onceIpcMessage(host, channel, listener) {
34
36
  unsubscribe();
35
37
  return release;
36
38
  }
39
+ // Registers an invoke responder on `channel`. The returned release belongs to this registration.
40
+ export function onIpcInvoke(host, channel, handler) {
41
+ return host.ipc.handle.handle(channel, handler);
42
+ }
37
43
  // Subscribes to every message on `channel`. Returns the unsubscribe for THIS subscription alone —
38
44
  // releasing one listener never disturbs another on the same channel.
39
45
  export function onIpcMessage(host, channel, listener) {
40
46
  return host.ipc.message.subscribe(channel, (args) => listener(...args));
41
47
  }
48
+ export function sendIpcMessage(host, channel, ...args) {
49
+ host.ipc.send.send(channel, args);
50
+ }
51
+ export function sendIpcMessageTo(host, target, channel, ...args) {
52
+ host.ipc.targetedSend.send(target, channel, args);
53
+ }
42
54
  //# sourceMappingURL=ipc.js.map
package/dist/ipc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ipc.js","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"AAEA,yGAAyG;AACzG,uGAAuG;AACvG,wGAAwG;AACxG,sGAAsG;AACtG,EAAE;AACF,+FAA+F;AAC/F,4FAA4F;AAC5F,wGAAwG;AACxG,wGAAwG;AACxG,qDAAqD;AAErD,iGAAiG;AACjG,+FAA+F;AAC/F,EAAE;AACF,kGAAkG;AAClG,yEAAyE;AACzE,MAAM,UAAU,cAAc,CAC5B,IAAmB,EACnB,OAAe,EACf,QAA+C;IAE/C,IAAI,WAAW,GAAwB,IAAI,CAAC;IAC5C,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,IAAI;YAAE,OAAO;QACjB,IAAI,GAAG,IAAI,CAAC;QACZ,iGAAiG;QACjG,yEAAyE;QACzE,WAAW,EAAE,EAAE,CAAC;IAClB,CAAC,CAAC;IACF,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;QACzD,IAAI,IAAI;YAAE,OAAO;QACjB,OAAO,EAAE,CAAC;QACV,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,IAAI,IAAI;QAAE,WAAW,EAAE,CAAC;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,kGAAkG;AAClG,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAC1B,IAAmB,EACnB,OAAe,EACf,QAA+C;IAE/C,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC"}
1
+ {"version":3,"file":"ipc.js","sourceRoot":"","sources":["../src/ipc.ts"],"names":[],"mappings":"AAQA,uGAAuG;AACvG,sGAAsG;AACtG,yFAAyF;AACzF,EAAE;AACF,+FAA+F;AAC/F,4FAA4F;AAC5F,wGAAwG;AACxG,wGAAwG;AACxG,qDAAqD;AAErD,MAAM,UAAU,SAAS,CAAC,IAAkB,EAAE,OAAe,EAAE,GAAG,IAAwB;IACxF,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC/C,CAAC;AAED,iGAAiG;AACjG,+FAA+F;AAC/F,EAAE;AACF,kGAAkG;AAClG,yEAAyE;AACzE,MAAM,UAAU,cAAc,CAC5B,IAAmB,EACnB,OAAe,EACf,QAA+C;IAE/C,IAAI,WAAW,GAAwB,IAAI,CAAC;IAC5C,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,IAAI;YAAE,OAAO;QACjB,IAAI,GAAG,IAAI,CAAC;QACZ,iGAAiG;QACjG,yEAAyE;QACzE,WAAW,EAAE,EAAE,CAAC;IAClB,CAAC,CAAC;IACF,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;QACzD,IAAI,IAAI;YAAE,OAAO;QACjB,OAAO,EAAE,CAAC;QACV,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IACH,IAAI,IAAI;QAAE,WAAW,EAAE,CAAC;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,WAAW,CACzB,IAAkB,EAClB,OAAe,EACf,OAAoE;IAEpE,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,kGAAkG;AAClG,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAC1B,IAAmB,EACnB,OAAe,EACf,QAA+C;IAE/C,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAgB,EAAE,OAAe,EAAE,GAAG,IAAwB;IAC3F,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,IAAgC,EAChC,MAAuB,EACvB,OAAe,EACf,GAAG,IAAwB;IAE3B,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/ipc",
3
- "version": "0.5.1-next.704.19c91ec",
3
+ "version": "0.5.1-next.730.f29a5aa",
4
4
  "author": "Joshua Granick and other contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,13 +38,12 @@
38
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@flighthq/signals": "0.5.1-next.704.19c91ec",
42
- "@flighthq/types": "0.5.1-next.704.19c91ec"
41
+ "@flighthq/types": "0.5.1-next.730.f29a5aa"
43
42
  },
44
43
  "devDependencies": {
45
44
  "@flighthq/entity": "*",
46
45
  "typescript": "^5.3.0"
47
46
  },
48
- "description": "Inter-process message reception over an explicit host capability",
47
+ "description": "Inter-process messaging over explicit operation-tight host capabilities",
49
48
  "sideEffects": false
50
49
  }
package/src/ipc.test.ts CHANGED
@@ -1,7 +1,19 @@
1
1
  import { createEntity } from '@flighthq/entity/contract';
2
- import type { EntityWithoutRuntime, HasIpcMessage, IpcMessageBackend } from '@flighthq/types/contract';
2
+ import type {
3
+ EntityWithoutRuntime,
4
+ HasIpcHandle,
5
+ HasIpcInvoke,
6
+ HasIpcMessage,
7
+ HasIpcSend,
8
+ HasIpcTargetedSend,
9
+ IpcHandleBackend,
10
+ IpcInvokeBackend,
11
+ IpcMessageBackend,
12
+ IpcSendBackend,
13
+ IpcTargetedSendBackend,
14
+ } from '@flighthq/types/contract';
3
15
 
4
- import { onIpcMessage, onceIpcMessage } from './ipc';
16
+ import { invokeIpc, onIpcInvoke, onIpcMessage, onceIpcMessage, sendIpcMessage, sendIpcMessageTo } from './ipc';
5
17
 
6
18
  // A host carrying a recording message provider. Nothing installs anywhere, so two hosts can be live at
7
19
  // once — the property the ambient seam could not express.
@@ -30,6 +42,77 @@ function messageHost(): HasIpcMessage & {
30
42
  };
31
43
  }
32
44
 
45
+ interface TestIpcTarget {
46
+ readonly id: number;
47
+ }
48
+
49
+ function operationHost(): HasIpcHandle &
50
+ HasIpcInvoke &
51
+ HasIpcSend &
52
+ HasIpcTargetedSend<TestIpcTarget> & {
53
+ readonly handlers: Map<string, (...args: readonly unknown[]) => unknown | Promise<unknown>>;
54
+ readonly invocations: Array<{ readonly args: readonly unknown[]; readonly channel: string }>;
55
+ readonly sent: Array<{ readonly args: readonly unknown[]; readonly channel: string }>;
56
+ readonly sentTo: Array<{
57
+ readonly args: readonly unknown[];
58
+ readonly channel: string;
59
+ readonly target: TestIpcTarget;
60
+ }>;
61
+ } {
62
+ const handlers = new Map<string, (...args: readonly unknown[]) => unknown | Promise<unknown>>();
63
+ const invocations: Array<{ readonly args: readonly unknown[]; readonly channel: string }> = [];
64
+ const sent: Array<{ readonly args: readonly unknown[]; readonly channel: string }> = [];
65
+ const sentTo: Array<{
66
+ readonly args: readonly unknown[];
67
+ readonly channel: string;
68
+ readonly target: TestIpcTarget;
69
+ }> = [];
70
+ return {
71
+ handlers,
72
+ invocations,
73
+ ipc: {
74
+ handle: createEntity<EntityWithoutRuntime<IpcHandleBackend>>({
75
+ handle(channel, handler) {
76
+ handlers.set(channel, handler);
77
+ return () => {
78
+ if (handlers.get(channel) === handler) handlers.delete(channel);
79
+ };
80
+ },
81
+ }),
82
+ invoke: createEntity<EntityWithoutRuntime<IpcInvokeBackend>>({
83
+ invoke(channel, args) {
84
+ invocations.push({ args, channel });
85
+ return Promise.resolve({ args, channel });
86
+ },
87
+ }),
88
+ send: createEntity<EntityWithoutRuntime<IpcSendBackend>>({
89
+ send(channel, args) {
90
+ sent.push({ args, channel });
91
+ },
92
+ }),
93
+ targetedSend: createEntity<EntityWithoutRuntime<IpcTargetedSendBackend<TestIpcTarget>>>({
94
+ send(target, channel, args) {
95
+ sentTo.push({ args, channel, target });
96
+ },
97
+ }),
98
+ },
99
+ sent,
100
+ sentTo,
101
+ };
102
+ }
103
+
104
+ describe('invokeIpc', () => {
105
+ it('requires the invoke capability and returns its response', async () => {
106
+ expectTypeOf(invokeIpc).parameter(0).toEqualTypeOf<HasIpcInvoke>();
107
+ const host = operationHost();
108
+
109
+ const response = await invokeIpc(host, 'compute', 1, 2);
110
+
111
+ expect(response).toEqual({ args: [1, 2], channel: 'compute' });
112
+ expect(host.invocations).toEqual([{ args: [1, 2], channel: 'compute' }]);
113
+ });
114
+ });
115
+
33
116
  describe('onceIpcMessage', () => {
34
117
  it('delivers the first message and then releases the subscription', () => {
35
118
  const host = messageHost();
@@ -91,6 +174,19 @@ describe('onceIpcMessage', () => {
91
174
  });
92
175
  });
93
176
 
177
+ describe('onIpcInvoke', () => {
178
+ it('requires the handle capability, spreads arguments, and returns its release', async () => {
179
+ expectTypeOf(onIpcInvoke).parameter(0).toEqualTypeOf<HasIpcHandle>();
180
+ const host = operationHost();
181
+ const stop = onIpcInvoke(host, 'double', (value) => (value as number) * 2);
182
+
183
+ expect(await host.handlers.get('double')?.(4)).toBe(8);
184
+
185
+ stop();
186
+ expect(host.handlers.has('double')).toBe(false);
187
+ });
188
+ });
189
+
94
190
  describe('onIpcMessage', () => {
95
191
  it('delivers every message on its channel with the sent arguments', () => {
96
192
  const host = messageHost();
@@ -134,3 +230,29 @@ describe('onIpcMessage', () => {
134
230
  expect(seen).toEqual(['second', 'first']);
135
231
  });
136
232
  });
233
+
234
+ describe('sendIpcMessage', () => {
235
+ it('requires the send capability and forwards the arguments', () => {
236
+ expectTypeOf(sendIpcMessage).parameter(0).toEqualTypeOf<HasIpcSend>();
237
+ const host = operationHost();
238
+
239
+ sendIpcMessage(host, 'log', 'hello', 7);
240
+
241
+ expect(host.sent).toEqual([{ args: ['hello', 7], channel: 'log' }]);
242
+ });
243
+ });
244
+
245
+ describe('sendIpcMessageTo', () => {
246
+ it('requires a capability for the target type and forwards that target unchanged', () => {
247
+ expectTypeOf(sendIpcMessageTo<TestIpcTarget>)
248
+ .parameter(0)
249
+ .toEqualTypeOf<HasIpcTargetedSend<TestIpcTarget>>();
250
+ const host = operationHost();
251
+ const target = { id: 7 };
252
+
253
+ sendIpcMessageTo(host, target, 'log', 'hello');
254
+
255
+ expect(host.sentTo).toEqual([{ args: ['hello'], channel: 'log', target }]);
256
+ expect(host.sentTo[0].target).toBe(target);
257
+ });
258
+ });