@nu-art/push-pub-sub-backend 0.401.9 → 0.500.0

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.
@@ -1,3 +1,3 @@
1
- export declare const ModulePackBE_PushPubSub: (import("../modules/ModuleBE_PushSessionDB.js").ModuleBE_PushSessionDB_Class | import("../modules/ModuleBE_PushSubscriptionDB.js").ModuleBE_PushSubscriptionDB_Class | import("@nu-art/thunderstorm-backend").ModuleBE_BaseApi_Class<import("@nu-art/push-pub-sub-shared/push-subscription/types").DBProto_PushSubscription> | import("../modules/ModuleBE_PushMessagesHistoryDB.js").ModuleBE_PushMessagesHistoryDB_Class | import("../modules/ModuleBE_PushPubSub.js").ModuleBE_PushPubSub_Class)[];
1
+ export declare const ModulePackBE_PushPubSub: (import("../modules/ModuleBE_PushSessionDB.js").ModuleBE_PushSessionDB_Class | import("../modules/ModuleBE_PushSubscriptionDB.js").ModuleBE_PushSubscriptionDB_Class | import("@nu-art/db-api-backend").ModuleBE_BaseApi_Class<import("@nu-art/push-pub-sub-shared/push-subscription/types").DatabaseDef_PushSubscription & import("@nu-art/db-api-shared").DB_Prototype> | import("../modules/ModuleBE_PushMessagesHistoryDB.js").ModuleBE_PushMessagesHistoryDB_Class | import("../modules/ModuleBE_PushPubSub.js").ModuleBE_PushPubSub_Class)[];
2
2
  export * from '../modules/ModuleBE_PushPubSub.js';
3
3
  export * from '../modules/PushKey.js';
@@ -1,5 +1,5 @@
1
1
  import { DefaultDef_Group } from '@nu-art/permissions-shared';
2
- import { DefaultDef_Domain, DefaultDef_Package } from '@nu-art/permissions-backend/types';
2
+ import { DefaultDef_Domain, DefaultDef_Package } from '@nu-art/permissions-backend';
3
3
  export declare const PermissionsDomain_PushMessages: Readonly<DefaultDef_Domain>;
4
4
  export declare const PermissionsGroup_PushMessanger: Readonly<DefaultDef_Group>;
5
5
  export declare const PermissionsPackage_PushMessages: DefaultDef_Package;
@@ -1,6 +1,6 @@
1
- import { CreateDefaultAccessLevels, DefaultAccessLevel_Admin } from '@nu-art/permissions-shared';
1
+ import { CreateDefaultAccessLevels, DefaultAccessLevel_Admin, toPermissionAccessLevelId, toPermissionDomainId, toPermissionGroupId } from '@nu-art/permissions-shared';
2
2
  import { ApiDef_PushMessages } from '@nu-art/push-pub-sub-shared';
3
- import { Domain_Developer } from '@nu-art/permissions-backend/permissions';
3
+ import { Domain_Developer } from '@nu-art/permissions-backend';
4
4
  import { ModuleBE_PushSubscriptionAPI } from '../modules/ModuleBE_PushSubscriptionDB.js';
5
5
  import { _values } from '@nu-art/ts-common';
6
6
  const Domain_PushMessages_ID = 'ce2e840bb639c34887ae19c2c7c82c11';
@@ -9,28 +9,28 @@ const DefaultAccessLevel_Active = Object.freeze({ name: 'Active', value: 0 });
9
9
  const DefaultAccessLevel_Tester = Object.freeze({ name: 'Tester', value: 600 });
10
10
  const accessLevels = [{ ...DefaultAccessLevel_Passive }, { ...DefaultAccessLevel_Active }, { ...DefaultAccessLevel_Tester }];
