@moneypot/hub 1.3.0 → 1.4.1

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
@@ -73,3 +73,9 @@ You'll need an api key from your hub database:
73
73
  ```sql
74
74
  insert into hub.api_key default values returning key;
75
75
  ```
76
+
77
+ ## Changelog
78
+
79
+ ### 1.4.1
80
+
81
+ - Added `hubPutAlert` subscription
@@ -0,0 +1,22 @@
1
+ -- Let experience know when user successfully puts money into their balance
2
+ -- A put is a successful deposit
3
+
4
+ CREATE OR REPLACE FUNCTION notify_put() RETURNS TRIGGER AS $$
5
+ BEGIN
6
+ PERFORM pg_notify('hub:user:' || NEW.user_id || ':put',
7
+ json_build_object(
8
+ 'currency_key', NEW.currency_key,
9
+ 'experience_id', NEW.experience_id,
10
+ 'mp_transfer_id', NEW.mp_transfer_id
11
+ )::text);
12
+ RETURN NEW;
13
+ END;
14
+ $$ LANGUAGE plpgsql;
15
+
16
+ DROP TRIGGER IF EXISTS notify_put_trigger ON hub.deposit;
17
+
18
+ CREATE TRIGGER notify_put_trigger
19
+ AFTER INSERT ON hub.deposit
20
+ FOR EACH ROW
21
+ EXECUTE FUNCTION notify_put();
22
+
@@ -0,0 +1 @@
1
+ export declare const HubPutAlertPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,56 @@
1
+ import { context, lambda } from "postgraphile/grafast";
2
+ import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
+ import { jsonParse } from "postgraphile/@dataplan/json";
4
+ import { listenWithFilter } from "./listen-with-filter.js";
5
+ export const HubPutAlertPlugin = makeExtendSchemaPlugin(() => {
6
+ return {
7
+ typeDefs: gql `
8
+ extend type Subscription {
9
+ hubPutAlert: HubPutAlertPayload
10
+ }
11
+
12
+ type HubPutAlertPayload {
13
+ currencyKey: String!
14
+ mpTransferId: UUID!
15
+ }
16
+ `,
17
+ plans: {
18
+ Subscription: {
19
+ hubPutAlert: {
20
+ subscribePlan(_$root) {
21
+ const $pgSubscriber = context().get("pgSubscriber");
22
+ const $identity = context().get("identity");
23
+ const $channelKey = lambda($identity, (identity) => {
24
+ if (identity?.kind === "user") {
25
+ return `hub:user:${identity.session.user_id}:put`;
26
+ }
27
+ else {
28
+ return "";
29
+ }
30
+ });
31
+ return listenWithFilter($pgSubscriber, $channelKey, jsonParse, $identity, (item, identity) => {
32
+ if (identity?.kind !== "user") {
33
+ return false;
34
+ }
35
+ else {
36
+ return (identity.session.experience_id ===
37
+ JSON.parse(item).experience_id);
38
+ }
39
+ });
40
+ },
41
+ plan($event) {
42
+ return $event;
43
+ },
44
+ },
45
+ },
46
+ HubPutAlertPayload: {
47
+ currencyKey($event) {
48
+ return $event.get("currency_key");
49
+ },
50
+ mpTransferId($event) {
51
+ return $event.get("mp_transfer_id");
52
+ },
53
+ },
54
+ },
55
+ };
56
+ });
@@ -0,0 +1,22 @@
1
+ import { __ItemStep, ExecutionDetails, GrafastResultStreamList } from "postgraphile/grafast";
2
+ import { GrafastSubscriber } from "postgraphile/grafast";
3
+ import { Step } from "postgraphile/grafast";
4
+ export declare class ListenWithFilterStep<TTopics extends {
5
+ [topic: string]: any;
6
+ }, TTopic extends keyof TTopics, TPayloadStep extends Step, TFilterInput> extends Step<TTopics[TTopic][]> {
7
+ itemPlan: (itemPlan: __ItemStep<TTopics[TTopic]>) => TPayloadStep;
8
+ filterFn: (item: any, filterInput: TFilterInput) => boolean;
9
+ static $$export: {
10
+ moduleName: string;
11
+ exportName: string;
12
+ };
13
+ isSyncAndSafe: boolean;
14
+ private pubsubDep;
15
+ private topicDep;
16
+ private filterInputDep;
17
+ constructor(pubsubOrPlan: Step<GrafastSubscriber<TTopics> | null> | GrafastSubscriber<TTopics> | null, topicOrPlan: Step<TTopic> | string, itemPlan: ((itemPlan: __ItemStep<TTopics[TTopic]>) => TPayloadStep) | undefined, filterInputPlan: Step<TFilterInput>, filterFn: (item: any, filterInput: TFilterInput) => boolean);
18
+ execute({ indexMap, values, stream, }: ExecutionDetails<readonly [GrafastSubscriber<TTopics>, TTopic]>): GrafastResultStreamList<TTopics[TTopic]>;
19
+ }
20
+ export declare function listenWithFilter<TTopics extends {
21
+ [topic: string]: any;
22
+ }, TTopic extends keyof TTopics, TPayloadStep extends Step, TFilterInput>(pubsubOrPlan: Step<GrafastSubscriber<TTopics> | null> | GrafastSubscriber<TTopics> | null, topicOrPlan: Step<TTopic> | string, itemPlan: ((itemPlan: __ItemStep<TTopics[TTopic]>) => TPayloadStep) | undefined, filterInputPlan: Step<TFilterInput>, filterFn: (item: any, filterInput: TFilterInput) => boolean): ListenWithFilterStep<TTopics, TTopic, TPayloadStep, TFilterInput>;
@@ -0,0 +1,61 @@
1
+ import { constant, isDev, isExecutableStep, SafeError, } from "postgraphile/grafast";
2
+ import { Step } from "postgraphile/grafast";
3
+ export class ListenWithFilterStep extends Step {
4
+ itemPlan;
5
+ filterFn;
6
+ static $$export = {
7
+ moduleName: "grafast",
8
+ exportName: "ListenWithFilterStep",
9
+ };
10
+ isSyncAndSafe = true;
11
+ pubsubDep;
12
+ topicDep;
13
+ filterInputDep;
14
+ constructor(pubsubOrPlan, topicOrPlan, itemPlan = ($item) => $item, filterInputPlan, filterFn) {
15
+ super();
16
+ this.itemPlan = itemPlan;
17
+ this.filterFn = filterFn;
18
+ const $topic = typeof topicOrPlan === "string" ? constant(topicOrPlan) : topicOrPlan;
19
+ const $pubsub = isExecutableStep(pubsubOrPlan)
20
+ ? pubsubOrPlan
21
+ : constant(pubsubOrPlan, false);
22
+ this.pubsubDep = this.addDependency($pubsub);
23
+ this.topicDep = this.addDependency($topic);
24
+ this.filterInputDep = this.addDependency(filterInputPlan);
25
+ }
26
+ execute({ indexMap, values, stream, }) {
27
+ if (!stream) {
28
+ throw new Error("ListenWithFilterStep must be streamed, never merely executed");
29
+ }
30
+ const pubsubValue = values[this.pubsubDep];
31
+ const topicValue = values[this.topicDep];
32
+ const filterInputValue = values[this.filterInputDep];
33
+ return indexMap((i) => {
34
+ const pubsub = pubsubValue.at(i);
35
+ if (!pubsub) {
36
+ throw new SafeError("Subscription not supported", isDev
37
+ ? {
38
+ hint: `${this.dependencies[this.pubsubDep]} did not provide a GrafastSubscriber; perhaps you forgot to add the relevant property to context?`,
39
+ }
40
+ : {});
41
+ }
42
+ const topic = topicValue.at(i);
43
+ const filterInput = filterInputValue.at(i);
44
+ const origStream = pubsub.subscribe(topic);
45
+ const filterFn = this.filterFn;
46
+ return {
47
+ [Symbol.asyncIterator]: async function* () {
48
+ const iterator = await origStream;
49
+ for await (const item of iterator) {
50
+ if (filterFn(item, filterInput)) {
51
+ yield item;
52
+ }
53
+ }
54
+ },
55
+ };
56
+ });
57
+ }
58
+ }
59
+ export function listenWithFilter(pubsubOrPlan, topicOrPlan, itemPlan = ($item) => $item, filterInputPlan, filterFn) {
60
+ return new ListenWithFilterStep(pubsubOrPlan, topicOrPlan, itemPlan, filterInputPlan, filterFn);
61
+ }
@@ -24,6 +24,7 @@ import { HubCreateHashChainPlugin } from "../hash-chain/plugins/hub-create-hash-
24
24
  import { HubBadHashChainErrorPlugin } from "../hash-chain/plugins/hub-bad-hash-chain-error.js";
25
25
  import { HubUserActiveHashChainPlugin } from "../hash-chain/plugins/hub-user-active-hash-chain.js";
26
26
  import { HubOutcomeInputNonNullFieldsPlugin } from "../plugins/hub-outcome-input-non-null-fields.js";
27
+ import { HubPutAlertPlugin } from "../plugins/hub-put-alert.js";
27
28
  export const requiredPlugins = [
28
29
  SmartTagsPlugin,
29
30
  IdToNodeIdPlugin,
@@ -32,6 +33,7 @@ export const requiredPlugins = [
32
33
  HubCurrentXPlugin,
33
34
  HubWithdrawPlugin,
34
35
  HubBalanceAlertPlugin,
36
+ HubPutAlertPlugin,
35
37
  HubUserBalanceByCurrencyPlugin,
36
38
  HubAddCasinoPlugin,
37
39
  ValidateCasinoFieldsPlugin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moneypot/hub",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "author": "moneypot.com",
5
5
  "homepage": "https://moneypot.com/hub",
6
6
  "keywords": [