simplex-chat 7.0.2 → 7.1.0-beta.4
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/binding.gyp +2 -0
- package/cpp/simplex.cc +265 -29
- package/cpp/simplex.h +2 -0
- package/dist/api.d.ts +3 -64
- package/dist/api.js +8 -106
- package/dist/api.js.map +1 -1
- package/dist/bot.d.ts +4 -2
- package/dist/bot.js +1 -1
- package/dist/bot.js.map +1 -1
- package/dist/util.js +1 -1
- package/dist/util.js.map +1 -1
- package/docs/Namespace.bot.md +1 -0
- package/docs/api.Class.ChatApi.md +122 -78
- package/docs/bot.Function.run.md +1 -1
- package/docs/bot.Function.subscribeChatItems.md +27 -0
- package/docs/bot.Interface.BotConfig.md +7 -7
- package/docs/bot.Interface.BotOptions.md +10 -10
- package/docs/bot.TypeAlias.BotDbOpts.md +4 -0
- package/docs/core.Class.ChatAPIError.md +4 -4
- package/docs/core.Class.ChatInitError.md +4 -4
- package/docs/core.DBMigrationError.Interface.ErrorMigration.md +4 -4
- package/docs/core.DBMigrationError.Interface.ErrorNotADatabase.md +3 -3
- package/docs/core.DBMigrationError.Interface.ErrorSQL.md +4 -4
- package/docs/core.DBMigrationError.Interface.InvalidConfirmation.md +2 -2
- package/docs/core.DBMigrationError.Interface.InvalidQueueSize.md +25 -0
- package/docs/core.DBMigrationError.TypeAlias.Tag.md +2 -2
- package/docs/core.Enumeration.MigrationConfirmation.md +5 -5
- package/docs/core.Function.chatCloseStore.md +1 -1
- package/docs/core.Function.chatDecryptFile.md +1 -1
- package/docs/core.Function.chatEncryptFile.md +1 -1
- package/docs/core.Function.chatMigrateInit.md +8 -2
- package/docs/core.Function.chatReadFile.md +3 -3
- package/docs/core.Function.chatRecvMsgWait.md +1 -1
- package/docs/core.Function.chatSendCmd.md +1 -1
- package/docs/core.Function.chatWriteFile.md +2 -2
- package/docs/core.Interface.APIResult.md +3 -3
- package/docs/core.Interface.CryptoArgs.md +3 -3
- package/docs/core.Interface.UpMigration.md +3 -3
- package/docs/core.MTRError.Interface.MTREDifferent.md +3 -3
- package/docs/core.MTRError.Interface.MTRENoDown.md +10 -10
- package/docs/core.MTRError.TypeAlias.Tag.md +1 -1
- package/docs/core.MigrationError.Interface.MEDowngrade.md +3 -3
- package/docs/core.MigrationError.Interface.MEUpgrade.md +4 -4
- package/docs/core.MigrationError.Interface.MigrationError.md +3 -3
- package/docs/core.MigrationError.TypeAlias.Tag.md +1 -1
- package/docs/core.Namespace.DBMigrationError.md +1 -0
- package/docs/core.TypeAlias.DBMigrationError.md +2 -2
- package/docs/core.TypeAlias.MTRError.md +1 -1
- package/docs/core.TypeAlias.MigrationError.md +1 -1
- package/package.json +2 -2
- package/src/api.ts +40 -22
- package/src/bot.ts +17 -30
- package/src/core.ts +15 -7
- package/src/download-libs.js +28 -1
- package/src/simplex.d.ts +3 -2
- package/src/util.ts +1 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# Interface: MTRENoDown
|
|
8
8
|
|
|
9
|
-
Defined in: [src/core.ts:
|
|
9
|
+
Defined in: [src/core.ts:209](../src/core.ts#L209)
|
|
10
10
|
|
|
11
11
|
## Extends
|
|
12
12
|
|
|
@@ -14,20 +14,20 @@ Defined in: [src/core.ts:201](../src/core.ts#L201)
|
|
|
14
14
|
|
|
15
15
|
## Properties
|
|
16
16
|
|
|
17
|
-
###
|
|
17
|
+
### dbMigrations
|
|
18
18
|
|
|
19
|
-
> **
|
|
19
|
+
> **dbMigrations**: `string`[]
|
|
20
20
|
|
|
21
|
-
Defined in: [src/core.ts:
|
|
21
|
+
Defined in: [src/core.ts:211](../src/core.ts#L211)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
***
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
### type
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
> **type**: `"noDown"`
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
Defined in: [src/core.ts:210](../src/core.ts#L210)
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
#### Overrides
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
`Interface.type`
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# Interface: MEDowngrade
|
|
8
8
|
|
|
9
|
-
Defined in: [src/core.ts:
|
|
9
|
+
Defined in: [src/core.ts:182](../src/core.ts#L182)
|
|
10
10
|
|
|
11
11
|
## Extends
|
|
12
12
|
|
|
@@ -18,7 +18,7 @@ Defined in: [src/core.ts:174](../src/core.ts#L174)
|
|
|
18
18
|
|
|
19
19
|
> **downMigrations**: `string`[]
|
|
20
20
|
|
|
21
|
-
Defined in: [src/core.ts:
|
|
21
|
+
Defined in: [src/core.ts:184](../src/core.ts#L184)
|
|
22
22
|
|
|
23
23
|
***
|
|
24
24
|
|
|
@@ -26,7 +26,7 @@ Defined in: [src/core.ts:176](../src/core.ts#L176)
|
|
|
26
26
|
|
|
27
27
|
> **type**: `"downgrade"`
|
|
28
28
|
|
|
29
|
-
Defined in: [src/core.ts:
|
|
29
|
+
Defined in: [src/core.ts:183](../src/core.ts#L183)
|
|
30
30
|
|
|
31
31
|
#### Overrides
|
|
32
32
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# Interface: MEUpgrade
|
|
8
8
|
|
|
9
|
-
Defined in: [src/core.ts:
|
|
9
|
+
Defined in: [src/core.ts:177](../src/core.ts#L177)
|
|
10
10
|
|
|
11
11
|
## Extends
|
|
12
12
|
|
|
@@ -18,7 +18,7 @@ Defined in: [src/core.ts:169](../src/core.ts#L169)
|
|
|
18
18
|
|
|
19
19
|
> **type**: `"upgrade"`
|
|
20
20
|
|
|
21
|
-
Defined in: [src/core.ts:
|
|
21
|
+
Defined in: [src/core.ts:178](../src/core.ts#L178)
|
|
22
22
|
|
|
23
23
|
#### Overrides
|
|
24
24
|
|
|
@@ -28,6 +28,6 @@ Defined in: [src/core.ts:170](../src/core.ts#L170)
|
|
|
28
28
|
|
|
29
29
|
### upMigrations
|
|
30
30
|
|
|
31
|
-
> **upMigrations**: [`UpMigration`](core.Interface.UpMigration.md)
|
|
31
|
+
> **upMigrations**: [`UpMigration`](core.Interface.UpMigration.md)[]
|
|
32
32
|
|
|
33
|
-
Defined in: [src/core.ts:
|
|
33
|
+
Defined in: [src/core.ts:179](../src/core.ts#L179)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# Interface: MigrationError
|
|
8
8
|
|
|
9
|
-
Defined in: [src/core.ts:
|
|
9
|
+
Defined in: [src/core.ts:187](../src/core.ts#L187)
|
|
10
10
|
|
|
11
11
|
## Extends
|
|
12
12
|
|
|
@@ -18,7 +18,7 @@ Defined in: [src/core.ts:179](../src/core.ts#L179)
|
|
|
18
18
|
|
|
19
19
|
> **mtrError**: [`MTRError`](core.TypeAlias.MTRError.md)
|
|
20
20
|
|
|
21
|
-
Defined in: [src/core.ts:
|
|
21
|
+
Defined in: [src/core.ts:189](../src/core.ts#L189)
|
|
22
22
|
|
|
23
23
|
***
|
|
24
24
|
|
|
@@ -26,7 +26,7 @@ Defined in: [src/core.ts:181](../src/core.ts#L181)
|
|
|
26
26
|
|
|
27
27
|
> **type**: `"migrationError"`
|
|
28
28
|
|
|
29
|
-
Defined in: [src/core.ts:
|
|
29
|
+
Defined in: [src/core.ts:188](../src/core.ts#L188)
|
|
30
30
|
|
|
31
31
|
#### Overrides
|
|
32
32
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
- [ErrorNotADatabase](core.DBMigrationError.Interface.ErrorNotADatabase.md)
|
|
13
13
|
- [ErrorSQL](core.DBMigrationError.Interface.ErrorSQL.md)
|
|
14
14
|
- [InvalidConfirmation](core.DBMigrationError.Interface.InvalidConfirmation.md)
|
|
15
|
+
- [InvalidQueueSize](core.DBMigrationError.Interface.InvalidQueueSize.md)
|
|
15
16
|
|
|
16
17
|
## Type Aliases
|
|
17
18
|
|
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
# Type Alias: DBMigrationError
|
|
8
8
|
|
|
9
|
-
> **DBMigrationError** = [`InvalidConfirmation`](core.DBMigrationError.Interface.InvalidConfirmation.md) \| [`ErrorNotADatabase`](core.DBMigrationError.Interface.ErrorNotADatabase.md) \| [`ErrorMigration`](core.DBMigrationError.Interface.ErrorMigration.md) \| [`ErrorSQL`](core.DBMigrationError.Interface.ErrorSQL.md)
|
|
9
|
+
> **DBMigrationError** = [`InvalidConfirmation`](core.DBMigrationError.Interface.InvalidConfirmation.md) \| [`InvalidQueueSize`](core.DBMigrationError.Interface.InvalidQueueSize.md) \| [`ErrorNotADatabase`](core.DBMigrationError.Interface.ErrorNotADatabase.md) \| [`ErrorMigration`](core.DBMigrationError.Interface.ErrorMigration.md) \| [`ErrorSQL`](core.DBMigrationError.Interface.ErrorSQL.md)
|
|
10
10
|
|
|
11
|
-
Defined in: [src/core.ts:
|
|
11
|
+
Defined in: [src/core.ts:125](../src/core.ts#L125)
|
|
@@ -8,4 +8,4 @@
|
|
|
8
8
|
|
|
9
9
|
> **MigrationError** = [`MEUpgrade`](core.MigrationError.Interface.MEUpgrade.md) \| [`MEDowngrade`](core.MigrationError.Interface.MEDowngrade.md) \| [`MigrationError`](core.MigrationError.Interface.MigrationError.md)
|
|
10
10
|
|
|
11
|
-
Defined in: [src/core.ts:
|
|
11
|
+
Defined in: [src/core.ts:165](../src/core.ts#L165)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "simplex-chat",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.1.0-beta.4",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"docs": "typedoc"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@simplex-chat/types": "^0.
|
|
27
|
+
"@simplex-chat/types": "^0.11.4",
|
|
28
28
|
"extract-zip": "^2.0.1",
|
|
29
29
|
"fast-deep-equal": "^3.1.3",
|
|
30
30
|
"node-addon-api": "^8.5.0"
|
package/src/api.ts
CHANGED
|
@@ -106,13 +106,15 @@ export class ChatApi {
|
|
|
106
106
|
* Initializes the ChatApi.
|
|
107
107
|
* @param {DbConfig} db - Database configuration (sqlite or postgres).
|
|
108
108
|
* @param {core.MigrationConfirmation} [confirm=core.MigrationConfirmation.YesUp] - Migration confirmation mode.
|
|
109
|
+
* @param {number} [queueSize] - Size of internal queues, the core default is used when omitted.
|
|
109
110
|
*/
|
|
110
111
|
static async init(
|
|
111
112
|
db: DbConfig,
|
|
112
|
-
confirm = core.MigrationConfirmation.YesUp
|
|
113
|
+
confirm = core.MigrationConfirmation.YesUp,
|
|
114
|
+
queueSize?: number
|
|
113
115
|
): Promise<ChatApi> {
|
|
114
116
|
const [path, key] = dbConfigToMigrateArgs(db)
|
|
115
|
-
const ctrl = await core.chatMigrateInit(path, key, confirm)
|
|
117
|
+
const ctrl = await core.chatMigrateInit(path, key, confirm, queueSize)
|
|
116
118
|
return new ChatApi(ctrl)
|
|
117
119
|
}
|
|
118
120
|
|
|
@@ -120,39 +122,52 @@ export class ChatApi {
|
|
|
120
122
|
* Start chat controller. Must be called with the existing user profile.
|
|
121
123
|
*/
|
|
122
124
|
async startChat(): Promise<void> {
|
|
125
|
+
if (this.eventsLoop) throw new Error("chat already started")
|
|
126
|
+
const ctrl = this.ctrl
|
|
123
127
|
this.receiveEvents = true
|
|
124
128
|
this.eventsLoop = this.runEventsLoop()
|
|
125
|
-
|
|
129
|
+
let r: ChatResponse
|
|
130
|
+
try {
|
|
131
|
+
r = await core.chatSendCmd(ctrl, CC.StartChat.cmdString({mainApp: true, enableSndFiles: true, serviceRequests: false}))
|
|
132
|
+
} catch (e) {
|
|
133
|
+
await this.stopEventsLoop()
|
|
134
|
+
throw e
|
|
135
|
+
}
|
|
126
136
|
if (r.type !== "chatStarted" && r.type !== "chatRunning") {
|
|
137
|
+
await this.stopEventsLoop()
|
|
127
138
|
throw new ChatCommandError("error starting chat", r)
|
|
128
139
|
}
|
|
129
140
|
}
|
|
130
|
-
|
|
141
|
+
|
|
131
142
|
/**
|
|
132
143
|
* Stop chat controller.
|
|
133
|
-
*
|
|
144
|
+
* `close` calls it before closing the database.
|
|
134
145
|
* Usually doesn't need to be called in chat bots.
|
|
135
146
|
*/
|
|
136
147
|
async stopChat(): Promise<void> {
|
|
137
148
|
const r = await this.sendChatCmd("/_stop")
|
|
138
|
-
if (r.type !== "chatStopped") throw new ChatCommandError("error
|
|
139
|
-
this.
|
|
140
|
-
if (this.eventsLoop) await this.eventsLoop
|
|
141
|
-
this.eventsLoop = undefined
|
|
149
|
+
if (r.type !== "chatStopped") throw new ChatCommandError("error stopping chat", r)
|
|
150
|
+
await this.stopEventsLoop()
|
|
142
151
|
}
|
|
143
152
|
|
|
144
153
|
/**
|
|
145
|
-
*
|
|
154
|
+
* Stop chat controller and close chat database.
|
|
155
|
+
* The database is not closed if stopping fails.
|
|
146
156
|
* Usually doesn't need to be called in chat bots.
|
|
147
157
|
*/
|
|
148
158
|
async close(): Promise<void> {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
this.eventsLoop = undefined
|
|
159
|
+
// a running controller keeps using the database connections that closing frees
|
|
160
|
+
await this.stopChat()
|
|
152
161
|
await core.chatCloseStore(this.ctrl)
|
|
153
162
|
this.ctrl_ = undefined
|
|
154
163
|
}
|
|
155
|
-
|
|
164
|
+
|
|
165
|
+
private async stopEventsLoop(): Promise<void> {
|
|
166
|
+
this.receiveEvents = false
|
|
167
|
+
if (this.eventsLoop) await this.eventsLoop
|
|
168
|
+
this.eventsLoop = undefined
|
|
169
|
+
}
|
|
170
|
+
|
|
156
171
|
private async runEventsLoop(): Promise<void> {
|
|
157
172
|
while (this.receiveEvents) {
|
|
158
173
|
try {
|
|
@@ -335,7 +350,7 @@ export class ChatApi {
|
|
|
335
350
|
return await core.chatSendCmd(this.ctrl, cmd)
|
|
336
351
|
}
|
|
337
352
|
|
|
338
|
-
async recvChatEvent(wait: number =
|
|
353
|
+
async recvChatEvent(wait: number = 500_000): Promise<ChatEvent | undefined> {
|
|
339
354
|
return await core.chatRecvMsgWait(this.ctrl, wait)
|
|
340
355
|
}
|
|
341
356
|
|
|
@@ -386,8 +401,10 @@ export class ChatApi {
|
|
|
386
401
|
switch (r.type) {
|
|
387
402
|
case "userProfileUpdated":
|
|
388
403
|
return r.updateSummary
|
|
404
|
+
case "userProfileNoChange":
|
|
405
|
+
return {updateSuccesses: 0, updateFailures: 0, changedContacts: []}
|
|
389
406
|
default:
|
|
390
|
-
throw new ChatCommandError("error
|
|
407
|
+
throw new ChatCommandError("error setting profile address", r)
|
|
391
408
|
}
|
|
392
409
|
}
|
|
393
410
|
|
|
@@ -460,7 +477,7 @@ export class ChatApi {
|
|
|
460
477
|
updatedMessage: {msgContent, mentions: {}},
|
|
461
478
|
})
|
|
462
479
|
)
|
|
463
|
-
if (r.type === "chatItemUpdated") return r.chatItem.chatItem
|
|
480
|
+
if (r.type === "chatItemUpdated" || r.type === "chatItemNotChanged") return r.chatItem.chatItem
|
|
464
481
|
throw new ChatCommandError("error updating chat item", r)
|
|
465
482
|
}
|
|
466
483
|
|
|
@@ -499,10 +516,10 @@ export class ChatApi {
|
|
|
499
516
|
chatItemId: number,
|
|
500
517
|
add: boolean,
|
|
501
518
|
reaction: T.MsgReaction
|
|
502
|
-
) {
|
|
519
|
+
): Promise<T.ACIReaction> {
|
|
503
520
|
const r = await this.sendChatCmd(CC.APIChatItemReaction.cmdString({chatRef: {chatType, chatId}, chatItemId, add, reaction}))
|
|
504
|
-
if (r.type === "
|
|
505
|
-
throw new ChatCommandError("error setting item reaction", r)
|
|
521
|
+
if (r.type === "chatItemReaction") return r.reaction
|
|
522
|
+
throw new ChatCommandError("error setting item reaction", r)
|
|
506
523
|
}
|
|
507
524
|
|
|
508
525
|
/**
|
|
@@ -512,6 +529,7 @@ export class ChatApi {
|
|
|
512
529
|
async apiReceiveFile(fileId: number): Promise<T.AChatItem> {
|
|
513
530
|
const r = await this.sendChatCmd(CC.ReceiveFile.cmdString({fileId, userApprovedRelays: true}))
|
|
514
531
|
if (r.type === "rcvFileAccepted") return r.chatItem
|
|
532
|
+
if (r.type === "rcvFileAcceptedSndCancelled") throw new ChatCommandError("file cancelled by sender", r)
|
|
515
533
|
throw new ChatCommandError("error receiving file", r)
|
|
516
534
|
}
|
|
517
535
|
|
|
@@ -698,7 +716,7 @@ export class ChatApi {
|
|
|
698
716
|
* Connect via prepared SimpleX link. The link can be 1-time invitation link, contact address or group link
|
|
699
717
|
* Network usage: interactive.
|
|
700
718
|
*/
|
|
701
|
-
async apiConnect(userId: number, incognito: boolean, preparedLink
|
|
719
|
+
async apiConnect(userId: number, incognito: boolean, preparedLink: T.CreatedConnLink): Promise<ConnReqType> {
|
|
702
720
|
const r = await this.sendChatCmd(CC.APIConnect.cmdString({userId, incognito, preparedLink_: preparedLink}))
|
|
703
721
|
return this.handleConnectResult(r)
|
|
704
722
|
}
|
|
@@ -740,7 +758,7 @@ export class ChatApi {
|
|
|
740
758
|
* Network usage: no.
|
|
741
759
|
*/
|
|
742
760
|
async apiRejectContactRequest(contactReqId: number): Promise<void> {
|
|
743
|
-
const r = await this.sendChatCmd(CC.APIRejectContact.cmdString({contactReqId}))
|
|
761
|
+
const r = await this.sendChatCmd(CC.APIRejectContact.cmdString({contactReqId, notify: false}))
|
|
744
762
|
if (r.type === "contactRequestRejected") return
|
|
745
763
|
throw new ChatCommandError("error rejecting contact request", r)
|
|
746
764
|
}
|
package/src/bot.ts
CHANGED
|
@@ -6,6 +6,7 @@ import equal = require("fast-deep-equal")
|
|
|
6
6
|
|
|
7
7
|
export type BotDbOpts = api.DbConfig & {
|
|
8
8
|
confirmMigrations?: core.MigrationConfirmation
|
|
9
|
+
queueSize?: number
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
export interface BotOptions {
|
|
@@ -45,10 +46,9 @@ export interface BotConfig {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
export async function run({profile, dbOpts, options = defaultOpts, onMessage, onCommands = {}, events = {}}: BotConfig): Promise<[api.ChatApi, T.User, T.UserContactLink | undefined]> {
|
|
48
|
-
const bot = await api.ChatApi.init(dbOpts, dbOpts.confirmMigrations || core.MigrationConfirmation.YesUp)
|
|
49
|
+
const bot = await api.ChatApi.init(dbOpts, dbOpts.confirmMigrations || core.MigrationConfirmation.YesUp, dbOpts.queueSize)
|
|
49
50
|
const opts = fullOptions(options)
|
|
50
|
-
if (onMessage)
|
|
51
|
-
if (Object.keys(onCommands).length > 0) subscribeCommands(bot, onCommands)
|
|
51
|
+
if (onMessage || Object.keys(onCommands).length > 0) subscribeChatItems(bot, onMessage, onCommands)
|
|
52
52
|
if (Object.keys(events).length > 0) bot.on(events)
|
|
53
53
|
subscribeLogEvents(bot, opts)
|
|
54
54
|
const botProfile = mkBotProfile(profile, opts)
|
|
@@ -105,38 +105,25 @@ function mkBotProfile(profile: T.Profile, opts: Required<BotOptions>): T.Profile
|
|
|
105
105
|
return profile
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
function
|
|
108
|
+
export function subscribeChatItems(
|
|
109
|
+
bot: api.ChatApi,
|
|
110
|
+
onMessage: ((chatItem: T.AChatItem, content: T.MsgContent) => void | Promise<void>) | undefined,
|
|
111
|
+
commands: {[K in string]?: ((chatItem: T.AChatItem, command: util.BotCommand) => void | Promise<void>)}
|
|
112
|
+
) {
|
|
109
113
|
bot.on("newChatItems", async ({chatItems}) => {
|
|
110
114
|
for (const ci of chatItems) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const p = onMessage(ci, ci.chatItem.content.msgContent)
|
|
114
|
-
if (p instanceof Promise) await p
|
|
115
|
-
} catch (e) {
|
|
116
|
-
console.log("message processing error", e)
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function subscribeCommands(bot: api.ChatApi, commands: {[K in string]?: ((chatItem: T.AChatItem, command: util.BotCommand) => void | Promise<void>)}) {
|
|
124
|
-
bot.on("newChatItems", async (evt) => {
|
|
125
|
-
for (const ci of evt.chatItems) {
|
|
115
|
+
const content = ci.chatItem.content
|
|
116
|
+
if (content.type !== "rcvMsgContent") continue
|
|
126
117
|
const cmd = util.ciBotCommand(ci.chatItem)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (cmdFunc)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
} catch(e) {
|
|
134
|
-
console.log(`${cmd} command processing error`, e)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
118
|
+
const cmdFunc = cmd && (commands[cmd.keyword] || commands[""])
|
|
119
|
+
try {
|
|
120
|
+
if (cmd && cmdFunc) await cmdFunc(ci, cmd)
|
|
121
|
+
else if (onMessage) await onMessage(ci, content.msgContent)
|
|
122
|
+
} catch (e) {
|
|
123
|
+
console.log(cmd && cmdFunc ? `${cmd.keyword} command processing error` : "message processing error", e)
|
|
137
124
|
}
|
|
138
125
|
}
|
|
139
|
-
})
|
|
126
|
+
})
|
|
140
127
|
}
|
|
141
128
|
|
|
142
129
|
function subscribeLogEvents(bot: api.ChatApi, opts: Required<BotOptions>) {
|
package/src/core.ts
CHANGED
|
@@ -3,9 +3,12 @@ import * as simplex from "./simplex"
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Initialize chat controller
|
|
6
|
+
* @param {number} [queueSize] - Size of internal queues, the core default is used when omitted.
|
|
6
7
|
*/
|
|
7
|
-
export async function chatMigrateInit(dbPath: string, dbKey: string, confirm: MigrationConfirmation): Promise<bigint> {
|
|
8
|
-
const [ctrl, res] =
|
|
8
|
+
export async function chatMigrateInit(dbPath: string, dbKey: string, confirm: MigrationConfirmation, queueSize?: number): Promise<bigint> {
|
|
9
|
+
const [ctrl, res] = queueSize === undefined
|
|
10
|
+
? await simplex.chat_migrate_init(dbPath, dbKey, confirm)
|
|
11
|
+
: await simplex.chat_migrate_init_queue(dbPath, dbKey, confirm, queueSize)
|
|
9
12
|
const json = JSON.parse(res)
|
|
10
13
|
if (json.type === 'ok') return ctrl
|
|
11
14
|
throw new ChatInitError("Database or migration error (see dbMigrationError property)", json as DBMigrationError)
|
|
@@ -47,7 +50,7 @@ export async function chatRecvMsgWait(ctrl: bigint, wait: number): Promise<ChatE
|
|
|
47
50
|
/**
|
|
48
51
|
* Write buffer to encrypted file
|
|
49
52
|
*/
|
|
50
|
-
export async function chatWriteFile(ctrl: bigint, path: string, buffer: ArrayBuffer): Promise<CryptoArgs> {
|
|
53
|
+
export async function chatWriteFile(ctrl: bigint, path: string, buffer: ArrayBuffer | Uint8Array): Promise<CryptoArgs> {
|
|
51
54
|
const res = await simplex.chat_write_file(ctrl, path, buffer)
|
|
52
55
|
return cryptoArgsResult(res)
|
|
53
56
|
}
|
|
@@ -55,7 +58,7 @@ export async function chatWriteFile(ctrl: bigint, path: string, buffer: ArrayBuf
|
|
|
55
58
|
/**
|
|
56
59
|
* Read buffer from encrypted file
|
|
57
60
|
*/
|
|
58
|
-
export async function chatReadFile(path: string, {fileKey, fileNonce}: CryptoArgs): Promise<
|
|
61
|
+
export async function chatReadFile(path: string, {fileKey, fileNonce}: CryptoArgs): Promise<Buffer> {
|
|
59
62
|
return await simplex.chat_read_file(path, fileKey, fileNonce)
|
|
60
63
|
}
|
|
61
64
|
|
|
@@ -121,12 +124,13 @@ export class ChatInitError extends Error {
|
|
|
121
124
|
|
|
122
125
|
export type DBMigrationError =
|
|
123
126
|
| DBMigrationError.InvalidConfirmation
|
|
127
|
+
| DBMigrationError.InvalidQueueSize
|
|
124
128
|
| DBMigrationError.ErrorNotADatabase // invalid/corrupt database file or incorrect encryption key
|
|
125
129
|
| DBMigrationError.ErrorMigration
|
|
126
130
|
| DBMigrationError.ErrorSQL
|
|
127
131
|
|
|
128
132
|
export namespace DBMigrationError {
|
|
129
|
-
export type Tag = "invalidConfirmation" | "errorNotADatabase" | "errorMigration" | "errorSQL"
|
|
133
|
+
export type Tag = "invalidConfirmation" | "invalidQueueSize" | "errorNotADatabase" | "errorMigration" | "errorSQL"
|
|
130
134
|
|
|
131
135
|
interface Interface {
|
|
132
136
|
type: Tag
|
|
@@ -136,6 +140,10 @@ export namespace DBMigrationError {
|
|
|
136
140
|
type: "invalidConfirmation"
|
|
137
141
|
}
|
|
138
142
|
|
|
143
|
+
export interface InvalidQueueSize extends Interface {
|
|
144
|
+
type: "invalidQueueSize"
|
|
145
|
+
}
|
|
146
|
+
|
|
139
147
|
export interface ErrorNotADatabase extends Interface {
|
|
140
148
|
type: "errorNotADatabase"
|
|
141
149
|
dbFile: string
|
|
@@ -168,7 +176,7 @@ export namespace MigrationError {
|
|
|
168
176
|
|
|
169
177
|
export interface MEUpgrade extends Interface {
|
|
170
178
|
type: "upgrade"
|
|
171
|
-
upMigrations: UpMigration
|
|
179
|
+
upMigrations: UpMigration[]
|
|
172
180
|
}
|
|
173
181
|
|
|
174
182
|
export interface MEDowngrade extends Interface {
|
|
@@ -200,7 +208,7 @@ export namespace MTRError {
|
|
|
200
208
|
|
|
201
209
|
export interface MTRENoDown extends Interface {
|
|
202
210
|
type: "noDown"
|
|
203
|
-
|
|
211
|
+
dbMigrations: string[]
|
|
204
212
|
}
|
|
205
213
|
|
|
206
214
|
export interface MTREDifferent extends Interface {
|
package/src/download-libs.js
CHANGED
|
@@ -4,8 +4,12 @@ const path = require('path');
|
|
|
4
4
|
const extract = require('extract-zip');
|
|
5
5
|
|
|
6
6
|
const GITHUB_REPO = 'simplex-chat/simplex-chat-libs';
|
|
7
|
-
const RELEASE_TAG = 'v7.0.
|
|
7
|
+
const RELEASE_TAG = 'v7.1.0-beta.4';
|
|
8
8
|
const BACKEND = (process.env.SIMPLEX_BACKEND || process.env.npm_config_simplex_backend || 'sqlite').toLowerCase();
|
|
9
|
+
// A locally built libsimplex, copied into libs/ rather than loaded in place:
|
|
10
|
+
// the addon's RUNPATH is $ORIGIN/../../libs.
|
|
11
|
+
const LIBS_DIR_OVERRIDE = process.env.SIMPLEX_LIBS_DIR || process.env.npm_config_simplex_libs_dir;
|
|
12
|
+
const LIB_NAMES = ['libsimplex.so', 'libsimplex.dylib', 'libsimplex.dll'];
|
|
9
13
|
|
|
10
14
|
if (BACKEND !== 'sqlite' && BACKEND !== 'postgres') {
|
|
11
15
|
console.error(`✗ Invalid SIMPLEX_BACKEND: "${BACKEND}". Must be "sqlite" or "postgres".`);
|
|
@@ -83,8 +87,31 @@ function isAlreadyInstalled() {
|
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
89
|
|
|
90
|
+
// No version check: the files behind SIMPLEX_LIBS_DIR change on every rebuild.
|
|
91
|
+
function installFromOverride() {
|
|
92
|
+
if (!fs.existsSync(LIBS_DIR_OVERRIDE)) {
|
|
93
|
+
throw new Error(`SIMPLEX_LIBS_DIR does not exist: ${LIBS_DIR_OVERRIDE}`);
|
|
94
|
+
}
|
|
95
|
+
const lib = LIB_NAMES.find((name) => fs.existsSync(path.join(LIBS_DIR_OVERRIDE, name)));
|
|
96
|
+
if (!lib) {
|
|
97
|
+
throw new Error(`No ${LIB_NAMES.join(' / ')} in SIMPLEX_LIBS_DIR: ${LIBS_DIR_OVERRIDE}`);
|
|
98
|
+
}
|
|
99
|
+
console.log(`Using libraries from SIMPLEX_LIBS_DIR: ${LIBS_DIR_OVERRIDE}`);
|
|
100
|
+
cleanLibsDirectory();
|
|
101
|
+
copyDirSync(LIBS_DIR_OVERRIDE, LIBS_DIR);
|
|
102
|
+
// Not a release tag: a later install without the variable sees a mismatch
|
|
103
|
+
// and replaces these files with the released ones.
|
|
104
|
+
fs.writeFileSync(INSTALLED_FILE, `${LIBS_DIR_OVERRIDE}:${BACKEND}`, 'utf-8');
|
|
105
|
+
console.log(`✓ Installed ${lib} and its runtime libraries from ${LIBS_DIR_OVERRIDE}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
86
108
|
async function install() {
|
|
87
109
|
try {
|
|
110
|
+
if (LIBS_DIR_OVERRIDE) {
|
|
111
|
+
installFromOverride();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
88
115
|
// Check if already installed
|
|
89
116
|
if (isAlreadyInstalled()) {
|
|
90
117
|
return;
|
package/src/simplex.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// These functions are defined in CPP add-on ../cpp/simplex.cc
|
|
2
2
|
|
|
3
3
|
export function chat_migrate_init(dbPath: string, dbKey: string, confirm: string): Promise<[bigint, string]>
|
|
4
|
+
export function chat_migrate_init_queue(dbPath: string, dbKey: string, confirm: string, queueSize: number): Promise<[bigint, string]>
|
|
4
5
|
export function chat_close_store(ctrl: bigint): Promise<string>
|
|
5
6
|
export function chat_send_cmd(ctrl: bigint, cmd: string): Promise<string>
|
|
6
7
|
export function chat_recv_msg_wait(ctrl: bigint, wait: number): Promise<string>
|
|
7
|
-
export function chat_write_file(ctrl: bigint, path: string, buffer: ArrayBuffer): Promise<string>
|
|
8
|
-
export function chat_read_file(path: string, key: string, nonce: string): Promise<
|
|
8
|
+
export function chat_write_file(ctrl: bigint, path: string, buffer: ArrayBuffer | Uint8Array): Promise<string>
|
|
9
|
+
export function chat_read_file(path: string, key: string, nonce: string): Promise<Buffer>
|
|
9
10
|
export function chat_encrypt_file(ctrl: bigint, fromPath: string, toPath: string): Promise<string>
|
|
10
11
|
export function chat_decrypt_file(fromPath: string, key: string, nonce: string, toPath: string): Promise<string>
|
package/src/util.ts
CHANGED
|
@@ -78,7 +78,7 @@ export interface BotCommand {
|
|
|
78
78
|
export function ciBotCommand(chatItem: T.ChatItem): BotCommand | undefined {
|
|
79
79
|
const msg = ciContentText(chatItem)?.trim()
|
|
80
80
|
if (msg) {
|
|
81
|
-
const r = msg.match(/^\/([^\s]+)(
|
|
81
|
+
const r = msg.match(/^\/([^\s]+)([\s\S]*)/)
|
|
82
82
|
if (r && r.length >= 3) {
|
|
83
83
|
return {keyword: r[1], params: r[2].trim()}
|
|
84
84
|
}
|