UNPKG

use-secret-code

Version:

Custom hook for adding cheat codes to your React app

1 lines 8.13 kB
{"version":3,"sources":["../src/index.ts","../src/utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/consistent-type-assertions */\nimport * as React from 'react';\nimport { assign, setup } from 'xstate';\nimport { useMachine } from '@xstate/react';\nimport { isEqual, takeRight } from './utils';\n\ntype CheatCodeContext = {\n cheatCodeKeys?: string[];\n typedKeys: string[];\n};\n\ntype CheatCodeMachineInput = {\n cheatCodeKeys: CheatCodeContext['cheatCodeKeys'];\n};\n\nconst initialContext: CheatCodeContext = {\n cheatCodeKeys: undefined,\n typedKeys: [],\n};\n\ntype KeydownEvent = KeyboardEvent & { type: 'keydown' };\n\n/** @xstate-layout N4IgpgJg5mDOIC5QGMAWYCGAXAwgewjAFkM0BLAOzADoIzYMAjAG0mrIlYGIBrMATwh4A7hQDaABgC6iUAAc8sMljJ4KskAA9EAJgCsAdmoBGCQBYAHHoDMANjOnbei7YA0IfojMTb1B7YsATgtjAxsgs1sAXyj3NExcAmJSVEoaOgYWNg5uSRkkEAUlFTUNbQQdY189Y1qJPUiDQJtjM3dPBEDjaltrGusB2oMdHVsDGLj0bHxCEnIqWnomVghqACcwZDw1ugooXgEhUTyNIuVVdQLyhrMTYcCuiwljYIlrdsRrAwk-Z76LaxvL71aKxEDxaZJOapBYZZZsDZbHaUfYnApnEqXUDlQJOHoWEIPF6AqoGD4VELUerPCw6CJhWw6CbgqaJWYpNKLTIrdabba7faaWBYbA0DAAMywYDWAAohFQACr8OQogCUXAhbOS83SSyyq0R-JRaPkinOpSuuh0gWowLMzVadJqzXJdKMxn0ZjsXsMwTMzM1M21MJoYAo8NWOTAB0EInE0lOZsxZUQpgMt3T5kBb09ZjJHkQBmstx0kUs+gkpYsTQDrKD0M5YYj7E40ZNhSTFxTFSq1BqdQaY2a1la5Nsxgs1AMdTGYVa3nGYMDUI5Cyb+t5SIFMaO8fypuKXctCGM1geff0gWsFm8enquLHzT7ekZOgM1cqgP9S7rK511HXHlDWRPYuHbDEj2xVN9GsZ9zEHV9rz0clvBtfwCUrG9RmaPRawSetV1DcMN2A7chRFKVqAlKVZXlMAlRVPZ1WXdl-0AhE+RAqBwM7C0oJPCRAh0KdRiCO871pMw2gLBBxz0Kc6mLWwHgBJlmQoJJ4AKFjg05OENyjRNDz4rREACPwXyaadcRCMZkJkkcfi+BpnBqWwxh0aw8MhViQy5ZtSJRIzzSxUyEDMZxbQePMCVqD0hPJRzbTCCKrCqDyvJ-fC-z8-SVmC5Njx0H4IqHayAlJeyOheScPQaUI7BsFo1MmbLfMbYieUM9FeNCnFGXxQIvQed8fBHMc7GoatagGZpcRGYxvK1Bs106jityCnrjL66ChN+YJVLGWl8w6XpfGm08zz0eaRiWgi2LWiACsgsKuluAIhrPQJRt6YxyT0UYFNMYwX2ta8xjunK0mekzygAWjfPsvWKuk3gnax9FdHo+hBic5okLDQhiGIgA */\nconst cheatCodeMachine = setup({\n types: {\n // typegen: {};\n context: {} as CheatCodeContext,\n events: {} as KeydownEvent,\n input: {} as CheatCodeMachineInput,\n },\n actions: {\n record: assign({\n typedKeys: ({ context, event }) => [...context.typedKeys, event.key],\n }),\n resetTypedKeys: assign({\n typedKeys: initialContext.typedKeys,\n }),\n },\n delays: {\n doneTyping: 2000,\n },\n guards: {\n cheatCodeEntered: ({ context }) => {\n return (\n Array.isArray(context.cheatCodeKeys) &&\n isEqual(\n takeRight(context.typedKeys, context.cheatCodeKeys.length),\n context.cheatCodeKeys,\n )\n );\n },\n },\n}).createMachine({\n context: ({ input }) => ({ ...initialContext, ...input }),\n id: 'cheatCodeMachine',\n initial: 'disabled',\n states: {\n disabled: {\n initial: 'idle',\n states: {\n idle: {\n always: {\n target: '#cheatCodeMachine.enabled',\n guard: 'cheatCodeEntered',\n actions: 'resetTypedKeys',\n },\n on: {\n keydown: {\n target: 'recording',\n actions: 'record',\n },\n },\n },\n recording: {\n after: {\n doneTyping: {\n target: '#cheatCodeMachine.disabled.idle',\n actions: ['resetTypedKeys'],\n reenter: true,\n },\n },\n always: {\n target: '#cheatCodeMachine.enabled',\n guard: 'cheatCodeEntered',\n actions: 'resetTypedKeys',\n },\n on: {\n keydown: {\n target: 'recording',\n actions: 'record',\n reenter: true,\n },\n },\n },\n },\n },\n enabled: {\n initial: 'idle',\n states: {\n idle: {\n always: {\n target: '#cheatCodeMachine.disabled',\n guard: 'cheatCodeEntered',\n actions: 'resetTypedKeys',\n },\n on: {\n keydown: {\n target: 'recording',\n actions: 'record',\n },\n },\n },\n recording: {\n after: {\n doneTyping: {\n target: '#cheatCodeMachine.enabled.idle',\n actions: ['resetTypedKeys'],\n reenter: true,\n },\n },\n always: {\n target: '#cheatCodeMachine.disabled',\n guard: 'cheatCodeEntered',\n actions: 'resetTypedKeys',\n },\n on: {\n keydown: {\n target: 'recording',\n actions: 'record',\n reenter: true,\n },\n },\n },\n },\n },\n },\n});\n\nexport function useCheatCode(cheatCodeKeys: string[]): boolean {\n const machineOpts = React.useMemo<{ input: CheatCodeMachineInput }>(\n () => ({ input: { cheatCodeKeys } }),\n [cheatCodeKeys],\n );\n\n const [state, send] = useMachine(cheatCodeMachine, machineOpts);\n\n React.useEffect(() => {\n const handleKeydownEvent = (event: KeyboardEvent) => {\n send(event as KeydownEvent);\n };\n\n window.addEventListener('keydown', handleKeydownEvent);\n\n return () => {\n window.removeEventListener('keydown', handleKeydownEvent);\n };\n }, [send]);\n\n return state.matches('enabled');\n}\n\nexport const useSecretCode = /* c8 ignore next */ useCheatCode;\n","export function isEqual<T>(array1: T[], array2: T[]): boolean {\n return JSON.stringify(array1) === JSON.stringify(array2);\n}\n\nexport function takeRight<T>(array: T[], n: number): T[] {\n if (n < 1) return [];\n return array.slice(-1 * n);\n}\n"],"mappings":"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","names":[]}