@flighthq/shortcut 0.5.1-next.1069.554a2ac → 0.5.1-next.1201.9b49dee
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/shortcutExplicitDependency.d.ts +7 -7
- package/dist/shortcutExplicitDependency.d.ts.map +1 -1
- package/dist/shortcutExplicitDependency.js +14 -14
- package/dist/shortcutExplicitDependency.js.map +1 -1
- package/package.json +4 -4
- package/src/shortcutExplicitDependency.test.ts +39 -41
package/README.md
CHANGED
|
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/shortcut`. The `@fli
|
|
|
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/shortcut@0.5.1-next.
|
|
17
|
-
- [License](https://github.com/flighthq/flight/blob/
|
|
16
|
+
- [Source for @flighthq/shortcut@0.5.1-next.1201.9b49dee](https://github.com/flighthq/flight/tree/9b49dee3f22f6b2838c3d237edcc77bca65734f2/packages/shortcut)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/9b49dee3f22f6b2838c3d237edcc77bca65734f2/LICENSE.md)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Accelerator, CreateGlobalShortcutOutcome, EntityConstruction, GlobalShortcut, GlobalShortcutAttachOutcome, GlobalShortcutDetachOutcome, GlobalShortcutQueryOutcome,
|
|
2
|
-
export declare function attachGlobalShortcut(
|
|
1
|
+
import type { Accelerator, CreateGlobalShortcutOutcome, EntityConstruction, GlobalShortcut, GlobalShortcutAttachOutcome, GlobalShortcutDetachOutcome, GlobalShortcutQueryOutcome, HostShortcutQueryProvider, HostShortcutTriggerProvider, NonEntityCreateResult } from '@flighthq/types/contract';
|
|
2
|
+
export declare function attachGlobalShortcut(hostShortcutTrigger: Readonly<HostShortcutTriggerProvider>, shortcut: GlobalShortcut): Promise<GlobalShortcutAttachOutcome>;
|
|
3
3
|
export declare function createGlobalShortcut(accelerator: string): NonEntityCreateResult<CreateGlobalShortcutOutcome, 'descriptor'>;
|
|
4
|
-
export declare function destroyShortcutTrigger(
|
|
5
|
-
export declare function detachGlobalShortcut(
|
|
6
|
-
export declare function disposeGlobalShortcut(
|
|
4
|
+
export declare function destroyShortcutTrigger(hostShortcutTrigger: Readonly<HostShortcutTriggerProvider>): Promise<void>;
|
|
5
|
+
export declare function detachGlobalShortcut(hostShortcutTrigger: Readonly<HostShortcutTriggerProvider>, shortcut: GlobalShortcut): Promise<GlobalShortcutDetachOutcome>;
|
|
6
|
+
export declare function disposeGlobalShortcut(hostShortcutTrigger: Readonly<HostShortcutTriggerProvider>, shortcut: GlobalShortcut): Promise<GlobalShortcutDetachOutcome>;
|
|
7
7
|
export declare function initializeGlobalShortcut(out: EntityConstruction<GlobalShortcut>, accelerator: Accelerator): void;
|
|
8
|
-
export declare function queryGlobalShortcutConflict(
|
|
9
|
-
export declare function queryGlobalShortcutRegistration(
|
|
8
|
+
export declare function queryGlobalShortcutConflict(hostShortcutQuery: Readonly<HostShortcutQueryProvider>, accelerator: string): Promise<GlobalShortcutQueryOutcome>;
|
|
9
|
+
export declare function queryGlobalShortcutRegistration(hostShortcutQuery: Readonly<HostShortcutQueryProvider>, accelerator: string): Promise<GlobalShortcutQueryOutcome>;
|
|
10
10
|
//# sourceMappingURL=shortcutExplicitDependency.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortcutExplicitDependency.d.ts","sourceRoot":"","sources":["../src/shortcutExplicitDependency.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,2BAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,
|
|
1
|
+
{"version":3,"file":"shortcutExplicitDependency.d.ts","sourceRoot":"","sources":["../src/shortcutExplicitDependency.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,WAAW,EACX,2BAA2B,EAC3B,kBAAkB,EAClB,cAAc,EACd,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,2BAA2B,EAC3B,qBAAqB,EAGtB,MAAM,0BAA0B,CAAC;AA4BlC,wBAAsB,oBAAoB,CACxC,mBAAmB,EAAE,QAAQ,CAAC,2BAA2B,CAAC,EAC1D,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,2BAA2B,CAAC,CA6BtC;AAKD,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,GAClB,qBAAqB,CAAC,2BAA2B,EAAE,YAAY,CAAC,CAYlE;AAED,wBAAgB,sBAAsB,CAAC,mBAAmB,EAAE,QAAQ,CAAC,2BAA2B,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhH;AAID,wBAAsB,oBAAoB,CACxC,mBAAmB,EAAE,QAAQ,CAAC,2BAA2B,CAAC,EAC1D,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,2BAA2B,CAAC,CAgBtC;AAID,wBAAsB,qBAAqB,CACzC,mBAAmB,EAAE,QAAQ,CAAC,2BAA2B,CAAC,EAC1D,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,2BAA2B,CAAC,CAMtC;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,WAAW,GAAG,IAAI,CAGhH;AAED,wBAAsB,2BAA2B,CAC/C,iBAAiB,EAAE,QAAQ,CAAC,yBAAyB,CAAC,EACtD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,0BAA0B,CAAC,CAErC;AAED,wBAAsB,+BAA+B,CACnD,iBAAiB,EAAE,QAAQ,CAAC,yBAAyB,CAAC,EACtD,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,0BAA0B,CAAC,CASrC"}
|
|
@@ -18,14 +18,14 @@ const TRIGGER_DETACH_FAILED = Object.freeze({ reason: 'trigger-provider-failed'
|
|
|
18
18
|
const _attachments = new WeakMap();
|
|
19
19
|
const _attachedByAccelerator = new Map();
|
|
20
20
|
const _pendingAccelerators = new Set();
|
|
21
|
-
export async function attachGlobalShortcut(
|
|
21
|
+
export async function attachGlobalShortcut(hostShortcutTrigger, shortcut) {
|
|
22
22
|
if (_attachments.has(shortcut))
|
|
23
23
|
return ALREADY_ATTACHED;
|
|
24
24
|
if (_attachedByAccelerator.has(shortcut.accelerator))
|
|
25
25
|
return ALREADY_REGISTERED;
|
|
26
26
|
if (_pendingAccelerators.has(shortcut.accelerator))
|
|
27
27
|
return REGISTRATION_IN_PROGRESS;
|
|
28
|
-
const provider =
|
|
28
|
+
const provider = hostShortcutTrigger;
|
|
29
29
|
_pendingAccelerators.add(shortcut.accelerator);
|
|
30
30
|
try {
|
|
31
31
|
const outcome = await provider.subscribe(shortcut.accelerator, () => emitSignal(shortcut.onTrigger));
|
|
@@ -71,16 +71,16 @@ export function createGlobalShortcut(accelerator) {
|
|
|
71
71
|
})(),
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
-
export function destroyShortcutTrigger(
|
|
75
|
-
return
|
|
74
|
+
export function destroyShortcutTrigger(hostShortcutTrigger) {
|
|
75
|
+
return hostShortcutTrigger.destroy();
|
|
76
76
|
}
|
|
77
|
-
// The
|
|
78
|
-
//
|
|
79
|
-
export async function detachGlobalShortcut(
|
|
77
|
+
// The provider argument keeps the exact dependency visible, while the stored origin prevents a replacement
|
|
78
|
+
// provider from redirecting a release. Failed releases remain attached and can be retried exactly.
|
|
79
|
+
export async function detachGlobalShortcut(hostShortcutTrigger, shortcut) {
|
|
80
80
|
const attachment = _attachments.get(shortcut);
|
|
81
81
|
if (attachment === undefined)
|
|
82
82
|
return NOT_ATTACHED;
|
|
83
|
-
const selected =
|
|
83
|
+
const selected = hostShortcutTrigger;
|
|
84
84
|
const provider = selected === attachment.provider ? selected : attachment.provider;
|
|
85
85
|
try {
|
|
86
86
|
const outcome = await provider.unsubscribe(attachment.subscription);
|
|
@@ -98,9 +98,9 @@ export async function detachGlobalShortcut(host, shortcut) {
|
|
|
98
98
|
}
|
|
99
99
|
// Disposal always clears consumer listeners, including when native teardown fails. A failed native
|
|
100
100
|
// release remains attached so detachGlobalShortcut can retry it later.
|
|
101
|
-
export async function disposeGlobalShortcut(
|
|
101
|
+
export async function disposeGlobalShortcut(hostShortcutTrigger, shortcut) {
|
|
102
102
|
try {
|
|
103
|
-
return await detachGlobalShortcut(
|
|
103
|
+
return await detachGlobalShortcut(hostShortcutTrigger, shortcut);
|
|
104
104
|
}
|
|
105
105
|
finally {
|
|
106
106
|
clearSignal(shortcut.onTrigger);
|
|
@@ -110,16 +110,16 @@ export function initializeGlobalShortcut(out, accelerator) {
|
|
|
110
110
|
out.accelerator = accelerator;
|
|
111
111
|
out.onTrigger = createSignal();
|
|
112
112
|
}
|
|
113
|
-
export async function queryGlobalShortcutConflict(
|
|
114
|
-
return queryGlobalShortcutRegistration(
|
|
113
|
+
export async function queryGlobalShortcutConflict(hostShortcutQuery, accelerator) {
|
|
114
|
+
return queryGlobalShortcutRegistration(hostShortcutQuery, accelerator);
|
|
115
115
|
}
|
|
116
|
-
export async function queryGlobalShortcutRegistration(
|
|
116
|
+
export async function queryGlobalShortcutRegistration(hostShortcutQuery, accelerator) {
|
|
117
117
|
const parsed = makeParsedAccelerator();
|
|
118
118
|
const outcome = parseAcceleratorDetailed(accelerator, parsed);
|
|
119
119
|
if ('reason' in outcome)
|
|
120
120
|
return { parseError: outcome, reason: 'unparseable' };
|
|
121
121
|
try {
|
|
122
|
-
return (await
|
|
122
|
+
return (await hostShortcutQuery.isRegistered(formatParsedAccelerator(outcome))) ? REGISTERED : NOT_REGISTERED;
|
|
123
123
|
}
|
|
124
124
|
catch {
|
|
125
125
|
return QUERY_PROVIDER_FAILED;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shortcutExplicitDependency.js","sourceRoot":"","sources":["../src/shortcutExplicitDependency.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"shortcutExplicitDependency.js","sourceRoot":"","sources":["../src/shortcutExplicitDependency.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/shortcut",
|
|
3
|
-
"version": "0.5.1-next.
|
|
3
|
+
"version": "0.5.1-next.1201.9b49dee",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/entity": "0.5.1-next.
|
|
42
|
-
"@flighthq/signals": "0.5.1-next.
|
|
43
|
-
"@flighthq/types": "0.5.1-next.
|
|
41
|
+
"@flighthq/entity": "0.5.1-next.1201.9b49dee",
|
|
42
|
+
"@flighthq/signals": "0.5.1-next.1201.9b49dee",
|
|
43
|
+
"@flighthq/types": "0.5.1-next.1201.9b49dee"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"typescript": "^5.3.0"
|
|
@@ -31,7 +31,7 @@ interface QueryProviderLike extends Entity {
|
|
|
31
31
|
|
|
32
32
|
interface ShortcutApi {
|
|
33
33
|
attachGlobalShortcut(
|
|
34
|
-
|
|
34
|
+
hostShortcutTrigger: TriggerProviderLike,
|
|
35
35
|
shortcut: GlobalShortcutLike,
|
|
36
36
|
): Promise<Readonly<{ reason: string }>>;
|
|
37
37
|
createGlobalShortcut(
|
|
@@ -39,21 +39,21 @@ interface ShortcutApi {
|
|
|
39
39
|
):
|
|
40
40
|
| Readonly<{ parseError: AcceleratorParseError; reason: 'unparseable' }>
|
|
41
41
|
| Readonly<{ reason: 'created'; shortcut: GlobalShortcutLike }>;
|
|
42
|
-
destroyShortcutTrigger(
|
|
42
|
+
destroyShortcutTrigger(hostShortcutTrigger: TriggerProviderLike): Promise<void>;
|
|
43
43
|
detachGlobalShortcut(
|
|
44
|
-
|
|
44
|
+
hostShortcutTrigger: TriggerProviderLike,
|
|
45
45
|
shortcut: GlobalShortcutLike,
|
|
46
46
|
): Promise<Readonly<{ reason: string }>>;
|
|
47
47
|
disposeGlobalShortcut(
|
|
48
|
-
|
|
48
|
+
hostShortcutTrigger: TriggerProviderLike,
|
|
49
49
|
shortcut: GlobalShortcutLike,
|
|
50
50
|
): Promise<Readonly<{ reason: string }>>;
|
|
51
51
|
queryGlobalShortcutConflict(
|
|
52
|
-
|
|
52
|
+
hostShortcutQuery: QueryProviderLike,
|
|
53
53
|
accelerator: string,
|
|
54
54
|
): Promise<Readonly<{ reason: string }>>;
|
|
55
55
|
queryGlobalShortcutRegistration(
|
|
56
|
-
|
|
56
|
+
hostShortcutQuery: QueryProviderLike,
|
|
57
57
|
accelerator: string,
|
|
58
58
|
): Promise<Readonly<{ parseError?: AcceleratorParseError; reason: string }>>;
|
|
59
59
|
}
|
|
@@ -97,18 +97,10 @@ function triggerProvider(
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
function triggerHost(provider: TriggerProviderLike) {
|
|
101
|
-
return { shortcut: { trigger: provider } };
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function queryHost(provider: QueryProviderLike) {
|
|
105
|
-
return { shortcut: { query: provider } };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
100
|
describe('attachGlobalShortcut', () => {
|
|
109
101
|
it('maps a native refusal to a method-tight outcome', async () => {
|
|
110
102
|
const provider = triggerProvider({ subscribe: async () => ({ reason: 'refused' }) });
|
|
111
|
-
await expect(api().attachGlobalShortcut(
|
|
103
|
+
await expect(api().attachGlobalShortcut(provider, createShortcut('Control+K'))).resolves.toEqual({
|
|
112
104
|
reason: 'native-refused',
|
|
113
105
|
});
|
|
114
106
|
});
|
|
@@ -119,7 +111,7 @@ describe('attachGlobalShortcut', () => {
|
|
|
119
111
|
throw new Error('provider failed');
|
|
120
112
|
},
|
|
121
113
|
});
|
|
122
|
-
await expect(api().attachGlobalShortcut(
|
|
114
|
+
await expect(api().attachGlobalShortcut(provider, createShortcut('Control+J'))).resolves.toEqual({
|
|
123
115
|
reason: 'trigger-provider-failed',
|
|
124
116
|
});
|
|
125
117
|
});
|
|
@@ -127,10 +119,10 @@ describe('attachGlobalShortcut', () => {
|
|
|
127
119
|
it('reports an in-progress same-chord acquisition without invoking the provider twice', async () => {
|
|
128
120
|
const pending = deferred<Readonly<{ reason: 'subscribed'; subscription: ShortcutSubscriptionLike }>>();
|
|
129
121
|
const subscribe = vi.fn(() => pending.promise);
|
|
130
|
-
const
|
|
131
|
-
const first = api().attachGlobalShortcut(
|
|
122
|
+
const hostShortcutTrigger = triggerProvider({ subscribe });
|
|
123
|
+
const first = api().attachGlobalShortcut(hostShortcutTrigger, createShortcut('Control+P'));
|
|
132
124
|
|
|
133
|
-
await expect(api().attachGlobalShortcut(
|
|
125
|
+
await expect(api().attachGlobalShortcut(hostShortcutTrigger, createShortcut('ctrl+p'))).resolves.toEqual({
|
|
134
126
|
reason: 'registration-in-progress',
|
|
135
127
|
});
|
|
136
128
|
expect(subscribe).toHaveBeenCalledTimes(1);
|
|
@@ -139,11 +131,11 @@ describe('attachGlobalShortcut', () => {
|
|
|
139
131
|
});
|
|
140
132
|
|
|
141
133
|
it('does not overwrite the first live same-chord registration', async () => {
|
|
142
|
-
const
|
|
143
|
-
await expect(api().attachGlobalShortcut(
|
|
134
|
+
const hostShortcutTrigger = triggerProvider();
|
|
135
|
+
await expect(api().attachGlobalShortcut(hostShortcutTrigger, createShortcut('Control+B'))).resolves.toEqual({
|
|
144
136
|
reason: 'attached',
|
|
145
137
|
});
|
|
146
|
-
await expect(api().attachGlobalShortcut(
|
|
138
|
+
await expect(api().attachGlobalShortcut(hostShortcutTrigger, createShortcut('ctrl+b'))).resolves.toEqual({
|
|
147
139
|
reason: 'already-registered',
|
|
148
140
|
});
|
|
149
141
|
});
|
|
@@ -170,7 +162,7 @@ describe('createGlobalShortcut', () => {
|
|
|
170
162
|
describe('destroyShortcutTrigger', () => {
|
|
171
163
|
it('awaits the exact trigger provider destroy boundary', async () => {
|
|
172
164
|
const destroy = vi.fn(async () => {});
|
|
173
|
-
await api().destroyShortcutTrigger(
|
|
165
|
+
await api().destroyShortcutTrigger(triggerProvider({ destroy }));
|
|
174
166
|
expect(destroy).toHaveBeenCalledTimes(1);
|
|
175
167
|
});
|
|
176
168
|
});
|
|
@@ -179,8 +171,8 @@ describe('detachGlobalShortcut', () => {
|
|
|
179
171
|
it('uses the creator-pinned provider after Host replacement', async () => {
|
|
180
172
|
const originUnsubscribe = vi.fn(async () => ({ reason: 'unsubscribed' as const }));
|
|
181
173
|
const replacementUnsubscribe = vi.fn(async () => ({ reason: 'unsubscribed' as const }));
|
|
182
|
-
const origin =
|
|
183
|
-
const replacement =
|
|
174
|
+
const origin = triggerProvider({ unsubscribe: originUnsubscribe });
|
|
175
|
+
const replacement = triggerProvider({ unsubscribe: replacementUnsubscribe });
|
|
184
176
|
const shortcut = createShortcut('Control+D');
|
|
185
177
|
await api().attachGlobalShortcut(origin, shortcut);
|
|
186
178
|
|
|
@@ -194,12 +186,14 @@ describe('detachGlobalShortcut', () => {
|
|
|
194
186
|
.fn<TriggerProviderLike['unsubscribe']>()
|
|
195
187
|
.mockRejectedValueOnce(new Error('first release failed'))
|
|
196
188
|
.mockResolvedValueOnce({ reason: 'unsubscribed' });
|
|
197
|
-
const
|
|
189
|
+
const hostShortcutTrigger = triggerProvider({ unsubscribe });
|
|
198
190
|
const shortcut = createShortcut('Control+R');
|
|
199
|
-
await api().attachGlobalShortcut(
|
|
191
|
+
await api().attachGlobalShortcut(hostShortcutTrigger, shortcut);
|
|
200
192
|
|
|
201
|
-
await expect(api().detachGlobalShortcut(
|
|
202
|
-
|
|
193
|
+
await expect(api().detachGlobalShortcut(hostShortcutTrigger, shortcut)).resolves.toEqual({
|
|
194
|
+
reason: 'trigger-provider-failed',
|
|
195
|
+
});
|
|
196
|
+
await expect(api().detachGlobalShortcut(hostShortcutTrigger, shortcut)).resolves.toEqual({ reason: 'detached' });
|
|
203
197
|
expect(unsubscribe).toHaveBeenCalledTimes(2);
|
|
204
198
|
});
|
|
205
199
|
});
|
|
@@ -215,16 +209,18 @@ describe('disposeGlobalShortcut', () => {
|
|
|
215
209
|
providerTrigger = trigger;
|
|
216
210
|
return { reason: 'subscribed' as const, subscription: subscription() };
|
|
217
211
|
});
|
|
218
|
-
const
|
|
212
|
+
const hostShortcutTrigger = triggerProvider({ subscribe, unsubscribe });
|
|
219
213
|
const shortcut = createShortcut('Control+X');
|
|
220
214
|
const listener = vi.fn();
|
|
221
215
|
connectSignal(shortcut.onTrigger, listener);
|
|
222
|
-
await api().attachGlobalShortcut(
|
|
216
|
+
await api().attachGlobalShortcut(hostShortcutTrigger, shortcut);
|
|
223
217
|
|
|
224
|
-
await expect(api().disposeGlobalShortcut(
|
|
218
|
+
await expect(api().disposeGlobalShortcut(hostShortcutTrigger, shortcut)).resolves.toEqual({
|
|
219
|
+
reason: 'trigger-provider-failed',
|
|
220
|
+
});
|
|
225
221
|
providerTrigger?.();
|
|
226
222
|
expect(listener).not.toHaveBeenCalled();
|
|
227
|
-
await expect(api().detachGlobalShortcut(
|
|
223
|
+
await expect(api().detachGlobalShortcut(hostShortcutTrigger, shortcut)).resolves.toEqual({ reason: 'detached' });
|
|
228
224
|
});
|
|
229
225
|
});
|
|
230
226
|
|
|
@@ -236,15 +232,17 @@ describe('initializeGlobalShortcut', () => {
|
|
|
236
232
|
|
|
237
233
|
describe('queryGlobalShortcutConflict', () => {
|
|
238
234
|
it('uses the exact query witness and preserves its method-tight outcome', async () => {
|
|
239
|
-
const
|
|
240
|
-
await expect(api().queryGlobalShortcutConflict(
|
|
235
|
+
const hostShortcutQuery = { [EntityRuntimeKey]: undefined, isRegistered: async () => true };
|
|
236
|
+
await expect(api().queryGlobalShortcutConflict(hostShortcutQuery, 'Control+Q')).resolves.toEqual({
|
|
237
|
+
reason: 'registered',
|
|
238
|
+
});
|
|
241
239
|
});
|
|
242
240
|
});
|
|
243
241
|
describe('queryGlobalShortcutRegistration', () => {
|
|
244
242
|
it('parses before querying and returns the exact parse error without calling the provider', async () => {
|
|
245
243
|
const isRegistered = vi.fn(async () => false);
|
|
246
|
-
const
|
|
247
|
-
await expect(api().queryGlobalShortcutRegistration(
|
|
244
|
+
const hostShortcutQuery = { [EntityRuntimeKey]: undefined, isRegistered };
|
|
245
|
+
await expect(api().queryGlobalShortcutRegistration(hostShortcutQuery, 'Control+NotAKey')).resolves.toEqual({
|
|
248
246
|
parseError: { reason: 'unknown-key', token: 'NotAKey' },
|
|
249
247
|
reason: 'unparseable',
|
|
250
248
|
});
|
|
@@ -252,14 +250,14 @@ describe('queryGlobalShortcutRegistration', () => {
|
|
|
252
250
|
});
|
|
253
251
|
|
|
254
252
|
it('distinguishes registered, not registered, and an attempted query-provider fault', async () => {
|
|
255
|
-
const yes =
|
|
256
|
-
const no =
|
|
257
|
-
const failed =
|
|
253
|
+
const yes = { [EntityRuntimeKey]: undefined, isRegistered: async () => true };
|
|
254
|
+
const no = { [EntityRuntimeKey]: undefined, isRegistered: async () => false };
|
|
255
|
+
const failed = {
|
|
258
256
|
[EntityRuntimeKey]: undefined,
|
|
259
257
|
isRegistered: async () => {
|
|
260
258
|
throw new Error('query failed');
|
|
261
259
|
},
|
|
262
|
-
}
|
|
260
|
+
};
|
|
263
261
|
await expect(api().queryGlobalShortcutRegistration(yes, 'Control+Q')).resolves.toEqual({ reason: 'registered' });
|
|
264
262
|
await expect(api().queryGlobalShortcutRegistration(no, 'Control+Q')).resolves.toEqual({ reason: 'not-registered' });
|
|
265
263
|
await expect(api().queryGlobalShortcutRegistration(failed, 'Control+Q')).resolves.toEqual({
|