@wabot-dev/framework 0.9.16 → 0.9.18
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/dist/src/addon/async/in-memory/InMemoryCronJobRepository.js +74 -3
- package/dist/src/addon/async/in-memory/InMemoryJobRepository.js +75 -3
- package/dist/src/addon/async/pg/PgCronJobRepository.js +1 -2
- package/dist/src/addon/async/pg/PgJobRepository.js +1 -2
- package/dist/src/addon/async/pg/PgTransactionAdapter.js +3 -2
- package/dist/src/addon/auth/api-key/PgApiKeyRepository.js +3 -3
- package/dist/src/addon/auth/jwt/PgJwtRefreshTokenRepository.js +1 -1
- package/dist/src/addon/chat-bot/in-memory/InMemoryChatRepository.js +1 -1
- package/dist/src/addon/chat-bot/pg/PgChatMemory.js +2 -2
- package/dist/src/addon/chat-bot/pg/PgChatRepository.js +2 -2
- package/dist/src/addon/chat-controller/telegram/@telegram.js +3 -1
- package/dist/src/feature/pg/@pgExtension.js +1 -2
- package/dist/src/feature/repository/{@memoryExtension.js → @memExtension.js} +2 -2
- package/dist/src/feature/repository/MemoryRepositoryAdapter.js +93 -7
- package/dist/src/index.d.ts +23 -4
- package/dist/src/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
import { __decorate } from 'tslib';
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
2
4
|
import { generate } from 'short-uuid';
|
|
3
5
|
import { singleton } from '../../../core/injection/index.js';
|
|
6
|
+
import { Logger } from '../../../core/logger/Logger.js';
|
|
7
|
+
import '../../../feature/async/AsyncMetadataStore.js';
|
|
8
|
+
import '../../../feature/async/TransactionMetadataStore.js';
|
|
9
|
+
import '../../../feature/async/Async.js';
|
|
10
|
+
import { CronJob } from '../../../feature/async/CronJob.js';
|
|
11
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
12
|
+
import '../../../feature/async/JobRepository.js';
|
|
13
|
+
import '../../../feature/async/JobRunner.js';
|
|
14
|
+
import '../../../feature/async/JobScheduler.js';
|
|
15
|
+
import '../../../feature/async/JobWatchdog.js';
|
|
16
|
+
import '../../../feature/async/CronScheduler.js';
|
|
4
17
|
|
|
18
|
+
const CRON_JOBS_FILE = '.wabot/in-memory/cron-jobs.json';
|
|
19
|
+
const MAX_CRON_JOBS = 32;
|
|
20
|
+
const logger = new Logger('wabot:in-memory-cron-job-repository');
|
|
5
21
|
let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
22
|
+
// Insertion order acts as LRU: most-recently-touched at the end.
|
|
6
23
|
items = new Map();
|
|
24
|
+
constructor() {
|
|
25
|
+
this.load();
|
|
26
|
+
}
|
|
7
27
|
async create(cronJob) {
|
|
8
28
|
if (cronJob.wasCreated())
|
|
9
29
|
throw new Error('CronJob already created');
|
|
@@ -11,6 +31,8 @@ let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
|
11
31
|
cronJob['data'].createdAt = new Date().getTime();
|
|
12
32
|
cronJob.validate();
|
|
13
33
|
this.items.set(cronJob.id, cronJob);
|
|
34
|
+
this.enforceLimit();
|
|
35
|
+
this.persist();
|
|
14
36
|
}
|
|
15
37
|
async findDue(date) {
|
|
16
38
|
const now = (date ?? new Date()).getTime();
|
|
@@ -28,7 +50,8 @@ let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
|
28
50
|
if (!cronJob.wasCreated())
|
|
29
51
|
throw new Error('CronJob was not created');
|
|
30
52
|
cronJob.validate();
|
|
31
|
-
this.
|
|
53
|
+
this.touch(cronJob);
|
|
54
|
+
this.persist();
|
|
32
55
|
}
|
|
33
56
|
async findByName(name) {
|
|
34
57
|
for (const c of this.items.values()) {
|
|
@@ -37,9 +60,57 @@ let InMemoryCronJobRepository = class InMemoryCronJobRepository {
|
|
|
37
60
|
}
|
|
38
61
|
return null;
|
|
39
62
|
}
|
|
63
|
+
touch(item) {
|
|
64
|
+
this.items.delete(item.id);
|
|
65
|
+
this.items.set(item.id, item);
|
|
66
|
+
}
|
|
67
|
+
enforceLimit() {
|
|
68
|
+
while (this.items.size > MAX_CRON_JOBS) {
|
|
69
|
+
const oldestKey = this.items.keys().next().value;
|
|
70
|
+
if (oldestKey === undefined)
|
|
71
|
+
break;
|
|
72
|
+
this.items.delete(oldestKey);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
filePath() {
|
|
76
|
+
return path.resolve(process.cwd(), CRON_JOBS_FILE);
|
|
77
|
+
}
|
|
78
|
+
load() {
|
|
79
|
+
const file = this.filePath();
|
|
80
|
+
if (!fs.existsSync(file))
|
|
81
|
+
return;
|
|
82
|
+
try {
|
|
83
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
84
|
+
const parsed = JSON.parse(raw);
|
|
85
|
+
if (!Array.isArray(parsed))
|
|
86
|
+
return;
|
|
87
|
+
for (const data of parsed) {
|
|
88
|
+
if (!data?.id)
|
|
89
|
+
continue;
|
|
90
|
+
const cronJob = new CronJob(data);
|
|
91
|
+
this.items.set(cronJob.id, cronJob);
|
|
92
|
+
}
|
|
93
|
+
this.enforceLimit();
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
logger.warn(`Failed to load ${file}:`, err);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
persist() {
|
|
100
|
+
const file = this.filePath();
|
|
101
|
+
try {
|
|
102
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
103
|
+
const data = [...this.items.values()].map((c) => c['data']);
|
|
104
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
logger.warn(`Failed to persist ${file}:`, err);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
40
110
|
};
|
|
41
111
|
InMemoryCronJobRepository = __decorate([
|
|
42
|
-
singleton()
|
|
112
|
+
singleton(),
|
|
113
|
+
__metadata("design:paramtypes", [])
|
|
43
114
|
], InMemoryCronJobRepository);
|
|
44
115
|
|
|
45
116
|
export { InMemoryCronJobRepository };
|
|
@@ -1,9 +1,29 @@
|
|
|
1
|
-
import { __decorate } from 'tslib';
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
2
4
|
import { generate } from 'short-uuid';
|
|
3
5
|
import { singleton } from '../../../core/injection/index.js';
|
|
6
|
+
import { Logger } from '../../../core/logger/Logger.js';
|
|
7
|
+
import '../../../feature/async/AsyncMetadataStore.js';
|
|
8
|
+
import '../../../feature/async/TransactionMetadataStore.js';
|
|
9
|
+
import '../../../feature/async/Async.js';
|
|
10
|
+
import '../../../_virtual/index.js';
|
|
11
|
+
import { Job } from '../../../feature/async/Job.js';
|
|
12
|
+
import '../../../feature/async/JobRepository.js';
|
|
13
|
+
import '../../../feature/async/JobRunner.js';
|
|
14
|
+
import '../../../feature/async/JobScheduler.js';
|
|
15
|
+
import '../../../feature/async/JobWatchdog.js';
|
|
16
|
+
import '../../../feature/async/CronScheduler.js';
|
|
4
17
|
|
|
18
|
+
const JOBS_FILE = '.wabot/in-memory/jobs.json';
|
|
19
|
+
const MAX_JOBS = 32;
|
|
20
|
+
const logger = new Logger('wabot:in-memory-job-repository');
|
|
5
21
|
let InMemoryJobRepository = class InMemoryJobRepository {
|
|
22
|
+
// Insertion order acts as LRU: most-recently-touched at the end.
|
|
6
23
|
items = new Map();
|
|
24
|
+
constructor() {
|
|
25
|
+
this.load();
|
|
26
|
+
}
|
|
7
27
|
async find(id) {
|
|
8
28
|
return this.items.get(id) ?? null;
|
|
9
29
|
}
|
|
@@ -26,15 +46,19 @@ let InMemoryJobRepository = class InMemoryJobRepository {
|
|
|
26
46
|
item['data'].createdAt = new Date().getTime();
|
|
27
47
|
item.validate();
|
|
28
48
|
this.items.set(item.id, item);
|
|
49
|
+
this.enforceLimit();
|
|
50
|
+
this.persist();
|
|
29
51
|
}
|
|
30
52
|
async update(item) {
|
|
31
53
|
if (!item.wasCreated())
|
|
32
54
|
throw new Error('Job was not created');
|
|
33
55
|
item.validate();
|
|
34
|
-
this.
|
|
56
|
+
this.touch(item);
|
|
57
|
+
this.persist();
|
|
35
58
|
}
|
|
36
59
|
async delete(item) {
|
|
37
60
|
this.items.delete(item.id);
|
|
61
|
+
this.persist();
|
|
38
62
|
}
|
|
39
63
|
async findPendingForRunFrom(date, limit) {
|
|
40
64
|
const now = date.getTime();
|
|
@@ -67,9 +91,57 @@ let InMemoryJobRepository = class InMemoryJobRepository {
|
|
|
67
91
|
}
|
|
68
92
|
return count;
|
|
69
93
|
}
|
|
94
|
+
touch(item) {
|
|
95
|
+
this.items.delete(item.id);
|
|
96
|
+
this.items.set(item.id, item);
|
|
97
|
+
}
|
|
98
|
+
enforceLimit() {
|
|
99
|
+
while (this.items.size > MAX_JOBS) {
|
|
100
|
+
const oldestKey = this.items.keys().next().value;
|
|
101
|
+
if (oldestKey === undefined)
|
|
102
|
+
break;
|
|
103
|
+
this.items.delete(oldestKey);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
filePath() {
|
|
107
|
+
return path.resolve(process.cwd(), JOBS_FILE);
|
|
108
|
+
}
|
|
109
|
+
load() {
|
|
110
|
+
const file = this.filePath();
|
|
111
|
+
if (!fs.existsSync(file))
|
|
112
|
+
return;
|
|
113
|
+
try {
|
|
114
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
115
|
+
const parsed = JSON.parse(raw);
|
|
116
|
+
if (!Array.isArray(parsed))
|
|
117
|
+
return;
|
|
118
|
+
for (const data of parsed) {
|
|
119
|
+
if (!data?.id)
|
|
120
|
+
continue;
|
|
121
|
+
const job = new Job(data);
|
|
122
|
+
this.items.set(job.id, job);
|
|
123
|
+
}
|
|
124
|
+
this.enforceLimit();
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
logger.warn(`Failed to load ${file}:`, err);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
persist() {
|
|
131
|
+
const file = this.filePath();
|
|
132
|
+
try {
|
|
133
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
134
|
+
const data = [...this.items.values()].map((j) => j['data']);
|
|
135
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
logger.warn(`Failed to persist ${file}:`, err);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
70
141
|
};
|
|
71
142
|
InMemoryJobRepository = __decorate([
|
|
72
|
-
singleton()
|
|
143
|
+
singleton(),
|
|
144
|
+
__metadata("design:paramtypes", [])
|
|
73
145
|
], InMemoryJobRepository);
|
|
74
146
|
|
|
75
147
|
export { InMemoryJobRepository };
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import { singleton } from '../../../core/injection/index.js';
|
|
3
3
|
import { CronJob } from '../../../feature/async/CronJob.js';
|
|
4
|
-
import '
|
|
5
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
4
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
5
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
6
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
7
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import { Pool } from 'pg';
|
|
3
3
|
import { singleton } from '../../../core/injection/index.js';
|
|
4
|
-
import '
|
|
5
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
4
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
5
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
6
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
7
|
import { withPgClient } from '../../../feature/pg/withPgClient.js';
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import '../../../core/injection/index.js';
|
|
2
|
-
import '
|
|
3
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
2
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
4
3
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
5
4
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
6
5
|
import { withPgClient } from '../../../feature/pg/withPgClient.js';
|
|
7
6
|
import 'debug';
|
|
8
7
|
import '../../../feature/pg/PgLocker.js';
|
|
8
|
+
import 'short-uuid';
|
|
9
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
9
10
|
import 'node:crypto';
|
|
10
11
|
import '../../../feature/pg/pgStorage.js';
|
|
11
12
|
import { withPgTransaction } from '../../../feature/pg/withPgTransaction.js';
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import { singleton } from '../../../core/injection/index.js';
|
|
3
|
-
import '
|
|
4
|
-
import { CustomError } from '../../../core/error/CustomError.js';
|
|
5
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
3
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
4
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
5
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
6
|
import '../../../feature/pg/withPgClient.js';
|
|
9
7
|
import 'debug';
|
|
8
|
+
import { CustomError } from '../../../core/error/CustomError.js';
|
|
10
9
|
import '../../../feature/pg/PgLocker.js';
|
|
11
10
|
import { PgCrudRepository } from '../../../feature/pg/PgCrudRepository.js';
|
|
12
11
|
import 'node:crypto';
|
|
13
12
|
import '../../../feature/pg/pgStorage.js';
|
|
14
13
|
import { Pool } from 'pg';
|
|
15
14
|
import { ApiKey } from './ApiKey.js';
|
|
15
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
16
16
|
|
|
17
17
|
let PgApiKeyRepository = class PgApiKeyRepository extends PgCrudRepository {
|
|
18
18
|
constructor(pool) {
|
|
@@ -2,7 +2,7 @@ import { __decorate, __metadata } from 'tslib';
|
|
|
2
2
|
import { singleton } from '../../../core/injection/index.js';
|
|
3
3
|
import { CustomError } from '../../../core/error/CustomError.js';
|
|
4
4
|
import '../../../core/error/setupErrorHandlers.js';
|
|
5
|
-
import '
|
|
5
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
6
6
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
7
7
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
8
8
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -16,7 +16,7 @@ import '../../../core/error/setupErrorHandlers.js';
|
|
|
16
16
|
|
|
17
17
|
const CHATS_FILE = '.wabot/in-memory/chats.json';
|
|
18
18
|
const MEMORY_DIR = '.wabot/in-memory';
|
|
19
|
-
const MAX_CHATS =
|
|
19
|
+
const MAX_CHATS = 32;
|
|
20
20
|
const logger = new Logger('wabot:in-memory-chat-repository');
|
|
21
21
|
let InMemoryChatRepository = class InMemoryChatRepository {
|
|
22
22
|
// Ordered least-recently-active first, most-recent last.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import '../../../core/injection/index.js';
|
|
2
|
-
import '
|
|
3
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
2
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
4
3
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
5
4
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
6
5
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -17,6 +16,7 @@ import '../../../feature/chat-bot/UnionChatAdapter.js';
|
|
|
17
16
|
import '../../../feature/chat-bot/metadata/ChatAdapterMetadataStore.js';
|
|
18
17
|
import 'uuid';
|
|
19
18
|
import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
|
|
19
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
20
20
|
|
|
21
21
|
class PgChatMemory extends PgCrudRepository {
|
|
22
22
|
chatId;
|
|
@@ -2,8 +2,7 @@ import { __decorate, __metadata } from 'tslib';
|
|
|
2
2
|
import { Pool } from 'pg';
|
|
3
3
|
import { PgChatMemory } from './PgChatMemory.js';
|
|
4
4
|
import { singleton } from '../../../core/injection/index.js';
|
|
5
|
-
import '
|
|
6
|
-
import '../../../core/error/setupErrorHandlers.js';
|
|
5
|
+
import '../../../feature/repository/MemoryRepositoryAdapter.js';
|
|
7
6
|
import '../../../feature/repository/RepositoryMetadataStore.js';
|
|
8
7
|
import '../../../feature/repository/RepositoryAdapterRegistry.js';
|
|
9
8
|
import '../../../feature/pg/withPgClient.js';
|
|
@@ -20,6 +19,7 @@ import '../../../feature/chat-bot/UnionChatAdapter.js';
|
|
|
20
19
|
import '../../../feature/chat-bot/metadata/ChatAdapterMetadataStore.js';
|
|
21
20
|
import 'uuid';
|
|
22
21
|
import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
|
|
22
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
23
23
|
|
|
24
24
|
let PgChatRepository = class PgChatRepository extends PgCrudRepository {
|
|
25
25
|
constructor(pool) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { container } from '../../../core/injection/index.js';
|
|
2
|
+
import { resolveConfigReferences } from '../../../core/config/resolver.js';
|
|
2
3
|
import { ControllerMetadataStore } from '../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
|
|
3
4
|
import '../../../feature/chat-controller/ChatResolver.js';
|
|
4
5
|
import '../../../feature/chat-controller/runChatControllers.js';
|
|
@@ -7,12 +8,13 @@ import { TelegramChannelConfig } from './TelegramChannelConfig.js';
|
|
|
7
8
|
|
|
8
9
|
function telegram(config) {
|
|
9
10
|
return function (target, propertyKey) {
|
|
11
|
+
const resolved = resolveConfigReferences(config);
|
|
10
12
|
const store = container.resolve(ControllerMetadataStore);
|
|
11
13
|
store.saveChannelMetadata({
|
|
12
14
|
channelConstructor: TelegramChannel,
|
|
13
15
|
functionName: propertyKey.toString(),
|
|
14
16
|
controllerConstructor: target.constructor,
|
|
15
|
-
channelConfig: new TelegramChannelConfig(
|
|
17
|
+
channelConfig: new TelegramChannelConfig(resolved.botToken),
|
|
16
18
|
});
|
|
17
19
|
};
|
|
18
20
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { container } from '../../core/injection/index.js';
|
|
2
|
-
import '
|
|
3
|
-
import '../../core/error/setupErrorHandlers.js';
|
|
2
|
+
import '../repository/MemoryRepositoryAdapter.js';
|
|
4
3
|
import { RepositoryMetadataStore } from '../repository/RepositoryMetadataStore.js';
|
|
5
4
|
import '../repository/RepositoryAdapterRegistry.js';
|
|
6
5
|
import { PgRepositoryBase } from './PgRepositoryBase.js';
|
|
@@ -11,7 +11,7 @@ function inheritsFrom(ctor, base) {
|
|
|
11
11
|
}
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function memExtension(repositoryClass) {
|
|
15
15
|
if (typeof repositoryClass !== 'function') {
|
|
16
16
|
throw new Error(`@memoryExtension: repository argument must be a class, ` +
|
|
17
17
|
`got ${typeof repositoryClass}`);
|
|
@@ -26,4 +26,4 @@ function memoryExtension(repositoryClass) {
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
export {
|
|
29
|
+
export { memExtension };
|
|
@@ -1,12 +1,80 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
1
3
|
import { generate } from 'short-uuid';
|
|
2
4
|
import { CustomError } from '../../core/error/CustomError.js';
|
|
3
5
|
import '../../core/error/setupErrorHandlers.js';
|
|
6
|
+
import { Logger } from '../../core/logger/Logger.js';
|
|
4
7
|
import { evaluateQueryAst } from './evaluateQueryAst.js';
|
|
5
8
|
|
|
9
|
+
const DEFAULT_PERSIST_DIR = '.wabot/in-memory';
|
|
10
|
+
const DEFAULT_MAX_ITEMS = 32;
|
|
11
|
+
const logger = new Logger('wabot:memory-repository-adapter');
|
|
6
12
|
function cloneEntity(config, item) {
|
|
7
13
|
const data = JSON.parse(JSON.stringify(item['data']));
|
|
8
14
|
return new config.constructor(data);
|
|
9
15
|
}
|
|
16
|
+
class MemoryStore {
|
|
17
|
+
config;
|
|
18
|
+
persistOptions;
|
|
19
|
+
// Insertion order acts as LRU: most-recently-touched at the end.
|
|
20
|
+
items = new Map();
|
|
21
|
+
constructor(config, persistOptions) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.persistOptions = persistOptions;
|
|
24
|
+
this.load();
|
|
25
|
+
}
|
|
26
|
+
touch(item) {
|
|
27
|
+
this.items.delete(item.id);
|
|
28
|
+
this.items.set(item.id, item);
|
|
29
|
+
}
|
|
30
|
+
enforceLimit() {
|
|
31
|
+
while (this.items.size > this.persistOptions.maxItems) {
|
|
32
|
+
const oldest = this.items.keys().next().value;
|
|
33
|
+
if (oldest === undefined)
|
|
34
|
+
break;
|
|
35
|
+
this.items.delete(oldest);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
persist() {
|
|
39
|
+
if (!this.persistOptions.enabled)
|
|
40
|
+
return;
|
|
41
|
+
const file = this.filePath();
|
|
42
|
+
try {
|
|
43
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
44
|
+
const data = [...this.items.values()].map((i) => i['data']);
|
|
45
|
+
fs.writeFileSync(file, JSON.stringify(data, null, 2), 'utf-8');
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
logger.warn(`Failed to persist ${file}:`, err);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
load() {
|
|
52
|
+
if (!this.persistOptions.enabled)
|
|
53
|
+
return;
|
|
54
|
+
const file = this.filePath();
|
|
55
|
+
if (!fs.existsSync(file))
|
|
56
|
+
return;
|
|
57
|
+
try {
|
|
58
|
+
const raw = fs.readFileSync(file, 'utf-8');
|
|
59
|
+
const parsed = JSON.parse(raw);
|
|
60
|
+
if (!Array.isArray(parsed))
|
|
61
|
+
return;
|
|
62
|
+
for (const data of parsed) {
|
|
63
|
+
if (!data?.id)
|
|
64
|
+
continue;
|
|
65
|
+
const item = new this.config.constructor(data);
|
|
66
|
+
this.items.set(data.id, item);
|
|
67
|
+
}
|
|
68
|
+
this.enforceLimit();
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
logger.warn(`Failed to load ${file}:`, err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
filePath() {
|
|
75
|
+
return path.resolve(process.cwd(), this.persistOptions.dir, `${this.config.table}.json`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
10
78
|
class MemoryRepositoryExtension {
|
|
11
79
|
items;
|
|
12
80
|
config;
|
|
@@ -19,12 +87,15 @@ class MemoryRepositoryExtension {
|
|
|
19
87
|
}
|
|
20
88
|
}
|
|
21
89
|
class MemoryRepositoryRuntime {
|
|
22
|
-
|
|
90
|
+
store;
|
|
23
91
|
config;
|
|
24
|
-
constructor(
|
|
25
|
-
this.
|
|
92
|
+
constructor(store, config) {
|
|
93
|
+
this.store = store;
|
|
26
94
|
this.config = config;
|
|
27
95
|
}
|
|
96
|
+
get items() {
|
|
97
|
+
return this.store.items;
|
|
98
|
+
}
|
|
28
99
|
async find(id) {
|
|
29
100
|
const item = this.items.get(id);
|
|
30
101
|
return item ? cloneEntity(this.config, item) : null;
|
|
@@ -58,17 +129,22 @@ class MemoryRepositoryRuntime {
|
|
|
58
129
|
item['data'].id = generate();
|
|
59
130
|
item['data'].createdAt = new Date().getTime();
|
|
60
131
|
item.validate();
|
|
61
|
-
|
|
132
|
+
const stored = cloneEntity(this.config, item);
|
|
133
|
+
this.store.touch(stored);
|
|
134
|
+
this.store.enforceLimit();
|
|
135
|
+
this.store.persist();
|
|
62
136
|
}
|
|
63
137
|
async update(item) {
|
|
64
138
|
item.validate();
|
|
65
139
|
if (!this.items.has(item.id)) {
|
|
66
140
|
throw new Error(`Update failed: no affected rows`);
|
|
67
141
|
}
|
|
68
|
-
this.
|
|
142
|
+
this.store.touch(cloneEntity(this.config, item));
|
|
143
|
+
this.store.persist();
|
|
69
144
|
}
|
|
70
145
|
async delete(item) {
|
|
71
146
|
this.items.delete(item.id);
|
|
147
|
+
this.store.persist();
|
|
72
148
|
}
|
|
73
149
|
async runQuery(ast, args) {
|
|
74
150
|
const result = evaluateQueryAst(this.items.values(), ast, args);
|
|
@@ -85,16 +161,26 @@ class MemoryRepositoryRuntime {
|
|
|
85
161
|
for (const item of matched) {
|
|
86
162
|
this.items.delete(item.id);
|
|
87
163
|
}
|
|
164
|
+
if (matched.length > 0)
|
|
165
|
+
this.store.persist();
|
|
88
166
|
}
|
|
89
167
|
}
|
|
90
168
|
const MEMORY_ADAPTER_ID = Symbol('wabot:memory-adapter');
|
|
91
169
|
class MemoryRepositoryAdapter {
|
|
92
170
|
id = MEMORY_ADAPTER_ID;
|
|
93
171
|
stores = new Map();
|
|
172
|
+
persistOptions;
|
|
173
|
+
constructor(options = {}) {
|
|
174
|
+
this.persistOptions = {
|
|
175
|
+
enabled: options.persist ?? true,
|
|
176
|
+
dir: options.dir ?? DEFAULT_PERSIST_DIR,
|
|
177
|
+
maxItems: options.maxItems ?? DEFAULT_MAX_ITEMS,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
94
180
|
getStore(config) {
|
|
95
181
|
let store = this.stores.get(config);
|
|
96
182
|
if (!store) {
|
|
97
|
-
store = new
|
|
183
|
+
store = new MemoryStore(config, this.persistOptions);
|
|
98
184
|
this.stores.set(config, store);
|
|
99
185
|
}
|
|
100
186
|
return store;
|
|
@@ -103,7 +189,7 @@ class MemoryRepositoryAdapter {
|
|
|
103
189
|
return new MemoryRepositoryRuntime(this.getStore(config), config);
|
|
104
190
|
}
|
|
105
191
|
buildExtension(config, ExtensionCtor) {
|
|
106
|
-
return new ExtensionCtor(this.getStore(config), config);
|
|
192
|
+
return new ExtensionCtor(this.getStore(config).items, config);
|
|
107
193
|
}
|
|
108
194
|
}
|
|
109
195
|
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1373,6 +1373,11 @@ interface IRepositoryAdapter {
|
|
|
1373
1373
|
buildExtension?<E>(config: IRepositoryConfig<any>, ExtensionCtor: IConstructor<E>): E;
|
|
1374
1374
|
}
|
|
1375
1375
|
|
|
1376
|
+
interface IMemoryRepositoryAdapterOptions {
|
|
1377
|
+
persist?: boolean;
|
|
1378
|
+
dir?: string;
|
|
1379
|
+
maxItems?: number;
|
|
1380
|
+
}
|
|
1376
1381
|
declare class MemoryRepositoryExtension<P extends Entity<IEntityData>> {
|
|
1377
1382
|
protected readonly items: Map<string, P>;
|
|
1378
1383
|
protected readonly config: IRepositoryConfig<P>;
|
|
@@ -1383,13 +1388,15 @@ declare const MEMORY_ADAPTER_ID: unique symbol;
|
|
|
1383
1388
|
declare class MemoryRepositoryAdapter implements IRepositoryAdapter {
|
|
1384
1389
|
readonly id: symbol;
|
|
1385
1390
|
private stores;
|
|
1391
|
+
private readonly persistOptions;
|
|
1392
|
+
constructor(options?: IMemoryRepositoryAdapterOptions);
|
|
1386
1393
|
private getStore;
|
|
1387
1394
|
build<P extends Entity<IEntityData>>(config: IRepositoryConfig<P>): IRepositoryRuntime<P>;
|
|
1388
1395
|
buildExtension<E>(config: IRepositoryConfig<any>, ExtensionCtor: IConstructor<E>): E;
|
|
1389
1396
|
}
|
|
1390
1397
|
|
|
1391
1398
|
type ExtensionOf<R> = R extends CrudRepository<any, infer Ext> ? Ext : never;
|
|
1392
|
-
declare function
|
|
1399
|
+
declare function memExtension<R extends CrudRepository<any, any>>(repositoryClass: IConstructor<R>): <E extends MemoryRepositoryExtension<any> & ExtensionOf<R>>(target: IConstructor<E>) => void;
|
|
1393
1400
|
|
|
1394
1401
|
declare function query(): (target: object, propertyKey: string | symbol, descriptor?: PropertyDescriptor) => void;
|
|
1395
1402
|
|
|
@@ -1645,6 +1652,7 @@ declare class PgTransactionAdapter implements ITransactionAdapter {
|
|
|
1645
1652
|
|
|
1646
1653
|
declare class InMemoryJobRepository implements IJobRepository {
|
|
1647
1654
|
private items;
|
|
1655
|
+
constructor();
|
|
1648
1656
|
find(id: string): Promise<Job | null>;
|
|
1649
1657
|
findOrThrow(id: string): Promise<Job>;
|
|
1650
1658
|
findByIds(ids: string[]): Promise<Job[]>;
|
|
@@ -1655,15 +1663,26 @@ declare class InMemoryJobRepository implements IJobRepository {
|
|
|
1655
1663
|
findPendingForRunFrom(date: Date, limit: number): Promise<Job[]>;
|
|
1656
1664
|
findRunningJobs(): Promise<Job[]>;
|
|
1657
1665
|
countRunningByCommand(commandName: string): Promise<number>;
|
|
1666
|
+
private touch;
|
|
1667
|
+
private enforceLimit;
|
|
1668
|
+
private filePath;
|
|
1669
|
+
private load;
|
|
1670
|
+
private persist;
|
|
1658
1671
|
}
|
|
1659
1672
|
|
|
1660
1673
|
declare class InMemoryCronJobRepository implements ICronJobRepository {
|
|
1661
1674
|
private items;
|
|
1675
|
+
constructor();
|
|
1662
1676
|
create(cronJob: CronJob): Promise<void>;
|
|
1663
1677
|
findDue(date?: Date): Promise<CronJob[]>;
|
|
1664
1678
|
findOrThrow(id: string): Promise<CronJob>;
|
|
1665
1679
|
update(cronJob: CronJob): Promise<void>;
|
|
1666
1680
|
findByName(name: string): Promise<CronJob | null>;
|
|
1681
|
+
private touch;
|
|
1682
|
+
private enforceLimit;
|
|
1683
|
+
private filePath;
|
|
1684
|
+
private load;
|
|
1685
|
+
private persist;
|
|
1667
1686
|
}
|
|
1668
1687
|
|
|
1669
1688
|
declare function apiKeyHandshakeGuard(): (target: IConstructor<any>) => void;
|
|
@@ -2138,9 +2157,9 @@ declare class SocketChannel implements IChatChannel {
|
|
|
2138
2157
|
}
|
|
2139
2158
|
|
|
2140
2159
|
interface ITelegramChannelConfig {
|
|
2141
|
-
botToken: string
|
|
2160
|
+
botToken: string | ConfigReference<string>;
|
|
2142
2161
|
}
|
|
2143
|
-
declare class TelegramChannelConfig
|
|
2162
|
+
declare class TelegramChannelConfig {
|
|
2144
2163
|
botToken: string;
|
|
2145
2164
|
constructor(botToken: string);
|
|
2146
2165
|
}
|
|
@@ -2485,4 +2504,4 @@ declare function HtmlModule(options: IHtmlModuleOptions): {
|
|
|
2485
2504
|
new (): {};
|
|
2486
2505
|
};
|
|
2487
2506
|
|
|
2488
|
-
export { AnthropicChatAdapter, ApiKey, ApiKeyGuardMiddleware, ApiKeyHandshakeGuardMiddleware, ApiKeyRepository, Async, AsyncMetadataStore, Auth, Chat, ChatAdapter, ChatAdapterMetadataStore, ChatAdapterRegistry, ChatBot, ChatBotMetadataStore, ChatItem, ChatMemory, ChatOperator, ChatRepository, ChatResolver, type ClientMap, CmdChannel, CmdChannelConfig, CmdChannelServer, type CmdClientMessage, type CmdServerMessage, type ConfigReference, type ConfigReferenceType, ConfigResolver, Container, ControllerMetadataStore, CronJob, CronJobRepository, CrudRepository, CustomError, DeepSeekChatAdapter, DescriptionMetadataStore, EXPRESS_REQ, EXPRESS_RES, Entity, Env, type ErrorSeverity, ExpressProvider, GoogleChatAdapter, type GoogleChatAdapterV2Options, HtmlModule, HttpServerProvider, type IApiKeyData, type IApiKeyRepository, type IArrayValidationError, type IArrayValidationResult, type IBotMessageItem, type IBuiltQuery, type IChannelMessage, type IChannelMetadata, type IChatAdapter, type IChatAdapterDecoratorConfig, type IChatAdapterMetadata, type IChatAdapterNextItemsReq, type IChatAdapterNextItemsRes, type IChatAssociation, type IChatBot, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatItem, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatMessageDocument, type IChatMessageFile, type IChatMessageImage, type IChatMessagesPrivateFile, type IChatMessagesPublicFile, type IChatRepository, type IChatType, type ICmdChannelEntry, type ICmdChannelHandlers, type ICmdChannelMessage, type ICmdReceivedMessage, type ICommandConfig, type ICommandHandler, type ICommandHandlerConfig, type IConstructor, type ICronConfig, type ICronHandler, type ICronJobData, type ICronJobRepository, type ICrudRepository, type ICustomErrorData, type IDescriptionMetadata, type IEndPointConfig, type IEndPointMetadata, type IEntityData, type IEnvType, type IErrorHandlersConfig, type IErrorMonitor, type IErrorMonitorContext, type IExtractChatMessageTextOptions, type IFunctionCall, type IFunctionCallItem, type IGenerateApiKeyReq, type IGenerateApiKeyRes, type IHandshakeMiddleware, type IHandshakeMiddlewareMetadata, type IHtmlModuleOptions, type IHumanMessageItem, type IJobData, type IJobRepository, type IJwtRefreshTokenData, type IJwtRefreshTokenRepository, type ILanguageModelUsage, type ILockKey, type ILocker, type ILockerKey, type IMessageContext, type IMiddleware, type IMiddlewareMetadata, type IMindset, type IMindsetConfig, type IMindsetIdentity, type IMindsetLlm, type IMindsetMetadata, type IMindsetModelKind, type IMindsetModelRef, type IMindsetModels, type IMindsetModuleConfig, type IMindsetModuleMetadata, type IMindsetTool, type IMindsetToolParameter, type IModelValidationError, type IModelValidationResult, type IModelValidatorsInfo, type IMoneyData, type IPersistentData, type IPgRepositoryConfig, type IProjectRunnerConfig, type IPropertyValidatorInfo, type IQueryAst, type IQueryCondition, type IQueryMethodMetadata, type IQueryOrderBy, type IReceivedMessage, type IRemoteApiKeyFetcher, type IRepositoryAdapter, type IRepositoryConfig, type IRepositoryRuntime, type IRestControllerConfig, type IRestControllerMetadata, type IScanProjectFilesOptions, type IScheduleAt, type IScheduleDelay, type ISendWhatsAppMessageReq, type ISendWhatsAppTemplateReq, type ISocketChannelConfig, type ISocketChannelMessage, type ISocketChannelReceivedMessage, type ISocketControllerConfig, type ISocketControllerMetadata, type ISocketEventConfig, type ISocketEventMetadata, type ISocketReceivedMessage, type IStorableData, type ITelegramChannelConfig, type ITelegramChannelMessage, type ITelegramReceivedMessage, type ITransactionAdapter, type IValidateArrayOptions, type IValidateArrayOptionsWithItemsValidators, type IValidateInputShape, type IValidateIsInOptions, type IValidateIsRecordOptions, type IValidateMaxOptions, type IValidateMinOptions, type IValidationError, type IValidationResult, type IValidator, type IValidatorMetadata, type IWasenderChannelConfig, type IWasenderChannelMessageListener, type IWasenderDeviceListMetadata, type IWasenderEvent, type IWasenderMessageContent, type IWasenderMessageContextInfo, type IWasenderMessageKey, type IWasenderMessageReceivedData, type IWasenderMessageReceivedEvent, type IWasenderQrUpdatedEvent, type IWasenderReceivedMessage, type IWhatsAppCloudContact, type IWhatsAppCloudMessage, type IWhatsAppCloudMessageMetadata, type IWhatsAppCloudTemplate, type IWhatsAppCloudTemplateComponent, type IWhatsAppCloudTemplateResponse, type IWhatsAppCloudWebhookPayload, type IWhatsAppSender, type IWhatsAppTemplateData, type IWhatsAppTemplateParameter, type IchatControllerConfig, InMemoryChatMemory, InMemoryChatRepository, InMemoryCronJobRepository, InMemoryJobRepository, InMemoryLockKey, InMemoryLocker, Job, JobRepository, JobRunner, Jwt, JwtAccessAndRefreshTokenDto, JwtConfig, JwtGuardMiddleware, JwtHandshakeGuardMiddleware, JwtRefreshToken, JwtRefreshTokenRepository, JwtSigner, JwtTokenDto, Lifecycle, Locker, Logger, MEMORY_ADAPTER_ID, Mapper, MemoryRepositoryAdapter, MemoryRepositoryExtension, Mindset, MindsetMetadataStore, MindsetOperator, Money, MoneyDto, OpenRouterChatAdapter, OpenaiChatAdapter, PG_ADAPTER_ID, Password, type PasswordHashOptions, Persistent, PgApiKeyRepository, PgChatMemory, PgChatRepository, PgCronJobRepository, PgCrudRepository, PgJobRepository, PgJsonRepositoryAdapter, PgJwtRefreshTokenRepository, PgLockKey, PgLocker, PgRepositoryBase, PgRepositoryBase as PgRepositoryExtension, PgTransactionAdapter, ProjectRunner, type QueryConnector, type QueryOperator, type QueryPrefix, Random, RemoteApiKeyRepository, RepositoryAdapterRegistry, RepositoryMetadataStore, type ResolvedConfig, RestControllerMetadataStore, RestRequest, SocketChannel, SocketChannelConfig, SocketChannelMessageFile, SocketChannelReceivedMessage, SocketControllerMetadataStore, SocketServerConfig, SocketServerProvider, Storable, TelegramChannel, TelegramChannelConfig, TransactionMetadataStore, UnionChatAdapter, ValidationMetadataStore, WabotChatAdapter, WasenderChannel, WasenderChannelConfig, WasenderReceiver, WasenderSender, WasenderWebhookController, WhatsAppApiSender, WhatsAppReceiverByCloudApi, WhatsAppSender, apiKeyGuard, apiKeyHandshakeGuard, bool, boolArr, buildQuerySql, chatAdapter, chatBot, chatController, chatItemTypeOptions, cmd, cmdChannelName, cmdChannelSocketPath, command, commandHandler, container, cronHandler, description, errorToPlainObject, evaluateQueryAst, extractChatMessageText, extractNumberFromWasenderMessageKey, getClientMap, getPgClient, handshakeMiddlewares, inject, injectable, isArray, isBoolean, isChatMessageEmpty, isDate, isIn, isModel, isNotEmpty, isNumber, isOptional, isPresent, isRecord, isRetryableError, isString, jwtGuard, jwtHandshakeGuard, max,
|
|
2507
|
+
export { AnthropicChatAdapter, ApiKey, ApiKeyGuardMiddleware, ApiKeyHandshakeGuardMiddleware, ApiKeyRepository, Async, AsyncMetadataStore, Auth, Chat, ChatAdapter, ChatAdapterMetadataStore, ChatAdapterRegistry, ChatBot, ChatBotMetadataStore, ChatItem, ChatMemory, ChatOperator, ChatRepository, ChatResolver, type ClientMap, CmdChannel, CmdChannelConfig, CmdChannelServer, type CmdClientMessage, type CmdServerMessage, type ConfigReference, type ConfigReferenceType, ConfigResolver, Container, ControllerMetadataStore, CronJob, CronJobRepository, CrudRepository, CustomError, DeepSeekChatAdapter, DescriptionMetadataStore, EXPRESS_REQ, EXPRESS_RES, Entity, Env, type ErrorSeverity, ExpressProvider, GoogleChatAdapter, type GoogleChatAdapterV2Options, HtmlModule, HttpServerProvider, type IApiKeyData, type IApiKeyRepository, type IArrayValidationError, type IArrayValidationResult, type IBotMessageItem, type IBuiltQuery, type IChannelMessage, type IChannelMetadata, type IChatAdapter, type IChatAdapterDecoratorConfig, type IChatAdapterMetadata, type IChatAdapterNextItemsReq, type IChatAdapterNextItemsRes, type IChatAssociation, type IChatBot, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatItem, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatMessageDocument, type IChatMessageFile, type IChatMessageImage, type IChatMessagesPrivateFile, type IChatMessagesPublicFile, type IChatRepository, type IChatType, type ICmdChannelEntry, type ICmdChannelHandlers, type ICmdChannelMessage, type ICmdReceivedMessage, type ICommandConfig, type ICommandHandler, type ICommandHandlerConfig, type IConstructor, type ICronConfig, type ICronHandler, type ICronJobData, type ICronJobRepository, type ICrudRepository, type ICustomErrorData, type IDescriptionMetadata, type IEndPointConfig, type IEndPointMetadata, type IEntityData, type IEnvType, type IErrorHandlersConfig, type IErrorMonitor, type IErrorMonitorContext, type IExtractChatMessageTextOptions, type IFunctionCall, type IFunctionCallItem, type IGenerateApiKeyReq, type IGenerateApiKeyRes, type IHandshakeMiddleware, type IHandshakeMiddlewareMetadata, type IHtmlModuleOptions, type IHumanMessageItem, type IJobData, type IJobRepository, type IJwtRefreshTokenData, type IJwtRefreshTokenRepository, type ILanguageModelUsage, type ILockKey, type ILocker, type ILockerKey, type IMemoryRepositoryAdapterOptions, type IMessageContext, type IMiddleware, type IMiddlewareMetadata, type IMindset, type IMindsetConfig, type IMindsetIdentity, type IMindsetLlm, type IMindsetMetadata, type IMindsetModelKind, type IMindsetModelRef, type IMindsetModels, type IMindsetModuleConfig, type IMindsetModuleMetadata, type IMindsetTool, type IMindsetToolParameter, type IModelValidationError, type IModelValidationResult, type IModelValidatorsInfo, type IMoneyData, type IPersistentData, type IPgRepositoryConfig, type IProjectRunnerConfig, type IPropertyValidatorInfo, type IQueryAst, type IQueryCondition, type IQueryMethodMetadata, type IQueryOrderBy, type IReceivedMessage, type IRemoteApiKeyFetcher, type IRepositoryAdapter, type IRepositoryConfig, type IRepositoryRuntime, type IRestControllerConfig, type IRestControllerMetadata, type IScanProjectFilesOptions, type IScheduleAt, type IScheduleDelay, type ISendWhatsAppMessageReq, type ISendWhatsAppTemplateReq, type ISocketChannelConfig, type ISocketChannelMessage, type ISocketChannelReceivedMessage, type ISocketControllerConfig, type ISocketControllerMetadata, type ISocketEventConfig, type ISocketEventMetadata, type ISocketReceivedMessage, type IStorableData, type ITelegramChannelConfig, type ITelegramChannelMessage, type ITelegramReceivedMessage, type ITransactionAdapter, type IValidateArrayOptions, type IValidateArrayOptionsWithItemsValidators, type IValidateInputShape, type IValidateIsInOptions, type IValidateIsRecordOptions, type IValidateMaxOptions, type IValidateMinOptions, type IValidationError, type IValidationResult, type IValidator, type IValidatorMetadata, type IWasenderChannelConfig, type IWasenderChannelMessageListener, type IWasenderDeviceListMetadata, type IWasenderEvent, type IWasenderMessageContent, type IWasenderMessageContextInfo, type IWasenderMessageKey, type IWasenderMessageReceivedData, type IWasenderMessageReceivedEvent, type IWasenderQrUpdatedEvent, type IWasenderReceivedMessage, type IWhatsAppCloudContact, type IWhatsAppCloudMessage, type IWhatsAppCloudMessageMetadata, type IWhatsAppCloudTemplate, type IWhatsAppCloudTemplateComponent, type IWhatsAppCloudTemplateResponse, type IWhatsAppCloudWebhookPayload, type IWhatsAppSender, type IWhatsAppTemplateData, type IWhatsAppTemplateParameter, type IchatControllerConfig, InMemoryChatMemory, InMemoryChatRepository, InMemoryCronJobRepository, InMemoryJobRepository, InMemoryLockKey, InMemoryLocker, Job, JobRepository, JobRunner, Jwt, JwtAccessAndRefreshTokenDto, JwtConfig, JwtGuardMiddleware, JwtHandshakeGuardMiddleware, JwtRefreshToken, JwtRefreshTokenRepository, JwtSigner, JwtTokenDto, Lifecycle, Locker, Logger, MEMORY_ADAPTER_ID, Mapper, MemoryRepositoryAdapter, MemoryRepositoryExtension, Mindset, MindsetMetadataStore, MindsetOperator, Money, MoneyDto, OpenRouterChatAdapter, OpenaiChatAdapter, PG_ADAPTER_ID, Password, type PasswordHashOptions, Persistent, PgApiKeyRepository, PgChatMemory, PgChatRepository, PgCronJobRepository, PgCrudRepository, PgJobRepository, PgJsonRepositoryAdapter, PgJwtRefreshTokenRepository, PgLockKey, PgLocker, PgRepositoryBase, PgRepositoryBase as PgRepositoryExtension, PgTransactionAdapter, ProjectRunner, type QueryConnector, type QueryOperator, type QueryPrefix, Random, RemoteApiKeyRepository, RepositoryAdapterRegistry, RepositoryMetadataStore, type ResolvedConfig, RestControllerMetadataStore, RestRequest, SocketChannel, SocketChannelConfig, SocketChannelMessageFile, SocketChannelReceivedMessage, SocketControllerMetadataStore, SocketServerConfig, SocketServerProvider, Storable, TelegramChannel, TelegramChannelConfig, TransactionMetadataStore, UnionChatAdapter, ValidationMetadataStore, WabotChatAdapter, WasenderChannel, WasenderChannelConfig, WasenderReceiver, WasenderSender, WasenderWebhookController, WhatsAppApiSender, WhatsAppReceiverByCloudApi, WhatsAppSender, apiKeyGuard, apiKeyHandshakeGuard, bool, boolArr, buildQuerySql, chatAdapter, chatBot, chatController, chatItemTypeOptions, cmd, cmdChannelName, cmdChannelSocketPath, command, commandHandler, container, cronHandler, description, errorToPlainObject, evaluateQueryAst, extractChatMessageText, extractNumberFromWasenderMessageKey, getClientMap, getPgClient, handshakeMiddlewares, inject, injectable, isArray, isBoolean, isChatMessageEmpty, isDate, isIn, isModel, isNotEmpty, isNumber, isOptional, isPresent, isRecord, isRetryableError, isString, jwtGuard, jwtHandshakeGuard, max, memExtension, middleware, min, mindset, mindsetModule, modelInfo, num, numArr, obj, onDelete, onGet, onPost, onPut, onSocketEvent, parseQueryMethodName, pgExtension, pgStorage, query, queryExtension, readJsonFromFile, repository, resolveConfigReferences, restController, run, runChatAdapters, runChatControllers, runCmdClient, runCommandHandlers, runCronHandlers, runRestControllers, runSocketControllers, safeJsonParse, scanProjectFiles, scoped, setupErrorHandlers, singleton, socket, socketChannelName, socketController, stopCommandHandlers, stopCronHandlers, str, strArr, telegram, telegramChannelName, transaction, validateAndTransform, validateArray, validateIsBoolean, validateIsDate, validateIsIn, validateIsNotEmpty, validateIsNumber, validateIsPresent, validateIsRecord, validateIsString, validateMax, validateMin, validateModel, wasender, wasenderChannelName, withPgClient, withPgTransaction, writeJsonToFile };
|
package/dist/src/index.js
CHANGED
|
@@ -101,7 +101,7 @@ export { getClientMap, pgStorage } from './feature/pg/pgStorage.js';
|
|
|
101
101
|
export { buildQuerySql } from './feature/pg/buildQuerySql.js';
|
|
102
102
|
export { getPgClient, withPgClient } from './feature/pg/withPgClient.js';
|
|
103
103
|
export { withPgTransaction } from './feature/pg/withPgTransaction.js';
|
|
104
|
-
export {
|
|
104
|
+
export { memExtension } from './feature/repository/@memExtension.js';
|
|
105
105
|
export { query } from './feature/repository/@query.js';
|
|
106
106
|
export { queryExtension } from './feature/repository/@queryExtension.js';
|
|
107
107
|
export { repository } from './feature/repository/@repository.js';
|