Skip to content

Commit

Permalink
Implement plugins storage
Browse files Browse the repository at this point in the history
  • Loading branch information
ziulev committed Sep 10, 2021
1 parent b8adf6c commit bded6e4
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 29 deletions.
13 changes: 8 additions & 5 deletions index.js
Expand Up @@ -9,6 +9,7 @@ import {
EventsProvider,
SettingsProvider,
HistoryProvider,
StorageProvider,
} from './src/providers';

// TODO: Check
Expand All @@ -20,11 +21,13 @@ const AppWithModules = () => (
<ApiProvider>
<SettingsProvider>
<HistoryProvider>
<EventsProvider>
<ThemeProvider>
<QueryPanel />
</ThemeProvider>
</EventsProvider>
<StorageProvider>
<EventsProvider>
<ThemeProvider>
<QueryPanel />
</ThemeProvider>
</EventsProvider>
</StorageProvider>
</HistoryProvider>
</SettingsProvider>
</ApiProvider>
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -19,7 +19,7 @@
},
"dependencies": {
"@react-native-async-storage/async-storage": "^1.13.2",
"@spotter-app/core": "^1.1.1",
"@spotter-app/core": "^1.1.2",
"@types/math-expression-evaluator": "^1.2.0",
"@types/mathjs": "^6.0.11",
"buffer": "^6.0.3",
Expand Down
24 changes: 21 additions & 3 deletions src/core/helpers.ts
@@ -1,4 +1,4 @@
import { InputCommand, InputCommandType, OutputCommandType } from '@spotter-app/core';
import { InputCommand, InputCommandType, OutputCommandType, Storage } from '@spotter-app/core';
import { History } from '../providers';
import { INTERNAL_PLUGIN_KEY } from './constants';
import {
Expand Down Expand Up @@ -48,15 +48,21 @@ export const handleCommands = (commands: PluginOutputCommand[]): HandleCommandRe
? [...(acc.optionsToSet ?? []), ...handleCommandResult.optionsToSet]
: acc.optionsToSet;

const dataToStorage: Storage | null = handleCommandResult.dataToStorage
? {...(acc.optionsToSet ?? []), ...handleCommandResult.dataToStorage}
: acc.dataToStorage;

return {
optionsToRegister,
optionsToSet,
queryToSet: handleCommandResult.queryToSet ?? acc.queryToSet,
dataToStorage,
};
}, {
optionsToRegister: null,
optionsToSet: null,
queryToSet: null,
dataToStorage: null,
});
};

Expand All @@ -65,6 +71,7 @@ export const handleCommand = (command: PluginOutputCommand): HandleCommandResult
optionsToRegister: null,
optionsToSet: null,
queryToSet: null,
dataToStorage: null
};

if (command.type === OutputCommandType.registerOptions) {
Expand Down Expand Up @@ -92,6 +99,15 @@ export const handleCommand = (command: PluginOutputCommand): HandleCommandResult
};
}

if (command.type === OutputCommandType.setStorage) {
return {
...initialData,
dataToStorage: {
[command.plugin]: command.value,
}
};
}

return initialData;
};

