Files
directus/api/src/messenger.ts
Rijk van Zanten 32dd709778 Insights 2.0 (#14096)
* query function added to list

* dashboard reading query, adding to object

* typecasting of filter vals needed still

* numbers accepting strings too

* json-to-graphql-query => devD

* fixed unneeded return in list index.ts

* stitching and calling but not actually calling

* calls on panel change

* query object += new panel before dashboard save

* uuid generated in app not api

* fixed panel ids in query

* fixed the tests I just wrote

* passing the query data down!

* list showing data

* objDiff test moved to test

* metric bug fixes + data

* dashboard logic

* time series conversion started

* timeseries GQL query almost there

* query querying

* chart loading

* aggregate handling improved

* error handling for aggregate+filter errors

* removed query on empty queryObj

* maybe more error handling

* more error handling working

* improvements to erorr handling

* stitchGQL() error return type corrected

* added string fields to COUNT

* pushing up but needs work

* not an endless recursion

* its not pretty but it works.

* throws an error

* system collections supported

* refactor to solve some errors

* loading correct

* metric function fixed

* data loading but not blocking rendering

* removed redundant code.

* relational fields

* deep nesting relations

* options.precision has a default

* relational fields fix. (thanks azri)

* the limit

* limit and time series

* range has a default

* datat to workspace

* v-if

* panels loading

* workspaces dont get data anymore

* package.json

* requested changes

* loading

* get groups util

* timeseries => script setup

* list => script setup

* metric => script setup

* label => script setup

* declare optional props

* loadingPanels: only loading spinner on loading panels

* remove unneeded parseDate!!

* applyDataToPanels tests

* -.only

* remove unneeded steps

* processQuery tests

* tests

* removed unused var

* jest.config and some queryCaller tests

* one more test

* query tests

* typo

* clean up

* fix some but not all bugs

* bugs from merge fixed

* Start cleaning up 🧹

* Refactor custom input type

* Small tweaks in list index

* Cleanup imports

* Require Query object to be returned from query prop

* Tweak return statement

* Fix imports

* Cleanup metric watch effect

* Tweaks tweaks tweaks

* Don't rely on options, simplify fetch logic

* Add paths to validation errors

* [WIP] Start handling things in the store

* Rework query fetching logic into store

* Clean up data passing

* Use composition setup for insights store

* Remove outdated

* Fix missing return

* Allow batch updating in REST API

Allows sending an array of partial items to the endpoints, updating all to their own values

* Add batch update to graphql

* Start integrating edits

* Readd clear

* Add deletion

* Add duplication

* Finish create flow

* Resolve cache refresh on panel config

* Prevent warnings about component name

* Improve loading state

* Finalize dashboard overhaul

* Add auto-refresh sidebar detail

* Add efficient panel reloading

* Set/remove errors on succeeded requests

* Move options rendering to shared

* Fix wrong imports, render options in app

* Selectively reload panels with changed variables

* Ensure newly added panels don't lose data

* Only refresh panel if data query changed

* Never use empty filter object in metric query

* Add default value support to variable panel

* Centralize no-data state

* Only reload data on var change when query is altered

* Fix build

* Fix time series order

* Remove unused utils

* Remove no-longer-used logic

* Mark batch update result as non-nullable in GraphQL schema

* Interim flows fix

* Skip parsing undefined keys

* Refresh insights dashboard when discarding changes

* Don't submit primary key when updating batch

* Handle null prop field better

* Tweak panel padding

Co-authored-by: jaycammarano <jay.cammarano@gmail.com>
Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
Co-authored-by: ian <licitdev@gmail.com>
2022-06-27 15:26:42 -04:00

81 lines
2.0 KiB
TypeScript

import { parseJSON } from '@directus/shared/utils';
import IORedis from 'ioredis';
import env from './env';
import { getConfigFromEnv } from './utils/get-config-from-env';
export type MessengerSubscriptionCallback = (payload: Record<string, any>) => void;
export interface Messenger {
publish: (channel: string, payload: Record<string, any>) => void;
subscribe: (channel: string, callback: MessengerSubscriptionCallback) => void;
unsubscribe: (channel: string) => void;
}
export class MessengerMemory implements Messenger {
handlers: Record<string, MessengerSubscriptionCallback>;
constructor() {
this.handlers = {};
}
publish(channel: string, payload: Record<string, any>) {
this.handlers[channel]?.(payload);
}
subscribe(channel: string, callback: MessengerSubscriptionCallback) {
this.handlers[channel] = callback;
}
unsubscribe(channel: string) {
delete this.handlers[channel];
}
}
export class MessengerRedis implements Messenger {
namespace: string;
pub: IORedis.Redis;
sub: IORedis.Redis;
constructor() {
const config = getConfigFromEnv('MESSENGER_REDIS');
this.pub = new IORedis(env.MESSENGER_REDIS ?? config);
this.sub = new IORedis(env.MESSENGER_REDIS ?? config);
this.namespace = env.MESSENGER_NAMESPACE ?? 'directus';
}
publish(channel: string, payload: Record<string, any>) {
this.pub.publish(`${this.namespace}:${channel}`, JSON.stringify(payload));
}
subscribe(channel: string, callback: MessengerSubscriptionCallback) {
this.sub.subscribe(`${this.namespace}:${channel}`);
this.sub.on('message', (messageChannel, payloadString) => {
const payload = parseJSON(payloadString);
if (messageChannel === `${this.namespace}:${channel}`) {
callback(payload);
}
});
}
unsubscribe(channel: string) {
this.sub.unsubscribe(`${this.namespace}:${channel}`);
}
}
let messenger: Messenger;
export function getMessenger() {
if (messenger) return messenger;
if (env.MESSENGER_STORE === 'redis') {
messenger = new MessengerRedis();
} else {
messenger = new MessengerMemory();
}
return messenger;
}