11
11
  const _PermissionsDomain_PushMessages = {
12
- _id: Domain_PushMessages_ID,
12
+ _id: toPermissionDomainId(Domain_PushMessages_ID),
13
13
  namespace: 'Push Messages',
14
14
  dbNames: [],
15
- levels: CreateDefaultAccessLevels(Domain_PushMessages_ID, accessLevels),
15
+ levels: CreateDefaultAccessLevels(Domain_PushMessages_ID, accessLevels).map(level => ({ ...level, _id: toPermissionAccessLevelId(level._id) })),
16
16
  customApis: [
17
- ..._values(ModuleBE_PushSubscriptionAPI.apiDef.v1).map(api => {
17
+ ..._values(ModuleBE_PushSubscriptionAPI.crudApiDef).map(api => {
18
18
  return {
19
19
  path: api.path,
20
20
  accessLevel: DefaultAccessLevel_Admin.name,
21
21
  domainId: Domain_Developer._id
22
22
  };
23
23
  }),
24
- { path: ApiDef_PushMessages.v1.test.path, accessLevel: DefaultAccessLevel_Admin.name, domainId: Domain_Developer._id },
25
- { path: ApiDef_PushMessages.v1.register.path, accessLevel: DefaultAccessLevel_Active.name },
26
- { path: ApiDef_PushMessages.v1.registerAll.path, accessLevel: DefaultAccessLevel_Active.name },
27
- { path: ApiDef_PushMessages.v1.unregister.path, accessLevel: DefaultAccessLevel_Active.name },
24
+ { path: ApiDef_PushMessages.test.path, accessLevel: DefaultAccessLevel_Admin.name, domainId: Domain_Developer._id },
25
+ { path: ApiDef_PushMessages.register.path, accessLevel: DefaultAccessLevel_Active.name },
26
+ { path: ApiDef_PushMessages.registerAll.path, accessLevel: DefaultAccessLevel_Active.name },
27
+ { path: ApiDef_PushMessages.unregister.path, accessLevel: DefaultAccessLevel_Active.name },
28
28
  ]
29
29
  };
30
30
  export const PermissionsDomain_PushMessages = Object.freeze(_PermissionsDomain_PushMessages);
31
31
  const PermissionsGroupId_ProactivePushMessanger = '7f2c8925a6fdd2bcb9be3c1c0932deef';
32
32
  const _PermissionsGroup_ProactivePushMessanger = {
33
- _id: PermissionsGroupId_ProactivePushMessanger,
33
+ _id: toPermissionGroupId(PermissionsGroupId_ProactivePushMessanger),
34
34
  name: 'Push Messanger',
35
35
  uiLabel: 'Push Messenger',
36
36
  accessLevels: {
@@ -1,8 +1,7 @@
1
- import { DBApiConfigV3, ModuleBE_BaseDB } from '@nu-art/thunderstorm-backend';
2
- import { DBProto_PushMessagesHistory } from '@nu-art/push-pub-sub-shared/push-messages-history/index';
3
- type Config = DBApiConfigV3<DBProto_PushMessagesHistory> & {};
4
- export declare class ModuleBE_PushMessagesHistoryDB_Class extends ModuleBE_BaseDB<DBProto_PushMessagesHistory, Config> {
1
+ import type { DB_Prototype } from '@nu-art/db-api-shared';
2
+ import { ModuleBE_BaseDB } from '@nu-art/db-api-backend';
3
+ import { DatabaseDef_PushMessagesHistory } from '@nu-art/push-pub-sub-shared/push-messages-history/index';
4
+ export declare class ModuleBE_PushMessagesHistoryDB_Class extends ModuleBE_BaseDB<DatabaseDef_PushMessagesHistory & DB_Prototype, object> {
5
5
  constructor();
6
6
  }
7
7
  export declare const ModuleBE_PushMessagesHistoryDB: ModuleBE_PushMessagesHistoryDB_Class;
8
- export {};
@@ -1,4 +1,4 @@
1
- import { ModuleBE_BaseDB, } from '@nu-art/thunderstorm-backend';
1
+ import { ModuleBE_BaseDB } from '@nu-art/db-api-backend';
2
2
  import { DBDef_PushMessagesHistory } from '@nu-art/push-pub-sub-shared/push-messages-history/index';
3
3
  export class ModuleBE_PushMessagesHistoryDB_Class extends ModuleBE_BaseDB {
4
4
  constructor() {
@@ -1,7 +1,14 @@
1
1
  import { Module } from '@nu-art/ts-common';
2
2
  import { FirebaseType_BatchResponse } from '@nu-art/firebase-backend';
3
- import { PushMessage, Request_PushRegister } from '@nu-art/push-pub-sub-shared';
4
- import { OnCleanupSchedulerAct } from '@nu-art/thunderstorm-backend';
3
+ import { API_PushMessages, PushMessage } from '@nu-art/push-pub-sub-shared';
4
+ export type CleanupDetails = {
5
+ cleanup: () => Promise<void>;
6
+ interval: number;
7
+ moduleKey: string;
8
+ };
9
+ export interface OnCleanupSchedulerAct {
10
+ __onCleanupSchedulerAct: () => CleanupDetails;
11
+ }
5
12
  import { Message } from 'firebase-admin/messaging';
6
13
  type Config = {
7
14
  messageLengthLimit: number;
@@ -12,7 +19,13 @@ export declare class ModuleBE_PushPubSub_Class extends Module<Config> implements
12
19
  private messaging;
13
20
  constructor();
14
21
  protected init(): void;
15
- register: (body: Request_PushRegister) => Promise<void>;
22
+ test(body: {
23
+ message: PushMessage<any, any, any>;
24
+ }): Promise<void>;
25
+ register(body: API_PushMessages['register']['Body']): Promise<API_PushMessages['register']['Response']>;
26
+ unregister(body: API_PushMessages['unregister']['Body']): Promise<API_PushMessages['unregister']['Response']>;
27
+ registerAll(body: API_PushMessages['registerAll']['Body']): Promise<API_PushMessages['registerAll']['Response']>;
28
+ private processRegistration;
16
29
  pushToKey: <MessageType extends PushMessage<any, any, any>>(message: MessageType) => Promise<void>;
17
30
  sendMessage: (messages: Message[]) => Promise<{
18
31
  response: FirebaseType_BatchResponse;
@@ -15,191 +15,255 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
19
+ var useValue = arguments.length > 2;
20
+ for (var i = 0; i < initializers.length; i++) {
21
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
22
+ }
23
+ return useValue ? value : void 0;
24
+ };
25
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
26
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
27
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
28
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
29
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
30
+ var _, done = false;
31
+ for (var i = decorators.length - 1; i >= 0; i--) {
32
+ var context = {};
33
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
34
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
35
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
36
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
37
+ if (kind === "accessor") {
38
+ if (result === void 0) continue;
39
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
40
+ if (_ = accept(result.get)) descriptor.get = _;
41
+ if (_ = accept(result.set)) descriptor.set = _;
42
+ if (_ = accept(result.init)) initializers.unshift(_);
43
+ }
44
+ else if (_ = accept(result)) {
45
+ if (kind === "field") initializers.unshift(_);
46
+ else descriptor[key] = _;
47
+ }
48
+ }
49
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
50
+ done = true;
51
+ };
18
52
  import { arrayToMap, batchActionParallel, compare, currentTimeMillis, Day, filterDuplicates, filterKeys, KB, LogLevel, Module } from '@nu-art/ts-common';
19
53
  import { ModuleBE_Firebase } from '@nu-art/firebase-backend';
20
54
  import { ApiDef_PushMessages } from '@nu-art/push-pub-sub-shared';
21
- import { addRoutes, createBodyServerApi } from '@nu-art/thunderstorm-backend';
55
+ import { ApiHandler, HttpServer } from '@nu-art/http-server';
22
56
  import { MemKey_AccountId } from '@nu-art/user-account-backend';
23
57
  import { ModuleBE_PushSessionDB } from './ModuleBE_PushSessionDB.js';
24
58
  import { ModuleBE_PushSubscriptionDB } from './ModuleBE_PushSubscriptionDB.js';
25
59
  import { ModuleBE_PushMessagesHistoryDB } from './ModuleBE_PushMessagesHistoryDB.js';
26
60
  import { HttpCodes } from '@nu-art/ts-common/core/exceptions/http-codes';
27
- export class ModuleBE_PushPubSub_Class extends Module {
28
- // private pushSessions!: FirestoreCollection<DB_PushSession>;
29
- // private topics!: FirestoreCollection<DB_PushSubscription>;
30
- messaging;
31
- constructor() {
32
- super();
33
- this.setMinLevel(LogLevel.Verbose);
34
- this.setDefaultConfig({ messageLengthLimit: 10 * KB });
35
- }
36
- init() {
37
- super.init();
38
- const session = ModuleBE_Firebase.createAdminSession();
39
- this.messaging = session.getMessaging();
40
- addRoutes([
41
- createBodyServerApi(ApiDef_PushMessages.v1.test, (r) => this.pushToKey(r.message)),
42
- createBodyServerApi(ApiDef_PushMessages.v1.register, this.register),
43
- createBodyServerApi(ApiDef_PushMessages.v1.unregister, this.register),
44
- createBodyServerApi(ApiDef_PushMessages.v1.registerAll, this.register)
45
- ]);
46
- }
47
- register = async (body) => {
48
- const accountId = MemKey_AccountId.get();
49
- const session = {
50
- firebaseToken: body.firebaseToken,
51
- pushSessionId: body.pushSessionId,
52
- timestamp: currentTimeMillis(),
53
- accountId
54
- };
55
- await ModuleBE_PushSessionDB.set.item(session);
56
- const subscriptions = body.subscriptions.map((subscription) => {
57
- return filterKeys({
61
+ let ModuleBE_PushPubSub_Class = (() => {
62
+ let _classSuper = Module;
63
+ let _instanceExtraInitializers = [];
64
+ let _test_decorators;
65
+ let _register_decorators;
66
+ let _unregister_decorators;
67
+ let _registerAll_decorators;
68
+ return class ModuleBE_PushPubSub_Class extends _classSuper {
69
+ static {
70
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
71
+ _test_decorators = [ApiHandler(ApiDef_PushMessages.test, { httpServer: () => HttpServer.getDefault() })];
72
+ _register_decorators = [ApiHandler(ApiDef_PushMessages.register, { httpServer: () => HttpServer.getDefault() })];
73
+ _unregister_decorators = [ApiHandler(ApiDef_PushMessages.unregister, { httpServer: () => HttpServer.getDefault() })];
74
+ _registerAll_decorators = [ApiHandler(ApiDef_PushMessages.registerAll, { httpServer: () => HttpServer.getDefault() })];
75
+ __esDecorate(this, null, _test_decorators, { kind: "method", name: "test", static: false, private: false, access: { has: obj => "test" in obj, get: obj => obj.test }, metadata: _metadata }, null, _instanceExtraInitializers);
76
+ __esDecorate(this, null, _register_decorators, { kind: "method", name: "register", static: false, private: false, access: { has: obj => "register" in obj, get: obj => obj.register }, metadata: _metadata }, null, _instanceExtraInitializers);
77
+ __esDecorate(this, null, _unregister_decorators, { kind: "method", name: "unregister", static: false, private: false, access: { has: obj => "unregister" in obj, get: obj => obj.unregister }, metadata: _metadata }, null, _instanceExtraInitializers);
78
+ __esDecorate(this, null, _registerAll_decorators, { kind: "method", name: "registerAll", static: false, private: false, access: { has: obj => "registerAll" in obj, get: obj => obj.registerAll }, metadata: _metadata }, null, _instanceExtraInitializers);
79
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
80
+ }
81
+ // private pushSessions!: FirestoreCollection<DB_PushSession>;
82
+ // private topics!: FirestoreCollection<DB_PushSubscription>;
83
+ messaging = __runInitializers(this, _instanceExtraInitializers);
84
+ constructor() {
85
+ super();
86
+ this.setMinLevel(LogLevel.Verbose);
87
+ this.setDefaultConfig({ messageLengthLimit: 10 * KB });
88
+ }
89
+ init() {
90
+ super.init();
91
+ const session = ModuleBE_Firebase.createAdminSession();
92
+ this.messaging = session.getMessaging();
93
+ }
94
+ async test(body) {
95
+ await this.pushToKey(body.message);
96
+ }
97
+ async register(body) {
98
+ await this.processRegistration(body);
99
+ return body.subscriptions?.[0] ?? { topic: '', filter: undefined };
100
+ }
101
+ async unregister(body) {
102
+ await this.processRegistration(body);
103
+ return body.subscriptions?.[0] ?? { topic: '', filter: undefined };
104
+ }
105
+ async registerAll(body) {
106
+ await this.processRegistration(body);
107
+ return body.subscriptions ?? [];
108
+ }
109
+ processRegistration = async (body) => {
110
+ const accountId = MemKey_AccountId.get();
111
+ const session = {
112
+ firebaseToken: body.firebaseToken,
58
113
  pushSessionId: body.pushSessionId,
59
- ...subscription
60
- });
61
- });
62
- await ModuleBE_PushSubscriptionDB.runTransaction(async (transaction) => {
63
- const data = await ModuleBE_PushSubscriptionDB.query.where({ pushSessionId: body.pushSessionId }, transaction);
64
- const toInsert = subscriptions.filter(s => !data.find(d => d.topic === s.topic && compare(s.filter, d.filter)));
65
- if (toInsert.length === 0)
66
- return;
67
- this.logWarning(`Subscribe on: `, toInsert);
68
- return ModuleBE_PushSubscriptionDB.create.all(toInsert, transaction);
69
- });
70
- };
71
- // ---------------------------
72
- pushToKey = async (message) => {
73
- const originatingAccountId = MemKey_AccountId.get();
74
- const messageLength = JSON.stringify(message).length;
75
- if (messageLength > this.config.messageLengthLimit)
76
- throw HttpCodes._4XX.BAD_REQUEST(`Message content too long, ${messageLength} > ${this.config.messageLengthLimit}`);
77
- const messageSubscription = { topic: message.topic, props: message.filter };
78
- const newVar = async (transaction) => {
79
- let subscriptions = await ModuleBE_PushSubscriptionDB.query.where({ topic: message.topic }, transaction);
80
- this.logVerbose(`Found ${subscriptions.length} subscribers for message: `, messageSubscription);
81
- if (message.filter)
82
- subscriptions = subscriptions.filter(subscription => !subscription.filter || compare(subscription.filter, message.filter));
83
- if (subscriptions.length === 0)
84
- return this.logDebug('No subscribers match message: ', message);
85
- const sessionsIds = subscriptions.map(d => d.pushSessionId);
86
- // I get the tokens relative to those sessions (query)
87
- this.logDebug(`Sending push to:`, ` -- Sessions:`, sessionsIds, ` -- Message: `, message);
88
- const pushSessions = await batchActionParallel(sessionsIds, 10, async (elements) => ModuleBE_PushSessionDB.query.where({ pushSessionId: { $in: elements } }, transaction));
89
- const map_sessionIdToSession = arrayToMap(pushSessions, session => session.pushSessionId);
90
- subscriptions = subscriptions.filter(subscription => map_sessionIdToSession[subscription.pushSessionId]);
91
- const messagesToCreate = subscriptions.map((subscription) => {
92
- return {
93
- pushSessionId: subscription.pushSessionId,
94
- token: map_sessionIdToSession[subscription.pushSessionId].firebaseToken,
95
- message: message,
96
- read: false,
97
- originatingAccountId
98
- };
114
+ timestamp: currentTimeMillis(),
115
+ accountId
116
+ };
117
+ await ModuleBE_PushSessionDB.set.item(session);
118
+ const subscriptions = body.subscriptions.map((subscription) => {
119
+ return filterKeys({
120
+ pushSessionId: body.pushSessionId,
121
+ ...subscription
122
+ });
99
123
  });
100
- if (messagesToCreate.length === 0)
101
- return this.logDebug('No subscribers match message: ', message);
102
- const dbMessages = await ModuleBE_PushMessagesHistoryDB.create.all(messagesToCreate);
103
- const messagesToSend = dbMessages.map(dbMessage => {
104
- const messageBody = {
105
- _id: dbMessage._id,
106
- timestamp: dbMessage.__created,
107
- message: dbMessage.message,
108
- topic: message.topic,
109
- filter: message.filter,
110
- };
111
- const data = {
112
- sessionId: dbMessage.pushSessionId,
113
- payload: JSON.stringify(messageBody)
114
- };
115
- return {
116
- token: dbMessage.token,
117
- data: data
118
- };
124
+ await ModuleBE_PushSubscriptionDB.runTransaction(async (transaction) => {
125
+ const data = await ModuleBE_PushSubscriptionDB.query.where({ pushSessionId: body.pushSessionId }, transaction);
126
+ const toInsert = subscriptions.filter(s => !data.find(d => d.topic === s.topic && compare(s.filter, d.filter)));
127
+ if (toInsert.length === 0)
128
+ return;
129
+ this.logWarning(`Subscribe on: `, toInsert);
130
+ return ModuleBE_PushSubscriptionDB.create.all(toInsert, transaction);
119
131
  });
120
- const { response, messages } = await this.sendMessage(messagesToSend);
121
- this.logInfo(`${response.successCount} sent, ${response.failureCount} failed`, 'messages', messages);
122
- // return this.cleanUp(response, messages);
123
132
  };
124
- return ModuleBE_PushSubscriptionDB.runTransaction(newVar);
125
- };
126
- // async pushToUser<MessageType extends PushMessage<any, any, any>>(accountId: string, message: MessageType) {
127
- // const notification = this.buildNotification(message);
128
- // this.logInfo(`Account ${notification.originatingAccountId} is pushing to user ${accountId}`, message.filter);
129
- //
130
- // const docs = await ModuleBE_PushSessionDB.query.where({accountId});
131
- // if (docs.length === 0)
132
- // return;
133
- //
134
- // const sessionsIds = docs.map(d => d.pushSessionId);
135
- // const sessions = await batchActionParallel(sessionsIds, 10, async elements =>
136
- // ModuleBE_PushSessionDB.query.where({pushSessionId: {$in: elements}}));
137
- //
138
- // const _messages = docs.reduce((carry: TempMessages, db_topic) => {
139
- // const session = sessions.find(s => s.pushSessionId === db_topic.pushSessionId);
140
- // if (!session)
141
- // return carry;
142
- //
143
- // carry[session.firebaseToken] = [notification];
144
- //
145
- // return carry;
146
- // }, {} as TempMessages);
147
- //
148
- // await this.sendMessage(_messages);
149
- // }
150
- // private buildNotification<MessageType extends PushMessage<any, any, any>>(message: MessageType) {
151
- // const originatingAccountId = MemKey_AccountId.get();
152
- //
153
- // return {
154
- // message: JSON.stringify(message),
155
- // read: false,
156
- // originatingAccountId
157
- // };
158
- // }
159
- sendMessage = async (messages) => {
160
- this.logInfo('sending a message to \n' + Object.keys(messages).join('\n'));
161
- const response = await this.messaging.sendAll(messages);
162
- this.logInfo('and this is the response: ' + response.responses.map(_response => _response.success));
163
- return { response, messages };
164
- };
165
- __onCleanupSchedulerAct = () => {
166
- return {
167
- cleanup: this.scheduledCleanup,
168
- interval: Day,
169
- moduleKey: this.getName()
133
+ // ---------------------------
134
+ pushToKey = async (message) => {
135
+ const originatingAccountId = MemKey_AccountId.get();
136
+ const messageLength = JSON.stringify(message).length;
137
+ if (messageLength > this.config.messageLengthLimit)
138
+ throw HttpCodes._4XX.BAD_REQUEST(`Message content too long, ${messageLength} > ${this.config.messageLengthLimit}`);
139
+ const messageSubscription = { topic: message.topic, props: message.filter };
140
+ const newVar = async (transaction) => {
141
+ let subscriptions = await ModuleBE_PushSubscriptionDB.query.where({ topic: message.topic }, transaction);
142
+ this.logVerbose(`Found ${subscriptions.length} subscribers for message: `, messageSubscription);
143
+ if (message.filter)
144
+ subscriptions = subscriptions.filter(subscription => !subscription.filter || compare(subscription.filter, message.filter));
145
+ if (subscriptions.length === 0)
146
+ return this.logDebug('No subscribers match message: ', message);
147
+ const sessionsIds = subscriptions.map(d => d.pushSessionId);
148
+ // I get the tokens relative to those sessions (query)
149
+ this.logDebug(`Sending push to:`, ` -- Sessions:`, sessionsIds, ` -- Message: `, message);
150
+ const pushSessions = await batchActionParallel(sessionsIds, 10, async (elements) => ModuleBE_PushSessionDB.query.where({ pushSessionId: { $in: elements } }, transaction));
151
+ const map_sessionIdToSession = arrayToMap(pushSessions, session => session.pushSessionId);
152
+ subscriptions = subscriptions.filter(subscription => map_sessionIdToSession[subscription.pushSessionId]);
153
+ const messagesToCreate = subscriptions.map((subscription) => {
154
+ return {
155
+ pushSessionId: subscription.pushSessionId,
156
+ token: map_sessionIdToSession[subscription.pushSessionId].firebaseToken,
157
+ message: message,
158
+ read: false,
159
+ originatingAccountId
160
+ };
161
+ });
162
+ if (messagesToCreate.length === 0)
163
+ return this.logDebug('No subscribers match message: ', message);
164
+ const dbMessages = await ModuleBE_PushMessagesHistoryDB.create.all(messagesToCreate);
165
+ const messagesToSend = dbMessages.map(dbMessage => {
166
+ const messageBody = {
167
+ _id: dbMessage._id,
168
+ timestamp: dbMessage.__created,
169
+ message: dbMessage.message,
170
+ topic: message.topic,
171
+ filter: message.filter,
172
+ };
173
+ const data = {
174
+ sessionId: dbMessage.pushSessionId,
175
+ payload: JSON.stringify(messageBody)
176
+ };
177
+ return {
178
+ token: dbMessage.token,
179
+ data: data
180
+ };
181
+ });
182
+ const { response, messages } = await this.sendMessage(messagesToSend);
183
+ this.logInfo(`${response.successCount} sent, ${response.failureCount} failed`, 'messages', messages);
184
+ // return this.cleanUp(response, messages);
185
+ };
186
+ return ModuleBE_PushSubscriptionDB.runTransaction(newVar);
170
187
  };
171
- };
172
- scheduledCleanup = async () => {
173
- const sessionsCleanupTime = this.config?.sessionsCleanupTime || Day;
174
- const docs = await ModuleBE_PushSessionDB.query.where({ timestamp: { $lt: currentTimeMillis() - sessionsCleanupTime } });
175
- await Promise.all([
176
- this.cleanUpImpl(docs.map(d => d.firebaseToken))
177
- ]);
178
- };
179
- cleanUp = async (response) => {
180
- this.logInfo(`${response.successCount} sent, ${response.failureCount} failed`);
181
- if (response.failureCount > 0)
182
- this.logWarning(response.responses.filter(r => r.error));
183
- // const toDelete = response.responses.reduce((carry, resp, i) => {
184
- // if (!resp.success && messages[i])
185
- // carry.push(messages[i].token);
188
+ // async pushToUser<MessageType extends PushMessage<any, any, any>>(accountId: string, message: MessageType) {
189
+ // const notification = this.buildNotification(message);
190
+ // this.logInfo(`Account ${notification.originatingAccountId} is pushing to user ${accountId}`, message.filter);
186
191
  //
187
- // return carry;
188
- // }, [] as string[]);
189
- //TODO: delete notifications for the user that are older than X
190
- // return this.cleanUpImpl(toDelete); <== THIS WAS THE PROBLEM!!
192
+ // const docs = await ModuleBE_PushSessionDB.query.where({accountId});
193
+ // if (docs.length === 0)
194
+ // return;
195
+ //
196
+ // const sessionsIds = docs.map(d => d.pushSessionId);
197
+ // const sessions = await batchActionParallel(sessionsIds, 10, async elements =>
198
+ // ModuleBE_PushSessionDB.query.where({pushSessionId: {$in: elements}}));
199
+ //
200
+ // const _messages = docs.reduce((carry: TempMessages, db_topic) => {
201
+ // const session = sessions.find(s => s.pushSessionId === db_topic.pushSessionId);
202
+ // if (!session)
203
+ // return carry;
204
+ //
205
+ // carry[session.firebaseToken] = [notification];
206
+ //
207
+ // return carry;
208
+ // }, {} as TempMessages);
209
+ //
210
+ // await this.sendMessage(_messages);
211
+ // }
212
+ // private buildNotification<MessageType extends PushMessage<any, any, any>>(message: MessageType) {
213
+ // const originatingAccountId = MemKey_AccountId.get();
214
+ //
215
+ // return {
216
+ // message: JSON.stringify(message),
217
+ // read: false,
218
+ // originatingAccountId
219
+ // };
220
+ // }
221
+ sendMessage = async (messages) => {
222
+ this.logInfo('sending a message to \n' + Object.keys(messages).join('\n'));
223
+ const response = await this.messaging.sendAll(messages);
224
+ this.logInfo('and this is the response: ' + response.responses.map(_response => _response.success));
225
+ return { response, messages };
226
+ };
227
+ __onCleanupSchedulerAct = () => {
228
+ return {
229
+ cleanup: this.scheduledCleanup,
230
+ interval: Day,
231
+ moduleKey: this.getName()
232
+ };
233
+ };
234
+ scheduledCleanup = async () => {
235
+ const sessionsCleanupTime = this.config?.sessionsCleanupTime || Day;
236
+ const docs = await ModuleBE_PushSessionDB.query.where({ timestamp: { $lt: currentTimeMillis() - sessionsCleanupTime } });
237
+ await Promise.all([
238
+ this.cleanUpImpl(docs.map(d => d.firebaseToken))
239
+ ]);
240
+ };
241
+ cleanUp = async (response) => {
242
+ this.logInfo(`${response.successCount} sent, ${response.failureCount} failed`);
243
+ if (response.failureCount > 0)
244
+ this.logWarning(response.responses.filter(r => r.error));
245
+ // const toDelete = response.responses.reduce((carry, resp, i) => {
246
+ // if (!resp.success && messages[i])
247
+ // carry.push(messages[i].token);
248
+ //
249
+ // return carry;
250
+ // }, [] as string[]);
251
+ //TODO: delete notifications for the user that are older than X
252
+ // return this.cleanUpImpl(toDelete); <== THIS WAS THE PROBLEM!!
253
+ };
254
+ async cleanUpImpl(_toDelete) {
255
+ if (_toDelete.length === 0)
256
+ return;
257
+ const toDelete = filterDuplicates(_toDelete);
258
+ const _sessions = await batchActionParallel(toDelete, 10, async (elements) => ModuleBE_PushSessionDB.query.where({ firebaseToken: { $in: elements } }));
259
+ const sessions = filterDuplicates(_sessions.map(s => s.pushSessionId));
260
+ const async = [
261
+ batchActionParallel(toDelete, 10, async (elements) => ModuleBE_PushSessionDB.query.where({ firebaseToken: { $in: elements } })),
262
+ batchActionParallel(sessions, 10, async (elements) => ModuleBE_PushSubscriptionDB.delete.where({ pushSessionId: { $in: elements } }))
263
+ ];
264
+ await Promise.all(async);
265
+ }
191
266
  };
192
- async cleanUpImpl(_toDelete) {
193
- if (_toDelete.length === 0)
194
- return;
195
- const toDelete = filterDuplicates(_toDelete);
196
- const _sessions = await batchActionParallel(toDelete, 10, async (elements) => ModuleBE_PushSessionDB.query.where({ firebaseToken: { $in: elements } }));
197
- const sessions = filterDuplicates(_sessions.map(s => s.pushSessionId));
198
- const async = [
199
- batchActionParallel(toDelete, 10, async (elements) => ModuleBE_PushSessionDB.query.where({ firebaseToken: { $in: elements } })),
200
- batchActionParallel(sessions, 10, async (elements) => ModuleBE_PushSubscriptionDB.delete.where({ pushSessionId: { $in: elements } }))
201
- ];
202
- await Promise.all(async);
203
- }
204
- }
267
+ })();
268
+ export { ModuleBE_PushPubSub_Class };
205
269
  export const ModuleBE_PushPubSub = new ModuleBE_PushPubSub_Class();
@@ -1,8 +1,7 @@
1
- import { DBApiConfigV3, ModuleBE_BaseDB } from '@nu-art/thunderstorm-backend';
2
- import { DBProto_PushSession } from '@nu-art/push-pub-sub-shared/push-session/index';
3
- type Config = DBApiConfigV3<DBProto_PushSession> & {};
4
- export declare class ModuleBE_PushSessionDB_Class extends ModuleBE_BaseDB<DBProto_PushSession, Config> {
1
+ import type { DB_Prototype } from '@nu-art/db-api-shared';
2
+ import { ModuleBE_BaseDB } from '@nu-art/db-api-backend';
3
+ import { DatabaseDef_PushSession } from '@nu-art/push-pub-sub-shared/push-session/index';
4
+ export declare class ModuleBE_PushSessionDB_Class extends ModuleBE_BaseDB<DatabaseDef_PushSession & DB_Prototype, object> {
5
5
  constructor();
6
6
  }
7
7
  export declare const ModuleBE_PushSessionDB: ModuleBE_PushSessionDB_Class;
8
- export {};
@@ -1,4 +1,4 @@
1
- import { ModuleBE_BaseDB, } from '@nu-art/thunderstorm-backend';
1
+ import { ModuleBE_BaseDB } from '@nu-art/db-api-backend';
2
2
  import { DBDef_PushSession } from '@nu-art/push-pub-sub-shared/push-session/index';
3
3
  export class ModuleBE_PushSessionDB_Class extends ModuleBE_BaseDB {
4
4
  constructor() {
@@ -1,9 +1,8 @@
1
- import { DBApiConfigV3, ModuleBE_BaseDB } from '@nu-art/thunderstorm-backend';
2
- import { DBProto_PushSubscription } from '@nu-art/push-pub-sub-shared/push-subscription/index';
3
- type Config = DBApiConfigV3<DBProto_PushSubscription> & {};
4
- export declare class ModuleBE_PushSubscriptionDB_Class extends ModuleBE_BaseDB<DBProto_PushSubscription, Config> {
1
+ import type { DB_Prototype } from '@nu-art/db-api-shared';
2
+ import { ModuleBE_BaseDB } from '@nu-art/db-api-backend';
3
+ import { DatabaseDef_PushSubscription } from '@nu-art/push-pub-sub-shared/push-subscription/index';
4
+ export declare class ModuleBE_PushSubscriptionDB_Class extends ModuleBE_BaseDB<DatabaseDef_PushSubscription & DB_Prototype, object> {
5
5
  constructor();
6
6
  }
7
7
  export declare const ModuleBE_PushSubscriptionDB: ModuleBE_PushSubscriptionDB_Class;
8
- export declare const ModuleBE_PushSubscriptionAPI: import("@nu-art/thunderstorm-backend").ModuleBE_BaseApi_Class<DBProto_PushSubscription>;
9
- export {};
8
+ export declare const ModuleBE_PushSubscriptionAPI: import("@nu-art/db-api-backend").ModuleBE_BaseApi_Class<DatabaseDef_PushSubscription & DB_Prototype>;
@@ -1,4 +1,4 @@
1
- import { createApisForDBModuleV3, ModuleBE_BaseDB, } from '@nu-art/thunderstorm-backend';
1
+ import { createApisForDBModule, ModuleBE_BaseDB } from '@nu-art/db-api-backend';
2
2
  import { DBDef_PushSubscription } from '@nu-art/push-pub-sub-shared/push-subscription/index';
3
3
  export class ModuleBE_PushSubscriptionDB_Class extends ModuleBE_BaseDB {
4
4
  constructor() {
@@ -6,4 +6,4 @@ export class ModuleBE_PushSubscriptionDB_Class extends ModuleBE_BaseDB {
6
6
  }
7
7
  }
8
8
  export const ModuleBE_PushSubscriptionDB = new ModuleBE_PushSubscriptionDB_Class();
9
- export const ModuleBE_PushSubscriptionAPI = createApisForDBModuleV3(ModuleBE_PushSubscriptionDB);
9
+ export const ModuleBE_PushSubscriptionAPI = createApisForDBModule(ModuleBE_PushSubscriptionDB);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nu-art/push-pub-sub-backend",
3
- "version": "0.401.9",
3
+ "version": "0.500.0",
4
4
  "description": "push-pub-sub Backend",
5
5
  "keywords": [
6
6
  "TacB0sS",
@@ -21,20 +21,19 @@
21
21
  },
22
22
  "license": "Apache-2.0",
23
23
  "author": "TacB0sS",
24
- "scripts": {
25
- "build": "tsc -b -f"
26
- },
24
+ "scripts": {},
27
25
  "dependencies": {
28
- "@nu-art/push-pub-sub-shared": "0.401.9",
29
- "@nu-art/firebase-backend": "0.401.9",
30
- "@nu-art/firebase-shared": "0.401.9",
31
- "@nu-art/permissions-backend": "0.401.9",
32
- "@nu-art/permissions-shared": "0.401.9",
33
- "@nu-art/thunderstorm-backend": "0.401.9",
34
- "@nu-art/thunderstorm-shared": "0.401.9",
35
- "@nu-art/ts-common": "0.401.9",
36
- "@nu-art/user-account-backend": "0.401.9",
37
- "@nu-art/user-account-shared": "0.401.9",
26
+ "@nu-art/push-pub-sub-shared": "0.500.0",
27
+ "@nu-art/firebase-backend": "0.500.0",
28
+ "@nu-art/firebase-shared": "0.500.0",
29
+ "@nu-art/permissions-backend": "0.500.0",
30
+ "@nu-art/permissions-shared": "0.500.0",
31
+ "@nu-art/db-api-backend": "0.500.0",
32
+ "@nu-art/db-api-shared": "0.500.0",
33
+ "@nu-art/http-server": "{{THUNDERSTORM_VERSION}}",
34
+ "@nu-art/ts-common": "0.500.0",
35
+ "@nu-art/user-account-backend": "0.500.0",
36
+ "@nu-art/user-account-shared": "0.500.0",
38
37
  "firebase": "^11.9.0",
39
38
  "firebase-admin": "13.4.0",
40
39
  "moment": "^2.29.4",