Expand All @@ -116,6 +132,7 @@ export const onQueryExternalPluginAction = async (
option: ExternalPluginOption,
query: string,
shell: SpotterShell,
storage: Storage,
): Promise<PluginOutputCommand[]> => {
if (!option || !option.queryAction) {
return [];
Expand All @@ -124,7 +141,7 @@ export const onQueryExternalPluginAction = async (
const command: InputCommand = {
type: InputCommandType.onQueryAction,
queryAction: option.queryAction,
storage: {},
storage,
query
};

Expand All @@ -134,10 +151,11 @@ export const onQueryExternalPluginAction = async (
export const triggerOnInitForPlugin = async (
plugin: string | InternalPluginLifecycle,
shell: SpotterShell,
storage: Storage,
): Promise<PluginOutputCommand[]> => {
const command: InputCommand = {
type: InputCommandType.onInit,
storage: {},
storage,
};

if (isInternalPlugin(plugin)) {
Expand Down
3 changes: 2 additions & 1 deletion src/core/interfaces.ts
@@ -1,4 +1,4 @@
import { Option, OutputCommand } from '@spotter-app/core/dist/interfaces';
import { Option, OutputCommand, Storage } from '@spotter-app/core/dist/interfaces';
import { INTERNAL_PLUGIN_KEY } from './constants';

export interface SpotterApi {
Expand Down Expand Up @@ -178,4 +178,5 @@ export interface HandleCommandResult {
optionsToRegister: null | RegisteredOptions,
optionsToSet: null | ExternalPluginOption[],
queryToSet: null | string,
dataToStorage: null | Storage,
}
42 changes: 34 additions & 8 deletions src/providers/events.provider.tsx
Expand Up @@ -28,6 +28,7 @@ import {
triggerOnInitForPlugin,
} from '../core/helpers';
import { useHistory } from './history.provider';
import { useStorage } from '.';

type Context = {
onQuery: (query: string) => Promise<void>,
Expand Down Expand Up @@ -70,6 +71,7 @@ export const EventsProvider: FC<{}> = (props) => {
const { api } = useApi();
const { getSettings, addPlugin, removePlugin } = useSettings();
const { getHistory, increaseHistory } = useHistory();
const { getStorage, patchStorage } = useStorage();

const [ query, setQuery ] = useState<string>('');
const [ options, setOptions ] = useState<Options>([]);
Expand All @@ -84,9 +86,14 @@ export const EventsProvider: FC<{}> = (props) => {

const registerPlugin = async (plugin: string) => {
addPlugin(plugin);
const commands = await triggerOnInitForPlugin(plugin, api.shell);
const storage = await getStorage();
const commands = await triggerOnInitForPlugin(plugin, api.shell, storage);

const { optionsToRegister } = handleCommands(commands);
const { optionsToRegister, dataToStorage } = handleCommands(commands);

if (dataToStorage) {
patchStorage(dataToStorage);
}

if (optionsToRegister) {
setRegisteredOptions(prevOptions => ({
Expand Down Expand Up @@ -115,6 +122,7 @@ export const EventsProvider: FC<{}> = (props) => {

const onInit = async () => {
const settings = await getSettings();
const storage = await getStorage();

registerGlobalHotkeys(settings);

Expand All @@ -125,7 +133,7 @@ export const EventsProvider: FC<{}> = (props) => {
async (asyncAcc, plugin) => {
return [
...(await asyncAcc),
...(await triggerOnInitForPlugin(plugin, api.shell)),
...(await triggerOnInitForPlugin(plugin, api.shell, storage)),
]
},
Promise.resolve([]),
Expand All @@ -134,8 +142,13 @@ export const EventsProvider: FC<{}> = (props) => {
const {
optionsToRegister,
optionsToSet,
dataToStorage
} = handleCommands(externalPluginsCommands);

if (dataToStorage) {
patchStorage(dataToStorage)
}

if (optionsToSet) {
const history = await getHistory();
setOptions(
Expand Down Expand Up @@ -208,11 +221,17 @@ export const EventsProvider: FC<{}> = (props) => {
setSelectedOption(option);
setQuery('');

const storage = await getStorage();
const commands: PluginOutputCommand[] = isExternalPluginOption(option)
? await onQueryExternalPluginAction(option, '', api.shell)
? await onQueryExternalPluginAction(option, '', api.shell, storage)
: await onQueryInternalPluginAction(option, '');

const { optionsToSet } = handleCommands(commands);
const { optionsToSet, dataToStorage } = handleCommands(commands);

if (dataToStorage) {
patchStorage(dataToStorage);
}

const history = await getHistory();
increaseHistory(getHistoryPath(option, null));
setOptions(
Expand All @@ -238,11 +257,17 @@ export const EventsProvider: FC<{}> = (props) => {
setQuery(q);

if (selectedOption) {
const storage = await getStorage();
const commands: PluginOutputCommand[] = isExternalPluginOption(selectedOption)
? await onQueryExternalPluginAction(selectedOption, q, api.shell)
? await onQueryExternalPluginAction(selectedOption, q, api.shell, storage)
: await onQueryInternalPluginAction(selectedOption, q);

const { optionsToSet } = handleCommands(commands);
const { optionsToSet, dataToStorage } = handleCommands(commands);

if (dataToStorage) {
patchStorage(dataToStorage);
}

const history = await getHistory();
setOptions(
sortOptions(
Expand Down Expand Up @@ -317,11 +342,12 @@ export const EventsProvider: FC<{}> = (props) => {
};

const onSubmitExternalOption = async (option: ExternalPluginOption) => {
const storage = await getStorage();
const command: InputCommand = {
type: InputCommandType.onAction,
action: option.action ?? '',
query,
storage: {},
storage,
}

const commands: OutputCommand[] = await api.shell
Expand Down
1 change: 1 addition & 0 deletions src/providers/index.ts
Expand Up @@ -3,3 +3,4 @@ export * from './api.provider';
export * from './events.provider';
export * from './settings.provider';
export * from './history.provider';
export * from './storage.provider';
60 changes: 60 additions & 0 deletions src/providers/storage.provider.tsx
@@ -0,0 +1,60 @@
import { Storage } from '@spotter-app/core';
import React, { FC, useRef } from 'react';
import { useApi } from './api.provider';

const PLUGINS_STORAGE_KEY = 'PLUGINS_STORAGE';

type Context = {
getStorage: () => Promise<Storage>;
patchStorage: (data: Storage) => void;
};

const context: Context = {
getStorage: () => Promise.resolve({}),
patchStorage: () => null,
}

export const StorageContext = React.createContext<Context>(context);

export const StorageProvider: FC<{}> = (props) => {

const { api } = useApi();

const cachedStorage = useRef<Storage>();

const getStorage = async () => {
if (cachedStorage.current) {
return cachedStorage.current;
}

const storage = await api.storage.getItem<Storage>(PLUGINS_STORAGE_KEY);
if (!storage) {
return {};
}

cachedStorage.current = storage;
return storage;
}

const patchStorage = async (data: Storage) => {
const storage = await getStorage();
const updatedStorage = {
...storage,
...data,
};

cachedStorage.current = updatedStorage;
api.storage.setItem(PLUGINS_STORAGE_KEY, updatedStorage);
}

return (
<StorageContext.Provider value={{
getStorage,
patchStorage,
}}>
{props.children}
</StorageContext.Provider>
);
};

export const useStorage = () => React.useContext(StorageContext);
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -1655,10 +1655,10 @@
dependencies:
"@sinonjs/commons" "^1.7.0"

"@spotter-app/core@^1.1.1":
"integrity" "sha512-juH/Z8ggAxQ0i97S1HhDRtIC9/2FtVC/glSqKUF6RsfZ+epCFhVFmJlUZclYCELkN/7krmxC/gO5EWuHp6keSQ=="
"resolved" "https://registry.npmjs.org/@spotter-app/core/-/core-1.1.1.tgz"
"version" "1.1.1"
"@spotter-app/core@^1.1.2":
"integrity" "sha512-hFNePXBHlzaOMUZQOFHbeUYhwTooA1zHmR9tqwjF2epkBsd1L3HpXIRwOYlE9XF8FYhP5ur+DkrcurQg0klAHw=="
"resolved" "https://registry.npmjs.org/@spotter-app/core/-/core-1.1.2.tgz"
"version" "1.1.2"

"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
"version" "7.1.12"
Expand Down

0 comments on commit bded6e4

Please sign in to comment.