diff --git a/libs/permissions/permissionLogic/src/lib/permission-logic.spec.ts b/libs/permissions/permissionLogic/src/lib/permission-logic.spec.ts index b25b4a9..6145a9e 100644 --- a/libs/permissions/permissionLogic/src/lib/permission-logic.spec.ts +++ b/libs/permissions/permissionLogic/src/lib/permission-logic.spec.ts @@ -19,7 +19,6 @@ import { import { unimplementedPermissionMachineActions } from './permission.actions'; import { - InitialPermissionStatusMap, Permission, PermissionMachineEvents, PermissionStatus, @@ -27,8 +26,9 @@ import { PermissionStatuses, Permissions, } from './permission.types'; +import { InitialPermissionStatusMap } from './permission.fixtures'; -export type ParentEvent = +export type PermissionMonitoringMachineEvents = | { type: 'allPermissionsChecked'; statuses: PermissionStatusMapType; @@ -46,6 +46,7 @@ export type ParentEvent = type ApplicationLifecycleState = | 'applicationForegrounded' | 'applicationBackgrounded'; + type ApplicationStateChangeHandler = (event: ApplicationLifecycleState) => void; const stubSubscribeToApplicationStateChanges = ( handleApplicationStateChange: ApplicationStateChangeHandler @@ -116,7 +117,7 @@ describe('Permission Requester and Checker Machine', () => { }; const parentMachine = setup({ - types: {} as { events: ParentEvent }, + types: {} as { events: PermissionMonitoringMachineEvents }, actors: { permissionCheckerAndRequesterMachine, }, @@ -193,7 +194,7 @@ describe('Permission Requester and Checker Machine', () => { }; const parentMachine = setup({ - types: {} as { events: ParentEvent }, + types: {} as { events: PermissionMonitoringMachineEvents }, actors: { permissionCheckerAndRequesterMachine, }, @@ -243,7 +244,7 @@ describe('Permission Monitoring Machine', () => { it('handle the happy path of being invoked, checking permission initially and then handle a permission request', async () => { const permissionMonitoringMachine = setup({ types: {} as { - events: ParentEvent; + events: PermissionMonitoringMachineEvents; context: { permissionsStatuses: PermissionStatusMapType }; }, actors: { @@ -416,18 +417,18 @@ describe('Permission Monitoring Machine', () => { const permissionCheckerAndRequesterMachine = setup({ types: { context: {} as { - parent?: ActorRef, ParentEvent>; + parent?: ActorRef, PermissionMonitoringMachineEvents>; statuses: PermissionStatusMapType; }, events: {} as PermissionMachineEvents, input: {} as { - parent?: ActorRef, ParentEvent>; + parent?: ActorRef, PermissionMonitoringMachineEvents>; }, }, actions: { checkedSendParent: enqueueActions( - ({ context, enqueue }, event: ParentEvent) => { + ({ context, enqueue }, event: PermissionMonitoringMachineEvents) => { if (!context.parent) { console.log( 'WARN: an attempt to send an event to a non-existent parent' diff --git a/libs/permissions/permissionLogic/src/lib/permission-logic.ts b/libs/permissions/permissionLogic/src/lib/permission-logic.ts index 08be9f2..c155820 100644 --- a/libs/permissions/permissionLogic/src/lib/permission-logic.ts +++ b/libs/permissions/permissionLogic/src/lib/permission-logic.ts @@ -1,136 +1 @@ -import { fromCallback, raise, setup } from 'xstate'; - -export const Permissions = { - bluetooth: 'bluetooth', - microphone: 'microphone', -} as const; -export type Permission = (typeof Permissions)[keyof typeof Permissions]; -export const PermissionStatuses = { - unasked: 'unasked', - granted: 'granted', - denied: 'denied', - revoked: 'revoked', - blocked: 'blocked', -} as const; -export type PermissionStatus = - (typeof PermissionStatuses)[keyof typeof PermissionStatuses]; - -type PermissionStatusMapType = Record; -const PermissionStatusMap: PermissionStatusMapType = { - [Permissions.bluetooth]: PermissionStatuses.unasked, - [Permissions.microphone]: PermissionStatuses.unasked, -} as const; - -type PermissionMonitoringMachineContext = { - permissionStatuses: PermissionStatusMapType; -}; -type PermissionMonitoringMachineEvents = - | { type: 'checkPermissions' } - | { - type: 'permissionChecked'; - permission: Permission; - status: PermissionStatus; - } - | { type: 'applicationForegrounded' } - | { type: 'applicationBackgrounded' }; - -const ApplicationLifecycleEvents = { - applicationForegrounded: 'applicationForegrounded', - applicationBackgrounded: 'applicationBackgrounded', -} as const; - -type ApplicationLifecycleEvent = - (typeof ApplicationLifecycleEvents)[keyof typeof ApplicationLifecycleEvents]; - -// type PermissionMonitoringMachineInput = { -// subscribeToApplicationLifecycleEvents: ( -// event: ApplicationLifecycleEvent -// ) => void; -// checkBluetoothPermission: () => Promise; -// checkMicrophonePermission: () => Promise; -// requestBluetoothPermission: () => Promise; -// requestMicrophonePermission: () => Promise; -// }; - -const permissionMonitoringMachine = setup({ - types: { - // input: {} as PermissionMonitoringMachineInput, - context: {} as PermissionMonitoringMachineContext, - events: {} as PermissionMonitoringMachineEvents, - }, - actions: { - triggerPermissionCheck: raise({ type: 'checkPermissions' }), - // decrement: assign({ - // count: ({ context }) => context.count - 1, - // }), - }, - actors: { - subscribeToApplicationLifecycleEvents: fromCallback( - ({ input, sendBack, receive, self, system }) => { - // ... - // i have to have a default implementation here... what should it be? - // I'm leaning towards unimplemented to avoid confusion - /* - can't "forward" input to child actor... - - input.subscribeToApplicationLifecycleEvents((event) => { - if (event === 'applicationForegrounded') { - sendBack({ type: 'applicationForegrounded' }); - } else if (event === 'applicationBackgrounded') { - sendBack({ type: 'applicationBackgrounded' }); - } - }); - */ - } - ), - bluetoothPermissionActor: fromCallback( - ({ input, sendBack, receive, self, system }) => { - const checkPermission = (): Promise => { - return Promise.resolve(PermissionStatuses.granted); - }; - - const requestPermission = (): Promise => { - return Promise.resolve(PermissionStatuses.granted); - }; - - receive(async (event) => { - if (event.type === 'checkPermissions') { - const result = await checkPermission(); - sendBack({ - type: 'permissionChecked', - permission: Permissions.bluetooth, - status: result, - }); - } else if (event.type === 'requestPermission') { - const result = await requestPermission(); - sendBack({ - type: 'permissionChecked', - permission: Permissions.bluetooth, - status: result, - }); - } - }); - // ... - // needs to listen for 'checkPermissions' and 'requestPermission' events and then - // return results back to parent actor - // also needs to ensure mapping of library type -> permission status type that we recognize and respond to - } - ), - }, -}).createMachine({ - invoke: { - src: 'subscribeToApplicationLifecycleEvents', - id: 'applicationLifecycleEventsSubscriber', - }, - context: { permissionStatuses: PermissionStatusMap }, - on: { - applicationForegrounded: { target: 'application is in foreground' }, - applicationBackgrounded: { target: 'application is in background' }, - }, - states: { - 'application is in foreground': { - entry: ['triggerPermissionCheck'], - }, - 'application is in background': {}, - }, -}); +export const foo = 'bar'; diff --git a/libs/permissions/permissionLogic/src/lib/permission.fixtures.ts b/libs/permissions/permissionLogic/src/lib/permission.fixtures.ts new file mode 100644 index 0000000..436e0b0 --- /dev/null +++ b/libs/permissions/permissionLogic/src/lib/permission.fixtures.ts @@ -0,0 +1,10 @@ +import { + PermissionStatuses, + PermissionStatusMapType, + Permissions, +} from './permission.types'; + +export const InitialPermissionStatusMap: PermissionStatusMapType = { + [Permissions.bluetooth]: PermissionStatuses.unasked, + [Permissions.microphone]: PermissionStatuses.unasked, +} as const; diff --git a/libs/permissions/permissionLogic/src/lib/permission.types.ts b/libs/permissions/permissionLogic/src/lib/permission.types.ts index 2d0f873..d2e23de 100644 --- a/libs/permissions/permissionLogic/src/lib/permission.types.ts +++ b/libs/permissions/permissionLogic/src/lib/permission.types.ts @@ -28,10 +28,6 @@ export interface PermissionMachineActions { } export type PermissionStatusMapType = Record; -export const InitialPermissionStatusMap: PermissionStatusMapType = { - [Permissions.bluetooth]: PermissionStatuses.unasked, - [Permissions.microphone]: PermissionStatuses.unasked, -} as const; export const ApplicationLifecycleStates = { applicationInForeground: 'application is in foreground',