@flighthq/host-electron 0.5.1-next.920.da8f530 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/contract.d.ts +19 -24
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +18 -24
- package/dist/contract.js.map +1 -1
- package/dist/electronApp.d.ts +62 -34
- package/dist/electronApp.d.ts.map +1 -1
- package/dist/electronApp.js +175 -234
- package/dist/electronApp.js.map +1 -1
- package/dist/electronClipboard.d.ts +7 -5
- package/dist/electronClipboard.d.ts.map +1 -1
- package/dist/electronClipboard.js +91 -66
- package/dist/electronClipboard.js.map +1 -1
- package/dist/electronDefaultHostGroups.d.ts +59 -0
- package/dist/electronDefaultHostGroups.d.ts.map +1 -0
- package/dist/electronDefaultHostGroups.js +109 -0
- package/dist/electronDefaultHostGroups.js.map +1 -0
- package/dist/electronDialog.d.ts +12 -9
- package/dist/electronDialog.d.ts.map +1 -1
- package/dist/electronDialog.js +28 -21
- package/dist/electronDialog.js.map +1 -1
- package/dist/electronIpc.d.ts +13 -11
- package/dist/electronIpc.d.ts.map +1 -1
- package/dist/electronIpc.js +32 -26
- package/dist/electronIpc.js.map +1 -1
- package/dist/electronMenu.d.ts +12 -6
- package/dist/electronMenu.d.ts.map +1 -1
- package/dist/electronMenu.js +41 -30
- package/dist/electronMenu.js.map +1 -1
- package/dist/electronMenuTemplate.d.ts +2 -1
- package/dist/electronMenuTemplate.d.ts.map +1 -1
- package/dist/electronMenuTemplate.js.map +1 -1
- package/dist/electronNotification.d.ts +25 -7
- package/dist/electronNotification.d.ts.map +1 -1
- package/dist/electronNotification.js +39 -16
- package/dist/electronNotification.js.map +1 -1
- package/dist/electronPlatform.d.ts +5 -3
- package/dist/electronPlatform.d.ts.map +1 -1
- package/dist/electronPlatform.js +9 -7
- package/dist/electronPlatform.js.map +1 -1
- package/dist/electronPower.d.ts +22 -11
- package/dist/electronPower.d.ts.map +1 -1
- package/dist/electronPower.js +48 -59
- package/dist/electronPower.js.map +1 -1
- package/dist/electronProtocol.d.ts +16 -8
- package/dist/electronProtocol.d.ts.map +1 -1
- package/dist/electronProtocol.js +45 -28
- package/dist/electronProtocol.js.map +1 -1
- package/dist/electronRegister.d.ts +5 -7
- package/dist/electronRegister.d.ts.map +1 -1
- package/dist/electronRegister.js +72 -99
- package/dist/electronRegister.js.map +1 -1
- package/dist/electronScreen.d.ts +7 -6
- package/dist/electronScreen.d.ts.map +1 -1
- package/dist/electronScreen.js +17 -14
- package/dist/electronScreen.js.map +1 -1
- package/dist/electronShell.d.ts +16 -8
- package/dist/electronShell.d.ts.map +1 -1
- package/dist/electronShell.js +50 -43
- package/dist/electronShell.js.map +1 -1
- package/dist/electronShortcut.d.ts +6 -4
- package/dist/electronShortcut.d.ts.map +1 -1
- package/dist/electronShortcut.js +16 -10
- package/dist/electronShortcut.js.map +1 -1
- package/dist/electronStorage.d.ts +5 -3
- package/dist/electronStorage.d.ts.map +1 -1
- package/dist/electronStorage.js +9 -7
- package/dist/electronStorage.js.map +1 -1
- package/dist/electronTray.d.ts +38 -21
- package/dist/electronTray.d.ts.map +1 -1
- package/dist/electronTray.js +110 -76
- package/dist/electronTray.js.map +1 -1
- package/dist/electronUpdater.d.ts +6 -3
- package/dist/electronUpdater.d.ts.map +1 -1
- package/dist/electronUpdater.js +10 -7
- package/dist/electronUpdater.js.map +1 -1
- package/dist/electronWindow.d.ts +23 -7
- package/dist/electronWindow.d.ts.map +1 -1
- package/dist/electronWindow.js +234 -152
- package/dist/electronWindow.js.map +1 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/types/ElectronApi.d.ts +393 -0
- package/dist/types/ElectronApi.d.ts.map +1 -0
- package/dist/types/ElectronApi.js +20 -0
- package/dist/types/ElectronApi.js.map +1 -0
- package/dist/types/ElectronAppCapabilitiesFor.d.ts +8 -0
- package/dist/types/ElectronAppCapabilitiesFor.d.ts.map +1 -0
- package/dist/types/ElectronAppCapabilitiesFor.js +2 -0
- package/dist/types/ElectronAppCapabilitiesFor.js.map +1 -0
- package/dist/types/ElectronHost.d.ts +43 -0
- package/dist/types/ElectronHost.d.ts.map +1 -0
- package/dist/types/ElectronHost.js +2 -0
- package/dist/types/ElectronHost.js.map +1 -0
- package/dist/types/ElectronHostGroups.d.ts +85 -0
- package/dist/types/ElectronHostGroups.d.ts.map +1 -0
- package/dist/types/ElectronHostGroups.js +2 -0
- package/dist/types/ElectronHostGroups.js.map +1 -0
- package/dist/types/ElectronHostOptions.d.ts +7 -0
- package/dist/types/ElectronHostOptions.d.ts.map +1 -0
- package/dist/types/ElectronHostOptions.js +2 -0
- package/dist/types/ElectronHostOptions.js.map +1 -0
- package/dist/types/ElectronProtocolCapabilities.d.ts +3 -0
- package/dist/types/ElectronProtocolCapabilities.d.ts.map +1 -0
- package/dist/types/ElectronProtocolCapabilities.js +2 -0
- package/dist/types/ElectronProtocolCapabilities.js.map +1 -0
- package/dist/types/ElectronTrayCapabilitiesFor.d.ts +7 -0
- package/dist/types/ElectronTrayCapabilitiesFor.d.ts.map +1 -0
- package/dist/types/ElectronTrayCapabilitiesFor.js +2 -0
- package/dist/types/ElectronTrayCapabilitiesFor.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +42 -21
- package/src/electronApp.test.ts +158 -131
- package/src/electronClipboard.test.ts +40 -13
- package/src/electronDefaultHostGroups.test.ts +148 -0
- package/src/electronDialog.test.ts +55 -53
- package/src/electronHostTreeShaking.test.ts +51 -0
- package/src/electronIpc.test.ts +47 -66
- package/src/electronMenu.test.ts +61 -47
- package/src/electronMenuTemplate.test.ts +1 -1
- package/src/electronNotification.test.ts +71 -21
- package/src/electronPlatform.test.ts +17 -12
- package/src/electronPower.test.ts +112 -88
- package/src/electronProtocol.test.ts +68 -35
- package/src/electronRegister.test.ts +280 -26
- package/src/electronScreen.test.ts +34 -25
- package/src/electronShell.test.ts +99 -59
- package/src/electronShortcut.test.ts +22 -19
- package/src/electronStorage.test.ts +26 -24
- package/src/electronTray.test.ts +225 -109
- package/src/electronUpdater.test.ts +26 -19
- package/src/electronWindow.test.ts +229 -101
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { ElectronApi } from '@flighthq/types/contract';
|
|
2
|
-
import { EntityRuntimeKey } from '@flighthq/types/contract';
|
|
3
|
-
|
|
4
1
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
electronHostShortcut,
|
|
3
|
+
electronHostShortcutQuery,
|
|
4
|
+
electronHostShortcutTrigger,
|
|
5
|
+
populateElectronHostShortcutQuery,
|
|
6
|
+
} from './electronShortcut.ts';
|
|
7
|
+
import type { ElectronApi } from './types/index.ts';
|
|
9
8
|
|
|
10
9
|
function fakeElectron() {
|
|
11
10
|
const callbacks = new Map<string, () => void>();
|
|
@@ -30,27 +29,31 @@ function fakeElectron() {
|
|
|
30
29
|
return { callbacks, electron, unregisterCalls, unregisterFailures };
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
describe('
|
|
32
|
+
describe('electronHostShortcut', () => {
|
|
33
|
+
it('constructs the exact Entity-backed shortcut group', () => {
|
|
34
|
+
const shortcut = electronHostShortcut(fakeElectron().electron);
|
|
35
|
+
expect(Object.keys(shortcut).sort()).toEqual(['query', 'trigger']);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('electronHostShortcutQuery', () => {
|
|
34
40
|
it('returns an Entity and lifts the native query into the awaited contract', async () => {
|
|
35
41
|
const fake = fakeElectron();
|
|
36
42
|
fake.callbacks.set('Control+K', () => {});
|
|
37
|
-
const provider =
|
|
38
|
-
expect(EntityRuntimeKey in provider).toBe(true);
|
|
43
|
+
const provider = electronHostShortcutQuery(fake.electron);
|
|
39
44
|
await expect(provider.isRegistered('Control+K')).resolves.toBe(true);
|
|
40
45
|
await expect(provider.isRegistered('Control+J')).resolves.toBe(false);
|
|
41
46
|
});
|
|
42
47
|
});
|
|
43
48
|
|
|
44
|
-
describe('
|
|
49
|
+
describe('electronHostShortcutTrigger', () => {
|
|
45
50
|
it('returns an Entity, subscribes by exact token, and delivers native triggers', async () => {
|
|
46
51
|
const fake = fakeElectron();
|
|
47
|
-
const provider =
|
|
52
|
+
const provider = electronHostShortcutTrigger(fake.electron);
|
|
48
53
|
const trigger = vi.fn();
|
|
49
|
-
expect(EntityRuntimeKey in provider).toBe(true);
|
|
50
54
|
const outcome = await provider.subscribe('Control+K', trigger);
|
|
51
55
|
expect(outcome.reason).toBe('subscribed');
|
|
52
56
|
if (outcome.reason !== 'subscribed') return;
|
|
53
|
-
expect(EntityRuntimeKey in outcome.subscription).toBe(true);
|
|
54
57
|
fake.callbacks.get('Control+K')?.();
|
|
55
58
|
expect(trigger).toHaveBeenCalledTimes(1);
|
|
56
59
|
await expect(provider.unsubscribe(outcome.subscription)).resolves.toEqual({ reason: 'unsubscribed' });
|
|
@@ -61,13 +64,13 @@ describe('createElectronShortcutTriggerBackend', () => {
|
|
|
61
64
|
it('reports native collision/refusal without minting a token', async () => {
|
|
62
65
|
const fake = fakeElectron();
|
|
63
66
|
fake.callbacks.set('Control+K', () => {});
|
|
64
|
-
const provider =
|
|
67
|
+
const provider = electronHostShortcutTrigger(fake.electron);
|
|
65
68
|
await expect(provider.subscribe('Control+K', () => {})).resolves.toEqual({ reason: 'refused' });
|
|
66
69
|
});
|
|
67
70
|
|
|
68
71
|
it('destroy attempts every distinct obligation and retries only failed releases', async () => {
|
|
69
72
|
const fake = fakeElectron();
|
|
70
|
-
const provider =
|
|
73
|
+
const provider = electronHostShortcutTrigger(fake.electron);
|
|
71
74
|
await provider.subscribe('Control+A', () => {});
|
|
72
75
|
await provider.subscribe('Control+B', () => {});
|
|
73
76
|
fake.unregisterFailures.add('Control+A');
|
|
@@ -81,8 +84,8 @@ describe('createElectronShortcutTriggerBackend', () => {
|
|
|
81
84
|
expect(fake.unregisterCalls).toEqual(['Control+A', 'Control+B', 'Control+A']);
|
|
82
85
|
});
|
|
83
86
|
});
|
|
84
|
-
describe('
|
|
85
|
-
it('is the construction initializer of
|
|
86
|
-
expect(typeof
|
|
87
|
+
describe('populateElectronHostShortcutQuery', () => {
|
|
88
|
+
it('is the construction initializer of electronHostShortcutQuery', () => {
|
|
89
|
+
expect(typeof populateElectronHostShortcutQuery).toBe('function');
|
|
87
90
|
});
|
|
88
91
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { createElectronStorageBackend, initializeElectronStorageBackend } from './electronStorage';
|
|
1
|
+
import { electronHostStorage, electronHostStorageGroup, populateElectronHostStorage } from './electronStorage.ts';
|
|
2
|
+
import type { ElectronApi } from './types/index.ts';
|
|
5
3
|
|
|
6
4
|
const STORAGE_PATH = '/userData/storage.json';
|
|
7
5
|
|
|
@@ -70,13 +68,9 @@ function json(value: Readonly<Record<string, string>>): string {
|
|
|
70
68
|
return JSON.stringify(value);
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
describe('
|
|
74
|
-
it('returns an Entity', () => {
|
|
75
|
-
expect(EntityRuntimeKey in createElectronStorageBackend(fakeElectron().electron)).toBe(true);
|
|
76
|
-
});
|
|
77
|
-
|
|
71
|
+
describe('electronHostStorage', () => {
|
|
78
72
|
it('treats a missing file as successful empty storage', () => {
|
|
79
|
-
const backend =
|
|
73
|
+
const backend = electronHostStorage(fakeElectron().electron);
|
|
80
74
|
expect(backend.getItem('missing')).toEqual({ reason: 'ok', value: null });
|
|
81
75
|
expect(backend.keys()).toEqual({ reason: 'ok', value: [] });
|
|
82
76
|
});
|
|
@@ -84,7 +78,7 @@ describe('createElectronStorageBackend', () => {
|
|
|
84
78
|
it('reports corrupt and non-string persistence without silently resetting it', () => {
|
|
85
79
|
for (const raw of ['{', '[]', '{"key":1}']) {
|
|
86
80
|
const state = fakeElectron(raw);
|
|
87
|
-
const backend =
|
|
81
|
+
const backend = electronHostStorage(state.electron);
|
|
88
82
|
expect(backend.getItem('key')).toEqual({ reason: 'persistence-invalid', value: null });
|
|
89
83
|
expect(backend.keys()).toEqual({ reason: 'persistence-invalid', value: null });
|
|
90
84
|
expect(backend.setItem('key', 'value')).toEqual({ reason: 'persistence-invalid' });
|
|
@@ -96,7 +90,7 @@ describe('createElectronStorageBackend', () => {
|
|
|
96
90
|
|
|
97
91
|
it('clear deliberately recovers corrupt persistence through atomic replacement', () => {
|
|
98
92
|
const state = fakeElectron('{');
|
|
99
|
-
const backend =
|
|
93
|
+
const backend = electronHostStorage(state.electron);
|
|
100
94
|
expect(backend.clear()).toEqual({ reason: 'ok' });
|
|
101
95
|
expect(state.files.get(STORAGE_PATH)).toBe('{}');
|
|
102
96
|
expect(backend.keys()).toEqual({ reason: 'ok', value: [] });
|
|
@@ -104,7 +98,7 @@ describe('createElectronStorageBackend', () => {
|
|
|
104
98
|
|
|
105
99
|
it('persists a candidate through same-directory rename before committing cache', () => {
|
|
106
100
|
const state = fakeElectron(json({ a: 'old' }));
|
|
107
|
-
const backend =
|
|
101
|
+
const backend = electronHostStorage(state.electron);
|
|
108
102
|
expect(backend.setItem('a', 'new')).toEqual({ reason: 'ok' });
|
|
109
103
|
expect(state.written).toHaveLength(1);
|
|
110
104
|
expect(state.written[0]!.path.startsWith(`${STORAGE_PATH}.tmp-`)).toBe(true);
|
|
@@ -115,7 +109,7 @@ describe('createElectronStorageBackend', () => {
|
|
|
115
109
|
|
|
116
110
|
it('never exposes a false cache commit or replaced target when rename fails', () => {
|
|
117
111
|
const state = fakeElectron(json({ a: 'old' }));
|
|
118
|
-
const backend =
|
|
112
|
+
const backend = electronHostStorage(state.electron);
|
|
119
113
|
expect(backend.getItem('a')).toEqual({ reason: 'ok', value: 'old' });
|
|
120
114
|
state.renameFailure = codeError('EIO');
|
|
121
115
|
expect(backend.setItem('a', 'candidate')).toEqual({ reason: 'write-failed' });
|
|
@@ -127,7 +121,7 @@ describe('createElectronStorageBackend', () => {
|
|
|
127
121
|
|
|
128
122
|
it('keeps a partial temporary write unobservable and cleans it after failure', () => {
|
|
129
123
|
const state = fakeElectron(json({ a: 'old' }));
|
|
130
|
-
const backend =
|
|
124
|
+
const backend = electronHostStorage(state.electron);
|
|
131
125
|
expect(backend.getItem('a')).toEqual({ reason: 'ok', value: 'old' });
|
|
132
126
|
state.writeFailure = codeError('EIO');
|
|
133
127
|
state.writePartialBeforeFailure = true;
|
|
@@ -140,29 +134,29 @@ describe('createElectronStorageBackend', () => {
|
|
|
140
134
|
it('classifies only reliable filesystem codes and otherwise uses the method fallback', () => {
|
|
141
135
|
const denied = fakeElectron(json({ a: '1' }));
|
|
142
136
|
denied.readFailure = codeError('EACCES');
|
|
143
|
-
expect(
|
|
137
|
+
expect(electronHostStorage(denied.electron).getItem('a')).toEqual({
|
|
144
138
|
reason: 'security-denied',
|
|
145
139
|
value: null,
|
|
146
140
|
});
|
|
147
141
|
|
|
148
142
|
const quota = fakeElectron(json({ a: '1' }));
|
|
149
|
-
const quotaBackend =
|
|
143
|
+
const quotaBackend = electronHostStorage(quota.electron);
|
|
150
144
|
quota.writeFailure = codeError('ENOSPC');
|
|
151
145
|
expect(quotaBackend.setItem('a', '2')).toEqual({ reason: 'quota-exceeded' });
|
|
152
146
|
|
|
153
147
|
const remove = fakeElectron(json({ a: '1' }));
|
|
154
|
-
const removeBackend =
|
|
148
|
+
const removeBackend = electronHostStorage(remove.electron);
|
|
155
149
|
remove.renameFailure = codeError('EIO');
|
|
156
150
|
expect(removeBackend.removeItem('a')).toEqual({ reason: 'remove-failed' });
|
|
157
151
|
|
|
158
152
|
const clear = fakeElectron(json({ a: '1' }));
|
|
159
153
|
clear.renameFailure = codeError('EIO');
|
|
160
|
-
expect(
|
|
154
|
+
expect(electronHostStorage(clear.electron).clear()).toEqual({ reason: 'clear-failed' });
|
|
161
155
|
});
|
|
162
156
|
|
|
163
157
|
it('treats absent remove as idempotent success without writing', () => {
|
|
164
158
|
const state = fakeElectron(json({}));
|
|
165
|
-
const backend =
|
|
159
|
+
const backend = electronHostStorage(state.electron);
|
|
166
160
|
expect(backend.removeItem('missing')).toEqual({ reason: 'ok' });
|
|
167
161
|
expect(state.written).toEqual([]);
|
|
168
162
|
expect(state.renamed).toEqual([]);
|
|
@@ -173,14 +167,22 @@ describe('createElectronStorageBackend', () => {
|
|
|
173
167
|
// power-loss durability claim.
|
|
174
168
|
it('defines ok as atomic visibility rather than power-loss durability', () => {
|
|
175
169
|
const state = fakeElectron(json({ a: 'old' }));
|
|
176
|
-
const backend =
|
|
170
|
+
const backend = electronHostStorage(state.electron);
|
|
177
171
|
expect(backend.setItem('a', 'visible')).toEqual({ reason: 'ok' });
|
|
178
172
|
expect(state.renamed).toHaveLength(1);
|
|
179
173
|
expect(backend.getItem('a')).toEqual({ reason: 'ok', value: 'visible' });
|
|
180
174
|
});
|
|
181
175
|
});
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
176
|
+
|
|
177
|
+
describe('electronHostStorageGroup', () => {
|
|
178
|
+
it('constructs the local storage slot', () => {
|
|
179
|
+
const storage = electronHostStorageGroup(fakeElectron().electron);
|
|
180
|
+
expect(Object.keys(storage)).toEqual(['local']);
|
|
181
|
+
expect(storage.local.getItem).toBeTypeOf('function');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
describe('populateElectronHostStorage', () => {
|
|
185
|
+
it('is the construction initializer of electronHostStorage', () => {
|
|
186
|
+
expect(typeof populateElectronHostStorage).toBe('function');
|
|
185
187
|
});
|
|
186
188
|
});
|