@flighthq/ipc 0.4.0-next.1903.50bfa67 → 0.4.0-next.1908.751021c

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 (2) hide show
  1. package/package.json +3 -3
  2. package/src/ipc.test.ts +81 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/ipc",
3
- "version": "0.4.0-next.1903.50bfa67",
3
+ "version": "0.4.0-next.1908.751021c",
4
4
  "author": "Joshua Granick and other contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,8 +38,8 @@
38
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@flighthq/signals": "0.4.0-next.1903.50bfa67",
42
- "@flighthq/types": "0.4.0-next.1903.50bfa67"
41
+ "@flighthq/signals": "0.4.0-next.1908.751021c",
42
+ "@flighthq/types": "0.4.0-next.1908.751021c"
43
43
  },
44
44
  "devDependencies": {
45
45
  "typescript": "^5.3.0"
package/src/ipc.test.ts CHANGED
@@ -18,6 +18,10 @@ import {
18
18
  sendIpcMessage,
19
19
  sendIpcMessageTo,
20
20
  setIpcBackend,
21
+ explainIpcBackend,
22
+ installIpcHostBackend,
23
+ observeIpcHostResult,
24
+ resetIpcBackendForTest,
21
25
  } from './ipc';
22
26
 
23
27
  interface FakeIpcBackend extends IpcBackend {
@@ -156,6 +160,34 @@ describe('enableIpcSignals', () => {
156
160
  });
157
161
  });
158
162
 
163
+ describe('explainIpcBackend', () => {
164
+ afterEach(() => resetIpcBackendForTest());
165
+
166
+ it('reports host-not-enabled when no backend is installed', () => {
167
+ resetIpcBackendForTest();
168
+ const explanation = explainIpcBackend();
169
+ expect(explanation.layer).toBe('host-not-enabled');
170
+ expect(explanation.conflict).toBe(false);
171
+ expect(explanation.viability).toBe('unobserved');
172
+ });
173
+
174
+ it('reports custom layer when a custom backend is set', () => {
175
+ setIpcBackend(fakeBackend());
176
+ expect(explainIpcBackend().layer).toBe('custom');
177
+ });
178
+
179
+ it('reports host layer when a host backend is installed', () => {
180
+ installIpcHostBackend(fakeBackend());
181
+ expect(explainIpcBackend().layer).toBe('host');
182
+ });
183
+
184
+ it('reports conflict when two different host backends are installed', () => {
185
+ installIpcHostBackend(fakeBackend());
186
+ installIpcHostBackend(fakeBackend());
187
+ expect(explainIpcBackend().conflict).toBe(true);
188
+ });
189
+ });
190
+
159
191
  describe('getIpcBackend', () => {
160
192
  it('falls back to a web backend', () => {
161
193
  expect(getIpcBackend()).not.toBeNull();
@@ -259,6 +291,25 @@ describe('hasIpcBackend', () => {
259
291
  });
260
292
  });
261
293
 
294
+ describe('installIpcHostBackend', () => {
295
+ afterEach(() => resetIpcBackendForTest());
296
+
297
+ it('installs a host backend that getIpcBackend returns', () => {
298
+ const backend = fakeBackend();
299
+ installIpcHostBackend(backend);
300
+ expect(getIpcBackend()).toBe(backend);
301
+ });
302
+
303
+ it('is first-host-wins: a second different backend sets conflict', () => {
304
+ const first = fakeBackend();
305
+ const second = fakeBackend();
306
+ installIpcHostBackend(first);
307
+ installIpcHostBackend(second);
308
+ expect(getIpcBackend()).toBe(first);
309
+ expect(explainIpcBackend().conflict).toBe(true);
310
+ });
311
+ });
312
+
262
313
  describe('invokeIpc', () => {
263
314
  it('passes variadic args as an array and resolves the backend result', async () => {
264
315
  const backend = fakeBackend();
@@ -306,6 +357,24 @@ describe('invokeIpcWithTimeout', () => {
306
357
  });
307
358
  });
308
359
 
360
+ describe('observeIpcHostResult', () => {
361
+ afterEach(() => resetIpcBackendForTest());
362
+
363
+ it('records a successful observation', () => {
364
+ installIpcHostBackend(fakeBackend());
365
+ observeIpcHostResult('send', true);
366
+ const explanation = explainIpcBackend();
367
+ expect(explanation.operation).toBe('send');
368
+ expect(explanation.viability).toBe('available');
369
+ });
370
+
371
+ it('records a failed observation', () => {
372
+ installIpcHostBackend(fakeBackend());
373
+ observeIpcHostResult('send', false);
374
+ expect(explainIpcBackend().viability).toBe('runtime-api-unavailable');
375
+ });
376
+ });
377
+
309
378
  describe('onceIpcMessage', () => {
310
379
  it('auto-unsubscribes after the first message', () => {
311
380
  const backend = fakeBackend();
@@ -460,6 +529,18 @@ describe('removeAllIpcListeners', () => {
460
529
  });
461
530
  });
462
531
 
532
+ describe('resetIpcBackendForTest', () => {
533
+ it('clears all backend slots', () => {
534
+ setIpcBackend(fakeBackend());
535
+ installIpcHostBackend(fakeBackend());
536
+ observeIpcHostResult('send', true);
537
+ resetIpcBackendForTest();
538
+ expect(explainIpcBackend().layer).toBe('host-not-enabled');
539
+ expect(explainIpcBackend().conflict).toBe(false);
540
+ expect(explainIpcBackend().viability).toBe('unobserved');
541
+ });
542
+ });
543
+
463
544
  describe('sendIpcMessage', () => {
464
545
  it('forwards channel and args array to the backend', () => {
465
546
  const backend = fakeBackend();