@flighthq/permissions 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 CHANGED
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/permissions`. The `@
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/permissions@0.5.1-next.1069.554a2ac](https://github.com/flighthq/flight/tree/554a2acc3fecf189b89b0729308ff890a15c21cc/packages/permissions)
17
- - [License](https://github.com/flighthq/flight/blob/554a2acc3fecf189b89b0729308ff890a15c21cc/LICENSE.md)
16
+ - [Source for @flighthq/permissions@0.5.1-next.1201.9b49dee](https://github.com/flighthq/flight/tree/9b49dee3f22f6b2838c3d237edcc77bca65734f2/packages/permissions)
17
+ - [License](https://github.com/flighthq/flight/blob/9b49dee3f22f6b2838c3d237edcc77bca65734f2/LICENSE.md)
@@ -1,5 +1,5 @@
1
- import type { Host, PermissionName, PermissionQueryOutcome, PermissionRequestOutcome } from '@flighthq/types/contract';
2
- export declare function getPermissionState(host: Host, name: PermissionName): Promise<PermissionQueryOutcome>;
3
- export declare function getPermissionStates(host: Host, names: readonly PermissionName[]): Promise<PermissionQueryOutcome[]>;
4
- export declare function requestPermission(host: Host, name: PermissionName): Promise<PermissionRequestOutcome>;
1
+ import type { HostGeolocationProvider, HostMidiPermissionProvider, HostNotificationPermissionProvider, HostStoragePersistenceQueryProvider, HostStoragePersistenceRequestProvider, PermissionName, PermissionQueryOutcome, PermissionRequestOutcome } from '@flighthq/types/contract';
2
+ export declare function getPermissionState(hostNotificationPermission: Readonly<HostNotificationPermissionProvider> | undefined, hostMidiPermission: Readonly<HostMidiPermissionProvider> | undefined, hostStoragePersistenceQuery: Readonly<HostStoragePersistenceQueryProvider> | undefined, name: PermissionName): Promise<PermissionQueryOutcome>;
3
+ export declare function getPermissionStates(hostNotificationPermission: Readonly<HostNotificationPermissionProvider> | undefined, hostMidiPermission: Readonly<HostMidiPermissionProvider> | undefined, hostStoragePersistenceQuery: Readonly<HostStoragePersistenceQueryProvider> | undefined, names: readonly PermissionName[]): Promise<PermissionQueryOutcome[]>;
4
+ export declare function requestPermission(hostNotificationPermission: Readonly<HostNotificationPermissionProvider> | undefined, hostStoragePersistenceRequest: Readonly<HostStoragePersistenceRequestProvider> | undefined, hostGeolocation: Readonly<HostGeolocationProvider> | undefined, name: PermissionName): Promise<PermissionRequestOutcome>;
5
5
  //# sourceMappingURL=permission.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,cAAc,EACd,sBAAsB,EACtB,wBAAwB,EAKzB,MAAM,0BAA0B,CAAC;AAOlC,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAEpG;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAInH;AAKD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,wBAAwB,CAAC,CA0BrG"}
1
+ {"version":3,"file":"permission.d.ts","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,0BAA0B,EAC1B,kCAAkC,EAClC,mCAAmC,EACnC,qCAAqC,EACrC,cAAc,EACd,sBAAsB,EACtB,wBAAwB,EAGzB,MAAM,0BAA0B,CAAC;AAOlC,wBAAgB,kBAAkB,CAChC,0BAA0B,EAAE,QAAQ,CAAC,kCAAkC,CAAC,GAAG,SAAS,EACpF,kBAAkB,EAAE,QAAQ,CAAC,0BAA0B,CAAC,GAAG,SAAS,EACpE,2BAA2B,EAAE,QAAQ,CAAC,mCAAmC,CAAC,GAAG,SAAS,EACtF,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAKjC;AAID,wBAAgB,mBAAmB,CACjC,0BAA0B,EAAE,QAAQ,CAAC,kCAAkC,CAAC,GAAG,SAAS,EACpF,kBAAkB,EAAE,QAAQ,CAAC,0BAA0B,CAAC,GAAG,SAAS,EACpE,2BAA2B,EAAE,QAAQ,CAAC,mCAAmC,CAAC,GAAG,SAAS,EACtF,KAAK,EAAE,SAAS,cAAc,EAAE,GAC/B,OAAO,CAAC,sBAAsB,EAAE,CAAC,CASnC;AAKD,wBAAgB,iBAAiB,CAC/B,0BAA0B,EAAE,QAAQ,CAAC,kCAAkC,CAAC,GAAG,SAAS,EACpF,6BAA6B,EAAE,QAAQ,CAAC,qCAAqC,CAAC,GAAG,SAAS,EAC1F,eAAe,EAAE,QAAQ,CAAC,uBAAuB,CAAC,GAAG,SAAS,EAC9D,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,wBAAwB,CAAC,CA0BnC"}
@@ -1,32 +1,32 @@
1
1
  import { PERMISSION_NATIVE_HOLDINGS } from './permissionNativeHoldings';
2
- // Queries are read-only: this function never escalates to a request that may prompt. Notification is
3
- // projected exclusively from Host.notification.permission, MIDI from Host.midi.permission, and the
4
- // remaining names from explicit interim Web holdings recorded in permissionNativeHoldings.ts.
5
- export function getPermissionState(host, name) {
6
- return queryPermissionState(capturePermissionQueryOrigins(host, [name]), name);
2
+ // Queries are read-only: this function never escalates to a request that may prompt. Notification,
3
+ // MIDI, and persistence are projected exclusively from the direct providers passed by the caller;
4
+ // the remaining names use explicit interim Web holdings recorded in permissionNativeHoldings.ts.
5
+ export function getPermissionState(hostNotificationPermission, hostMidiPermission, hostStoragePersistenceQuery, name) {
6
+ return queryPermissionState(capturePermissionQueryOrigins(hostNotificationPermission, hostMidiPermission, hostStoragePersistenceQuery, [name]), name);
7
7
  }
8
8
  // Captures every owner before starting work, then preserves input order and repeated names. A provider
9
9
  // transition during one result cannot redirect any later entry in the same batch.
10
- export function getPermissionStates(host, names) {
10
+ export function getPermissionStates(hostNotificationPermission, hostMidiPermission, hostStoragePersistenceQuery, names) {
11
11
  if (names.length === 0)
12
12
  return Promise.resolve([]);
13
- const origins = capturePermissionQueryOrigins(host, names);
13
+ const origins = capturePermissionQueryOrigins(hostNotificationPermission, hostMidiPermission, hostStoragePersistenceQuery, names);
14
14
  return Promise.all(names.map((name) => queryPermissionState(origins, name)));
15
15
  }
16
16
  // Requests may prompt. Their outcome is method-tight: a missing route never degrades to a query, and a
17
17
  // cleanup failure after a successful temporary acquisition is Flight's operational failure, never user
18
18
  // denial.
19
- export function requestPermission(host, name) {
19
+ export function requestPermission(hostNotificationPermission, hostStoragePersistenceRequest, hostGeolocation, name) {
20
20
  if (name === 'notifications')
21
- return requestNotificationPermission(captureNotificationPermission(host));
21
+ return requestNotificationPermission(hostNotificationPermission ?? null);
22
22
  if (name === 'persistent-storage') {
23
- return requestStoragePersistencePermission(captureStoragePersistenceRequest(host));
23
+ return requestStoragePersistencePermission(hostStoragePersistenceRequest ?? null);
24
24
  }
25
25
  // Geolocation is delegated, not held: the capability owns the prompt mechanism and this projects its
26
26
  // outcome. Routed above the interim guard because that guard is derived from the holdings ledger,
27
27
  // and geolocation's row is gone.
28
28
  if (name === 'geolocation')
29
- return requestGeolocationAccessPermission(host);
29
+ return requestGeolocationAccessPermission(hostGeolocation);
30
30
  if (name === 'midi')
31
31
  return Promise.resolve({ reason: 'no-request-route' });
32
32
  if (!isInterimPermissionName(name))
@@ -46,31 +46,18 @@ export function requestPermission(host, name) {
46
46
  return Promise.resolve({ reason: 'unsupported' });
47
47
  }
48
48
  }
49
- function capturePermissionQueryOrigins(host, names) {
49
+ function capturePermissionQueryOrigins(hostNotificationPermission, hostMidiPermission, hostStoragePersistenceQuery, names) {
50
50
  const needsNotification = names.includes('notifications');
51
51
  const needsMidi = names.includes('midi');
52
52
  const needsPersistence = names.includes('persistent-storage');
53
53
  const needsWeb = names.some((name) => name !== 'midi' && name !== 'notifications' && name !== 'persistent-storage' && isInterimPermissionName(name));
54
54
  return {
55
- midi: needsMidi ? captureMidiPermission(host) : null,
56
- notification: needsNotification ? captureNotificationPermission(host) : null,
57
- persistence: needsPersistence ? captureStoragePersistenceQuery(host) : null,
55
+ midi: needsMidi ? (hostMidiPermission ?? null) : null,
56
+ notification: needsNotification ? (hostNotificationPermission ?? null) : null,
57
+ persistence: needsPersistence ? (hostStoragePersistenceQuery ?? null) : null,
58
58
  web: needsWeb ? captureWebPermissionQueryOrigin() : null,
59
59
  };
60
60
  }
61
- function captureMidiPermission(host) {
62
- return host.midi.permission ?? null;
63
- }
64
- function captureNotificationPermission(host) {
65
- const notification = host.notification;
66
- return notification.permission ?? null;
67
- }
68
- function captureStoragePersistenceQuery(host) {
69
- return host.storage.persistenceQuery ?? null;
70
- }
71
- function captureStoragePersistenceRequest(host) {
72
- return host.storage.persistenceRequest ?? null;
73
- }
74
61
  function captureWebPermissionQueryOrigin() {
75
62
  if (typeof navigator === 'undefined')
76
63
  return { reason: 'runtime-unavailable' };
@@ -195,14 +182,13 @@ function projectStoragePersistenceRequest(result) {
195
182
  // through as a REASON WITH NO STATE: it reports an acquisition deadline, not a decision, and
196
183
  // inventing a state from it would assert something the capability never observed. A caller that needs
197
184
  // the state queries for it.
198
- async function requestGeolocationAccessPermission(host) {
199
- const backend = host.system?.geolocation;
200
- if (backend === undefined || typeof backend.promptForAccess !== 'function') {
185
+ async function requestGeolocationAccessPermission(hostGeolocation) {
186
+ if (hostGeolocation === undefined || typeof hostGeolocation.promptForAccess !== 'function') {
201
187
  return { reason: 'runtime-unavailable' };
202
188
  }
203
189
  let outcome;
204
190
  try {
205
- outcome = await backend.promptForAccess();
191
+ outcome = await hostGeolocation.promptForAccess();
206
192
  }
207
193
  catch {
208
194
  return { reason: 'operation-failed' };
@@ -1 +1 @@
1
- {"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"permission.js","sourceRoot":"","sources":["../src/permission.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/permissions",
3
- "version": "0.5.1-next.1069.554a2ac",
3
+ "version": "0.5.1-next.1201.9b49dee",
4
4
  "author": "Joshua Granick and other contributors",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -38,7 +38,7 @@
38
38
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
39
  },
40
40
  "dependencies": {
41
- "@flighthq/types": "0.5.1-next.1069.554a2ac"
41
+ "@flighthq/types": "0.5.1-next.1201.9b49dee"
42
42
  },
43
43
  "devDependencies": {
44
44
  "typescript": "^5.3.0"
@@ -1,34 +1,39 @@
1
- import type { GeolocationAccessOutcome, GeolocationBackend, Host } from '@flighthq/types/contract';
1
+ import type { GeolocationAccessOutcome, HostGeolocationProvider } from '@flighthq/types/contract';
2
2
 
3
3
  import { requestPermission } from './permission';
4
4
 
5
- function hostWithGeolocation(outcome: GeolocationAccessOutcome, calls?: { count: number }): Host {
6
- const backend = {
5
+ function geolocationProvider(outcome: GeolocationAccessOutcome, calls?: { count: number }): HostGeolocationProvider {
6
+ return {
7
7
  promptForAccess: () => {
8
8
  if (calls !== undefined) calls.count += 1;
9
9
  return Promise.resolve(outcome);
10
10
  },
11
- } as unknown as GeolocationBackend;
12
- return { system: { geolocation: backend } } as unknown as Host;
11
+ } as unknown as HostGeolocationProvider;
13
12
  }
14
13
 
15
14
  describe('requestPermission', () => {
16
15
  it('projects a granted geolocation prompt to granted', async () => {
17
- expect(await requestPermission(hostWithGeolocation({ reason: 'granted' }), 'geolocation')).toEqual({
16
+ expect(
17
+ await requestPermission(undefined, undefined, geolocationProvider({ reason: 'granted' }), 'geolocation'),
18
+ ).toEqual({
18
19
  reason: 'granted',
19
20
  state: 'granted',
20
21
  });
21
22
  });
22
23
 
23
24
  it('projects a denied geolocation prompt to denied', async () => {
24
- expect(await requestPermission(hostWithGeolocation({ reason: 'denied' }), 'geolocation')).toEqual({
25
+ expect(
26
+ await requestPermission(undefined, undefined, geolocationProvider({ reason: 'denied' }), 'geolocation'),
27
+ ).toEqual({
25
28
  reason: 'denied',
26
29
  state: 'denied',
27
30
  });
28
31
  });
29
32
 
30
33
  it('projects a dismissed geolocation prompt to prompt', async () => {
31
- expect(await requestPermission(hostWithGeolocation({ reason: 'dismissed' }), 'geolocation')).toEqual({
34
+ expect(
35
+ await requestPermission(undefined, undefined, geolocationProvider({ reason: 'dismissed' }), 'geolocation'),
36
+ ).toEqual({
32
37
  reason: 'dismissed',
33
38
  state: 'prompt',
34
39
  });
@@ -38,19 +43,31 @@ describe('requestPermission', () => {
38
43
  // already granted (indoors, no fix). It is not evidence of anything the user did, so Permissions must
39
44
  // carry it through as a reason and infer NO state. A caller that needs the state queries for it.
40
45
  it('preserves a geolocation timeout as a reason-only outcome with no state', async () => {
41
- const outcome = await requestPermission(hostWithGeolocation({ reason: 'timeout' }), 'geolocation');
46
+ const outcome = await requestPermission(
47
+ undefined,
48
+ undefined,
49
+ geolocationProvider({ reason: 'timeout' }),
50
+ 'geolocation',
51
+ );
42
52
  expect(outcome.reason).toBe('timeout');
43
53
  expect(Object.hasOwn(outcome, 'state')).toBe(false);
44
54
  });
45
55
 
46
56
  it('does not report a timeout as denied, dismissed or granted', async () => {
47
- const outcome = await requestPermission(hostWithGeolocation({ reason: 'timeout' }), 'geolocation');
57
+ const outcome = await requestPermission(
58
+ undefined,
59
+ undefined,
60
+ geolocationProvider({ reason: 'timeout' }),
61
+ 'geolocation',
62
+ );
48
63
  expect(['denied', 'dismissed', 'granted']).not.toContain(outcome.reason);
49
64
  });
50
65
 
51
66
  // cleanup-failed is Flight's own failure after access WAS obtained, so the decision survives it.
52
67
  it('keeps the granted decision when cleanup fails', async () => {
53
- expect(await requestPermission(hostWithGeolocation({ reason: 'cleanup-failed' }), 'geolocation')).toEqual({
68
+ expect(
69
+ await requestPermission(undefined, undefined, geolocationProvider({ reason: 'cleanup-failed' }), 'geolocation'),
70
+ ).toEqual({
54
71
  reason: 'cleanup-failed',
55
72
  state: 'granted',
56
73
  });
@@ -58,18 +75,18 @@ describe('requestPermission', () => {
58
75
 
59
76
  it('asks the geolocation provider exactly once per request', async () => {
60
77
  const calls = { count: 0 };
61
- await requestPermission(hostWithGeolocation({ reason: 'granted' }, calls), 'geolocation');
78
+ await requestPermission(undefined, undefined, geolocationProvider({ reason: 'granted' }, calls), 'geolocation');
62
79
  expect(calls.count).toBe(1);
63
80
  });
64
81
 
65
82
  it('does not consult the geolocation provider for another permission name', async () => {
66
83
  const calls = { count: 0 };
67
- await requestPermission(hostWithGeolocation({ reason: 'granted' }, calls), 'midi');
84
+ await requestPermission(undefined, undefined, geolocationProvider({ reason: 'granted' }, calls), 'midi');
68
85
  expect(calls.count).toBe(0);
69
86
  });
70
87
 
71
88
  it('reports runtime-unavailable when no geolocation provider is installed', async () => {
72
- const outcome = await requestPermission({ system: {} } as unknown as Host, 'geolocation');
89
+ const outcome = await requestPermission(undefined, undefined, undefined, 'geolocation');
73
90
  expect(outcome).toEqual({ reason: 'runtime-unavailable' });
74
91
  });
75
92
  });
@@ -1,5 +1,9 @@
1
1
  import { EntityRuntimeKey } from '@flighthq/types/contract';
2
- import type { Host } from '@flighthq/types/contract';
2
+ import type {
3
+ HostMidiPermissionProvider,
4
+ HostNotificationPermissionProvider,
5
+ HostStoragePersistenceQueryProvider,
6
+ } from '@flighthq/types/contract';
3
7
  import { afterEach, describe, expect, it, vi } from 'vitest';
4
8
 
5
9
  import { getPermissionState } from './permission';
@@ -14,28 +18,34 @@ describe('getPermissionState', () => {
14
18
  ] as const)('projects Notification %s to the common %s state', async (permission, state) => {
15
19
  const getPermission = vi.fn(async () => ({ permission, reason: 'ok' as const }));
16
20
  const requestPermission = vi.fn();
17
- const host = notificationHost({ getPermission, requestPermission });
21
+ const provider = notificationProvider({ getPermission, requestPermission });
18
22
  forbidNativeNotificationOwner();
19
23
 
20
- await expect(getPermissionState(host, 'notifications')).resolves.toEqual({ reason: 'ok', state });
24
+ await expect(getPermissionState(provider, undefined, undefined, 'notifications')).resolves.toEqual({
25
+ reason: 'ok',
26
+ state,
27
+ });
21
28
  expect(getPermission).toHaveBeenCalledOnce();
22
29
  expect(requestPermission).not.toHaveBeenCalled();
23
30
  });
24
31
 
25
32
  it('preserves an owner query failure instead of returning a plausible state', async () => {
26
- const host = notificationHost({
33
+ const provider = notificationProvider({
27
34
  getPermission: vi.fn(async () => ({ reason: 'operation-failed' as const })),
28
35
  requestPermission: vi.fn(),
29
36
  });
30
37
 
31
- await expect(getPermissionState(host, 'notifications')).resolves.toEqual({ reason: 'operation-failed' });
38
+ await expect(getPermissionState(provider, undefined, undefined, 'notifications')).resolves.toEqual({
39
+ reason: 'operation-failed',
40
+ });
32
41
  });
33
42
 
34
43
  it('reports an absent Notification owner structurally instead of falling back to a native global', async () => {
35
- const host = notificationHost(null);
36
44
  forbidNativeNotificationOwner();
37
45
 
38
- await expect(getPermissionState(host, 'notifications')).resolves.toEqual({ reason: 'unsupported' });
46
+ await expect(getPermissionState(undefined, undefined, undefined, 'notifications')).resolves.toEqual({
47
+ reason: 'unsupported',
48
+ });
39
49
  });
40
50
 
41
51
  it.each([
@@ -62,29 +72,24 @@ describe('getPermissionState', () => {
62
72
  ],
63
73
  ] as const)('projects the Storage owner snapshot %# without inferring field consistency', async (owner, expected) => {
64
74
  const getPersistence = vi.fn(async () => owner);
65
- const host = persistenceHost({ getPersistence });
75
+ const provider = persistenceProvider({ getPersistence });
66
76
  forbidNativeStorageOwner();
67
77
 
68
- await expect(getPermissionState(host, 'persistent-storage')).resolves.toEqual(expected);
78
+ await expect(getPermissionState(undefined, undefined, provider, 'persistent-storage')).resolves.toEqual(expected);
69
79
  expect(getPersistence).toHaveBeenCalledOnce();
70
80
  });
71
81
 
72
82
  it('reports an absent persistence-query owner structurally', async () => {
73
- const host = persistenceHost(null);
74
83
  forbidNativeStorageOwner();
75
84
 
76
- await expect(getPermissionState(host, 'persistent-storage')).resolves.toEqual({ reason: 'unsupported' });
85
+ await expect(getPermissionState(undefined, undefined, undefined, 'persistent-storage')).resolves.toEqual({
86
+ reason: 'unsupported',
87
+ });
77
88
  });
78
89
 
79
90
  it('projects MIDI from only Host.midi.permission without touching Web globals or access', async () => {
80
91
  const getPermission = vi.fn(async () => ({ reason: 'ok' as const, state: 'prompt' as const }));
81
- const midi: object = {};
82
- Object.defineProperty(midi, 'access', {
83
- get() {
84
- throw new Error('a MIDI permission query acquired access');
85
- },
86
- });
87
- Object.defineProperty(midi, 'permission', { value: { getPermission } });
92
+ const provider = { [EntityRuntimeKey]: undefined, getPermission } as HostMidiPermissionProvider;
88
93
  vi.stubGlobal(
89
94
  'navigator',
90
95
  new Proxy(
@@ -97,14 +102,14 @@ describe('getPermissionState', () => {
97
102
  ),
98
103
  );
99
104
 
100
- await expect(getPermissionState(hostWithMidiGroup(midi), 'midi')).resolves.toEqual({
105
+ await expect(getPermissionState(undefined, provider, undefined, 'midi')).resolves.toEqual({
101
106
  reason: 'ok',
102
107
  state: 'prompt',
103
108
  });
104
109
  expect(getPermission).toHaveBeenCalledOnce();
105
110
  });
106
111
 
107
- it('requires an explicit Host at the caller boundary', () => {
112
+ it('requires explicit providers at the caller boundary', () => {
108
113
  expect(ambientPermissionQueryMustNotCompile).toBeTypeOf('function');
109
114
  });
110
115
  });
@@ -121,7 +126,7 @@ function forbidNativeNotificationOwner(): void {
121
126
  {},
122
127
  {
123
128
  get() {
124
- throw new Error('Permissions must delegate to Host.notification.permission');
129
+ throw new Error('Permissions must delegate to HostNotificationPermissionProvider');
125
130
  },
126
131
  },
127
132
  ),
@@ -135,46 +140,17 @@ function forbidNativeStorageOwner(): void {
135
140
  {},
136
141
  {
137
142
  get() {
138
- throw new Error('Permissions must delegate persistent-storage to Host.storage.persistenceQuery');
143
+ throw new Error('Permissions must delegate to HostStoragePersistenceQueryProvider');
139
144
  },
140
145
  },
141
146
  ),
142
147
  );
143
148
  }
144
149
 
145
- function persistenceHost(persistenceQuery: object | null): Host {
146
- return {
147
- [EntityRuntimeKey]: undefined,
148
- notification: {},
149
- storage: persistenceQuery === null ? {} : { persistenceQuery },
150
- } as unknown as Host;
151
- }
152
-
153
- function notificationHost(permission: object | null): Host {
154
- return {
155
- [EntityRuntimeKey]: undefined,
156
- accessibility: {},
157
- app: {},
158
- clipboard: {},
159
- connectivity: {},
160
- dialog: {},
161
- graphics: {},
162
- input: {},
163
- media: {},
164
- menu: {},
165
- midi: {},
166
- net: {},
167
- notification: permission === null ? {} : { permission },
168
- share: {},
169
- storage: {},
170
- system: {},
171
- text: {},
172
- tray: {},
173
- ui: {},
174
- window: {},
175
- } as unknown as Host;
150
+ function persistenceProvider(provider: object): HostStoragePersistenceQueryProvider {
151
+ return { [EntityRuntimeKey]: undefined, ...provider } as unknown as HostStoragePersistenceQueryProvider;
176
152
  }
177
153
 
178
- function hostWithMidiGroup(midi: object): Host {
179
- return { ...notificationHost(null), midi } as Host;
154
+ function notificationProvider(provider: object): HostNotificationPermissionProvider {
155
+ return provider as HostNotificationPermissionProvider;
180
156
  }
@@ -1,5 +1,10 @@
1
1
  import { EntityRuntimeKey } from '@flighthq/types/contract';
2
- import type { Host, StoragePersistenceResult } from '@flighthq/types/contract';
2
+ import type {
3
+ HostMidiPermissionProvider,
4
+ HostNotificationPermissionProvider,
5
+ HostStoragePersistenceQueryProvider,
6
+ StoragePersistenceResult,
7
+ } from '@flighthq/types/contract';
3
8
  import { afterEach, describe, expect, it, vi } from 'vitest';
4
9
 
5
10
  import { getPermissionStates } from './permission';
@@ -7,42 +12,27 @@ import { getPermissionStates } from './permission';
7
12
  describe('getPermissionStates', () => {
8
13
  afterEach(() => vi.unstubAllGlobals());
9
14
 
10
- it('captures every resolved owner once before work and never splits repeated names across providers', async () => {
15
+ it('pins repeated names to the direct provider passed by the caller', async () => {
11
16
  const events: string[] = [];
12
17
  const second = permissionProvider('denied', events, 'second');
13
18
  const first = permissionProvider('granted', events, 'first', () => {
14
19
  active = second;
15
20
  });
16
21
  let active = first;
17
- let notificationOwnerReads = 0;
18
- const notification: object = {};
19
- Object.defineProperty(notification, 'permission', {
20
- get() {
21
- notificationOwnerReads += 1;
22
- events.push('capture:notification');
23
- return active;
24
- },
25
- });
26
- const host = hostWithNotificationGroup(notification);
27
22
 
28
- await expect(getPermissionStates(host, ['notifications', 'notifications'])).resolves.toEqual([
29
- { reason: 'ok', state: 'granted' },
30
- { reason: 'ok', state: 'granted' },
31
- ]);
32
- expect(notificationOwnerReads).toBe(1);
33
- expect(events).toEqual(['capture:notification', 'work:first', 'work:first']);
23
+ await expect(getPermissionStates(first, undefined, undefined, ['notifications', 'notifications'])).resolves.toEqual(
24
+ [
25
+ { reason: 'ok', state: 'granted' },
26
+ { reason: 'ok', state: 'granted' },
27
+ ],
28
+ );
29
+ expect(active).toBe(second);
30
+ expect(events).toEqual(['work:first', 'work:first']);
34
31
  });
35
32
 
36
- it('captures the Notification and interim Web-query owners before starting either operation', async () => {
33
+ it('captures the interim Web-query owner before starting provider work', async () => {
37
34
  const events: string[] = [];
38
35
  const provider = permissionProvider('granted', events, 'notification');
39
- const notification: object = {};
40
- Object.defineProperty(notification, 'permission', {
41
- get() {
42
- events.push('capture:notification');
43
- return provider;
44
- },
45
- });
46
36
  const permissions = {
47
37
  query: async () => {
48
38
  events.push('work:web-query');
@@ -58,16 +48,14 @@ describe('getPermissionStates', () => {
58
48
  });
59
49
  vi.stubGlobal('navigator', navigatorValue);
60
50
 
61
- await expect(
62
- getPermissionStates(hostWithNotificationGroup(notification), ['notifications', 'camera']),
63
- ).resolves.toEqual([
51
+ await expect(getPermissionStates(provider, undefined, undefined, ['notifications', 'camera'])).resolves.toEqual([
64
52
  { reason: 'ok', state: 'granted' },
65
53
  { reason: 'ok', state: 'denied' },
66
54
  ]);
67
- expect(events.slice(0, 2)).toEqual(['capture:notification', 'capture:web-query']);
55
+ expect(events.slice(0, 2)).toEqual(['capture:web-query', 'work:notification']);
68
56
  });
69
57
 
70
- it('captures the MIDI permission owner exactly once and keeps repeats pinned to it', async () => {
58
+ it('keeps repeated MIDI queries pinned to the direct provider', async () => {
71
59
  const events: string[] = [];
72
60
  const second = {
73
61
  async getPermission() {
@@ -85,20 +73,7 @@ describe('getPermissionStates', () => {
85
73
  let active: {
86
74
  getPermission(): Promise<{ reason: 'ok'; state: 'denied' | 'granted' }>;
87
75
  } = first;
88
- let midiOwnerReads = 0;
89
- const midi: object = {};
90
- Object.defineProperty(midi, 'permission', {
91
- get() {
92
- midiOwnerReads += 1;
93
- events.push('capture:midi');
94
- return active;
95
- },
96
- });
97
- Object.defineProperty(midi, 'access', {
98
- get() {
99
- throw new Error('batch permission query acquired MIDI access');
100
- },
101
- });
76
+ const provider = { [EntityRuntimeKey]: undefined, ...first } as HostMidiPermissionProvider;
102
77
  vi.stubGlobal(
103
78
  'navigator',
104
79
  new Proxy(
@@ -111,12 +86,12 @@ describe('getPermissionStates', () => {
111
86
  ),
112
87
  );
113
88
 
114
- await expect(getPermissionStates(hostWithGroups({}, midi), ['midi', 'midi'])).resolves.toEqual([
89
+ await expect(getPermissionStates(undefined, provider, undefined, ['midi', 'midi'])).resolves.toEqual([
115
90
  { reason: 'ok', state: 'granted' },
116
91
  { reason: 'ok', state: 'granted' },
117
92
  ]);
118
- expect(midiOwnerReads).toBe(1);
119
- expect(events).toEqual(['capture:midi', 'work:first', 'work:first']);
93
+ expect(active).toBe(second);
94
+ expect(events).toEqual(['work:first', 'work:first']);
120
95
  });
121
96
 
122
97
  it('keeps input order and repeated entries when work resolves out of order', async () => {
@@ -126,7 +101,7 @@ describe('getPermissionStates', () => {
126
101
  query: () => new Promise((resolve) => resolvers.push(resolve)),
127
102
  },
128
103
  });
129
- const result = getPermissionStates(hostWithNotificationGroup({}), ['camera', 'microphone', 'camera']);
104
+ const result = getPermissionStates(undefined, undefined, undefined, ['camera', 'microphone', 'camera']);
130
105
  await vi.waitFor(() => expect(resolvers).toHaveLength(3));
131
106
  resolvers[2]({ state: 'prompt' });
132
107
  resolvers[0]({ state: 'granted' });
@@ -140,16 +115,14 @@ describe('getPermissionStates', () => {
140
115
  });
141
116
 
142
117
  it('does not resolve an owner for an empty batch', async () => {
143
- const host = hostWithNotificationGroup(
144
- new Proxy(
145
- {},
146
- {
147
- get() {
148
- throw new Error('empty batch resolved an owner');
149
- },
118
+ const provider = new Proxy(
119
+ {},
120
+ {
121
+ get() {
122
+ throw new Error('empty batch resolved an owner');
150
123
  },
151
- ),
152
- );
124
+ },
125
+ ) as HostNotificationPermissionProvider;
153
126
  vi.stubGlobal(
154
127
  'navigator',
155
128
  new Proxy(
@@ -162,7 +135,7 @@ describe('getPermissionStates', () => {
162
135
  ),
163
136
  );
164
137
 
165
- await expect(getPermissionStates(host, [])).resolves.toEqual([]);
138
+ await expect(getPermissionStates(provider, undefined, undefined, [])).resolves.toEqual([]);
166
139
  });
167
140
 
168
141
  it('captures the persistence-query owner once and preserves repeated entries and order', async () => {
@@ -181,15 +154,7 @@ describe('getPermissionStates', () => {
181
154
  },
182
155
  };
183
156
  let active = first;
184
- let ownerReads = 0;
185
- const storage: object = {};
186
- Object.defineProperty(storage, 'persistenceQuery', {
187
- get() {
188
- ownerReads++;
189
- events.push('capture:persistence-query');
190
- return active;
191
- },
192
- });
157
+ const provider = { [EntityRuntimeKey]: undefined, ...first } as HostStoragePersistenceQueryProvider;
193
158
  vi.stubGlobal(
194
159
  'navigator',
195
160
  new Proxy(
@@ -203,59 +168,22 @@ describe('getPermissionStates', () => {
203
168
  );
204
169
 
205
170
  await expect(
206
- getPermissionStates(hostWithStorageGroup(storage), ['persistent-storage', 'persistent-storage']),
171
+ getPermissionStates(undefined, undefined, provider, ['persistent-storage', 'persistent-storage']),
207
172
  ).resolves.toEqual([
208
173
  { reason: 'best-effort', state: null },
209
174
  { reason: 'best-effort', state: null },
210
175
  ]);
211
- expect(ownerReads).toBe(1);
212
- expect(events).toEqual(['capture:persistence-query', 'work:first', 'work:first']);
176
+ expect(active).toBe(second);
177
+ expect(events).toEqual(['work:first', 'work:first']);
213
178
  });
214
179
  });
215
180
 
216
- function hostWithNotificationGroup(notification: object): Host {
217
- return hostWithGroups(notification, {});
218
- }
219
-
220
- function hostWithGroups(notification: object, midi: object): Host {
221
- return {
222
- [EntityRuntimeKey]: undefined,
223
- accessibility: {},
224
- app: {},
225
- clipboard: {},
226
- connectivity: {},
227
- dialog: {},
228
- graphics: {},
229
- input: {},
230
- media: {},
231
- menu: {},
232
- midi,
233
- net: {},
234
- notification,
235
- share: {},
236
- storage: {},
237
- system: {},
238
- text: {},
239
- tray: {},
240
- ui: {},
241
- window: {},
242
- } as unknown as Host;
243
- }
244
-
245
- function hostWithStorageGroup(storage: object): Host {
246
- return {
247
- [EntityRuntimeKey]: undefined,
248
- notification: {},
249
- storage,
250
- } as unknown as Host;
251
- }
252
-
253
181
  function permissionProvider(
254
182
  permission: 'denied' | 'granted',
255
183
  events: string[],
256
184
  label: string,
257
185
  beforeReturn?: () => void,
258
- ): object {
186
+ ): HostNotificationPermissionProvider {
259
187
  return {
260
188
  [EntityRuntimeKey]: undefined,
261
189
  async getPermission() {
@@ -266,5 +194,5 @@ function permissionProvider(
266
194
  async requestPermission() {
267
195
  return { reason: permission };
268
196
  },
269
- };
197
+ } as HostNotificationPermissionProvider;
270
198
  }
@@ -1,5 +1,8 @@
1
1
  import { EntityRuntimeKey } from '@flighthq/types/contract';
2
- import type { Host } from '@flighthq/types/contract';
2
+ import type {
3
+ HostNotificationPermissionProvider,
4
+ HostStoragePersistenceRequestProvider,
5
+ } from '@flighthq/types/contract';
3
6
  import { afterEach, describe, expect, it, vi } from 'vitest';
4
7
 
5
8
  import { requestPermission } from './permission';
@@ -13,20 +16,25 @@ describe('requestPermission', () => {
13
16
  ['dismissed', 'prompt'],
14
17
  ] as const)('projects the Notification %s outcome without erasing its owner reason', async (reason, state) => {
15
18
  const request = vi.fn(async () => ({ reason }));
16
- const host = notificationHost({ getPermission: vi.fn(), requestPermission: request });
19
+ const provider = notificationProvider({ getPermission: vi.fn(), requestPermission: request });
17
20
  forbidNativeNotificationOwner();
18
21
 
19
- await expect(requestPermission(host, 'notifications')).resolves.toEqual({ reason, state });
22
+ await expect(requestPermission(provider, undefined, undefined, 'notifications')).resolves.toEqual({
23
+ reason,
24
+ state,
25
+ });
20
26
  expect(request).toHaveBeenCalledOnce();
21
27
  });
22
28
 
23
29
  it('preserves an owner request failure instead of translating it to denial', async () => {
24
- const host = notificationHost({
30
+ const provider = notificationProvider({
25
31
  getPermission: vi.fn(),
26
32
  requestPermission: vi.fn(async () => ({ reason: 'operation-failed' as const })),
27
33
  });
28
34
 
29
- await expect(requestPermission(host, 'notifications')).resolves.toEqual({ reason: 'operation-failed' });
35
+ await expect(requestPermission(provider, undefined, undefined, 'notifications')).resolves.toEqual({
36
+ reason: 'operation-failed',
37
+ });
30
38
  });
31
39
 
32
40
  it('attempts every acquired media-track cleanup and reports cleanup failure as operational, not denial', async () => {
@@ -48,7 +56,7 @@ describe('requestPermission', () => {
48
56
  },
49
57
  });
50
58
 
51
- await expect(requestPermission(notificationHost(null), 'camera')).resolves.toEqual({
59
+ await expect(requestPermission(undefined, undefined, undefined, 'camera')).resolves.toEqual({
52
60
  reason: 'cleanup-failed',
53
61
  state: 'granted',
54
62
  });
@@ -66,7 +74,7 @@ describe('requestPermission', () => {
66
74
  },
67
75
  });
68
76
 
69
- await expect(requestPermission(notificationHost(null), 'screen-wake-lock')).resolves.toEqual({
77
+ await expect(requestPermission(undefined, undefined, undefined, 'screen-wake-lock')).resolves.toEqual({
70
78
  reason: 'cleanup-failed',
71
79
  state: 'granted',
72
80
  });
@@ -75,7 +83,7 @@ describe('requestPermission', () => {
75
83
  it('reports the Wake Lock API as unavailable when the standard property is absent at runtime', async () => {
76
84
  vi.stubGlobal('navigator', {});
77
85
 
78
- await expect(requestPermission(notificationHost(null), 'screen-wake-lock')).resolves.toEqual({
86
+ await expect(requestPermission(undefined, undefined, undefined, 'screen-wake-lock')).resolves.toEqual({
79
87
  reason: 'runtime-unavailable',
80
88
  });
81
89
  });
@@ -89,7 +97,7 @@ describe('requestPermission', () => {
89
97
  },
90
98
  });
91
99
 
92
- await expect(requestPermission(notificationHost(null), 'camera')).resolves.toEqual({
100
+ await expect(requestPermission(undefined, undefined, undefined, 'camera')).resolves.toEqual({
93
101
  reason: 'operation-failed',
94
102
  });
95
103
  });
@@ -98,7 +106,9 @@ describe('requestPermission', () => {
98
106
  const query = vi.fn(async () => ({ state: 'granted' }));
99
107
  vi.stubGlobal('navigator', { permissions: { query } });
100
108
 
101
- await expect(requestPermission(notificationHost(null), 'push')).resolves.toEqual({ reason: 'no-request-route' });
109
+ await expect(requestPermission(undefined, undefined, undefined, 'push')).resolves.toEqual({
110
+ reason: 'no-request-route',
111
+ });
102
112
  expect(query).not.toHaveBeenCalled();
103
113
  });
104
114
 
@@ -128,45 +138,35 @@ describe('requestPermission', () => {
128
138
  'projects the Storage request snapshot %# without inferring field consistency',
129
139
  async (owner, expected) => {
130
140
  const requestPersistence = vi.fn(async () => owner);
131
- const host = persistenceHost({ requestPersistence });
141
+ const provider = persistenceProvider({ requestPersistence });
132
142
  forbidNativeStorageOwner();
133
143
 
134
- await expect(requestPermission(host, 'persistent-storage')).resolves.toEqual(expected);
144
+ await expect(requestPermission(undefined, provider, undefined, 'persistent-storage')).resolves.toEqual(expected);
135
145
  expect(requestPersistence).toHaveBeenCalledOnce();
136
146
  },
137
147
  );
138
148
 
139
149
  it('reports an absent persistence-request owner without crossing into query', async () => {
140
150
  const getPersistence = vi.fn(async () => ({ outcome: 'persistent' as const, permissionState: 'granted' as const }));
141
- const host = persistenceHost(null, { getPersistence });
142
151
  forbidNativeStorageOwner();
143
152
 
144
- await expect(requestPermission(host, 'persistent-storage')).resolves.toEqual({ reason: 'unsupported' });
153
+ await expect(requestPermission(undefined, undefined, undefined, 'persistent-storage')).resolves.toEqual({
154
+ reason: 'unsupported',
155
+ });
145
156
  expect(getPersistence).not.toHaveBeenCalled();
146
157
  });
147
158
 
148
- it('makes MIDI query-only here and never acquires access from either owner', async () => {
149
- const midi: object = {};
150
- Object.defineProperty(midi, 'permission', {
151
- get() {
152
- throw new Error('a MIDI request-only decision queried permission');
153
- },
154
- });
155
- Object.defineProperty(midi, 'access', {
156
- get() {
157
- throw new Error('Permissions acquired explicit MIDI access');
158
- },
159
- });
159
+ it('makes MIDI query-only here and never acquires ambient access', async () => {
160
160
  const requestMIDIAccess = vi.fn();
161
161
  vi.stubGlobal('navigator', { requestMIDIAccess });
162
162
 
163
- await expect(requestPermission(hostWithMidiGroup(midi), 'midi')).resolves.toEqual({
163
+ await expect(requestPermission(undefined, undefined, undefined, 'midi')).resolves.toEqual({
164
164
  reason: 'no-request-route',
165
165
  });
166
166
  expect(requestMIDIAccess).not.toHaveBeenCalled();
167
167
  });
168
168
 
169
- it('requires an explicit Host at the caller boundary', () => {
169
+ it('requires explicit providers at the caller boundary', () => {
170
170
  expect(ambientPermissionRequestMustNotCompile).toBeTypeOf('function');
171
171
  });
172
172
  });
@@ -183,7 +183,7 @@ function forbidNativeNotificationOwner(): void {
183
183
  {},
184
184
  {
185
185
  get() {
186
- throw new Error('Permissions must delegate to Host.notification.permission');
186
+ throw new Error('Permissions must delegate to HostNotificationPermissionProvider');
187
187
  },
188
188
  },
189
189
  ),
@@ -197,49 +197,17 @@ function forbidNativeStorageOwner(): void {
197
197
  {},
198
198
  {
199
199
  get() {
200
- throw new Error('Permissions must delegate persistent-storage to Host.storage.persistenceRequest');
200
+ throw new Error('Permissions must delegate to HostStoragePersistenceRequestProvider');
201
201
  },
202
202
  },
203
203
  ),
204
204
  );
205
205
  }
206
206
 
207
- function persistenceHost(persistenceRequest: object | null, persistenceQuery: object | null = null): Host {
208
- return {
209
- [EntityRuntimeKey]: undefined,
210
- notification: {},
211
- storage: {
212
- ...(persistenceQuery === null ? {} : { persistenceQuery }),
213
- ...(persistenceRequest === null ? {} : { persistenceRequest }),
214
- },
215
- } as unknown as Host;
216
- }
217
-
218
- function notificationHost(permission: object | null): Host {
219
- return {
220
- [EntityRuntimeKey]: undefined,
221
- accessibility: {},
222
- app: {},
223
- clipboard: {},
224
- connectivity: {},
225
- dialog: {},
226
- graphics: {},
227
- input: {},
228
- media: {},
229
- menu: {},
230
- midi: {},
231
- net: {},
232
- notification: permission === null ? {} : { permission },
233
- share: {},
234
- storage: {},
235
- system: {},
236
- text: {},
237
- tray: {},
238
- ui: {},
239
- window: {},
240
- } as unknown as Host;
207
+ function persistenceProvider(provider: object): HostStoragePersistenceRequestProvider {
208
+ return { [EntityRuntimeKey]: undefined, ...provider } as unknown as HostStoragePersistenceRequestProvider;
241
209
  }
242
210
 
243
- function hostWithMidiGroup(midi: object): Host {
244
- return { ...notificationHost(null), midi } as Host;
211
+ function notificationProvider(provider: object): HostNotificationPermissionProvider {
212
+ return provider as HostNotificationPermissionProvider;
245
213
  }