@leemour/max-cli 0.5.0 → 0.7.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.
- package/README.md +22 -5
- package/dist/cache/index.d.ts +1 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +4 -4
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/store.d.ts.map +1 -1
- package/dist/cache/store.js +1 -0
- package/dist/cache/store.js.map +1 -1
- package/dist/client.d.ts +230 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +959 -78
- package/dist/client.js.map +1 -1
- package/dist/commands/account.d.ts.map +1 -1
- package/dist/commands/account.js +71 -3
- package/dist/commands/account.js.map +1 -1
- package/dist/commands/chats.d.ts.map +1 -1
- package/dist/commands/chats.js +159 -0
- package/dist/commands/chats.js.map +1 -1
- package/dist/commands/commands.d.ts +8 -0
- package/dist/commands/commands.d.ts.map +1 -0
- package/dist/commands/commands.js +36 -0
- package/dist/commands/commands.js.map +1 -0
- package/dist/commands/complete.d.ts +10 -0
- package/dist/commands/complete.d.ts.map +1 -0
- package/dist/commands/complete.js +89 -0
- package/dist/commands/complete.js.map +1 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +6 -2
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/contacts.d.ts +3 -0
- package/dist/commands/contacts.d.ts.map +1 -1
- package/dist/commands/contacts.js +85 -0
- package/dist/commands/contacts.js.map +1 -1
- package/dist/commands/context.d.ts +26 -1
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +47 -6
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/folders.d.ts +4 -0
- package/dist/commands/folders.d.ts.map +1 -0
- package/dist/commands/folders.js +76 -0
- package/dist/commands/folders.js.map +1 -0
- package/dist/commands/inbox.d.ts +14 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +90 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +17 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/messages.d.ts.map +1 -1
- package/dist/commands/messages.js +90 -4
- package/dist/commands/messages.js.map +1 -1
- package/dist/commands/reactions.d.ts +3 -0
- package/dist/commands/reactions.d.ts.map +1 -0
- package/dist/commands/reactions.js +43 -0
- package/dist/commands/reactions.js.map +1 -0
- package/dist/commands/recipients.d.ts +9 -0
- package/dist/commands/recipients.d.ts.map +1 -0
- package/dist/commands/recipients.js +68 -0
- package/dist/commands/recipients.js.map +1 -0
- package/dist/commands/sends.d.ts +4 -0
- package/dist/commands/sends.d.ts.map +1 -0
- package/dist/commands/sends.js +21 -0
- package/dist/commands/sends.js.map +1 -0
- package/dist/commands/serve.d.ts +10 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +50 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +84 -16
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/skill.d.ts.map +1 -1
- package/dist/commands/skill.js +2 -1
- package/dist/commands/skill.js.map +1 -1
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +53 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/watch.d.ts +9 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +68 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config.d.ts +24 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +43 -4
- package/dist/config.js.map +1 -1
- package/dist/domain/map.d.ts +10 -1
- package/dist/domain/map.d.ts.map +1 -1
- package/dist/domain/map.js +51 -1
- package/dist/domain/map.js.map +1 -1
- package/dist/domain/models.d.ts +80 -0
- package/dist/domain/models.d.ts.map +1 -1
- package/dist/domain/models.js.map +1 -1
- package/dist/generated/client.generated.d.ts +36 -0
- package/dist/generated/client.generated.d.ts.map +1 -1
- package/dist/generated/client.generated.js +36 -0
- package/dist/generated/client.generated.js.map +1 -1
- package/dist/generated/opcodes.generated.d.ts +37 -5
- package/dist/generated/opcodes.generated.d.ts.map +1 -1
- package/dist/generated/opcodes.generated.js +37 -5
- package/dist/generated/opcodes.generated.js.map +1 -1
- package/dist/generated/operations.generated.d.ts +245 -3
- package/dist/generated/operations.generated.d.ts.map +1 -1
- package/dist/generated/operations.generated.js +36 -4
- package/dist/generated/operations.generated.js.map +1 -1
- package/dist/markdown.d.ts +18 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +52 -0
- package/dist/markdown.js.map +1 -0
- package/dist/mcp/confirm.d.ts +24 -0
- package/dist/mcp/confirm.d.ts.map +1 -0
- package/dist/mcp/confirm.js +53 -0
- package/dist/mcp/confirm.js.map +1 -0
- package/dist/mcp/instructions.d.ts +10 -0
- package/dist/mcp/instructions.d.ts.map +1 -0
- package/dist/mcp/instructions.js +25 -0
- package/dist/mcp/instructions.js.map +1 -0
- package/dist/mcp/server.d.ts +23 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +38 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +28 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +91 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/tools.d.ts +8 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +274 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +27 -0
- package/dist/program.js.map +1 -1
- package/dist/protocol/connection.d.ts +10 -8
- package/dist/protocol/connection.d.ts.map +1 -1
- package/dist/protocol/connection.js +64 -7
- package/dist/protocol/connection.js.map +1 -1
- package/dist/protocol/frame.d.ts +2 -1
- package/dist/protocol/frame.d.ts.map +1 -1
- package/dist/protocol/frame.js.map +1 -1
- package/dist/rendering/messages.d.ts.map +1 -1
- package/dist/rendering/messages.js +21 -7
- package/dist/rendering/messages.js.map +1 -1
- package/dist/resolve.d.ts +15 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +48 -0
- package/dist/resolve.js.map +1 -0
- package/dist/sends/guard.d.ts +27 -0
- package/dist/sends/guard.d.ts.map +1 -0
- package/dist/sends/guard.js +52 -0
- package/dist/sends/guard.js.map +1 -0
- package/dist/sends/journal.d.ts +42 -0
- package/dist/sends/journal.d.ts.map +1 -0
- package/dist/sends/journal.js +40 -0
- package/dist/sends/journal.js.map +1 -0
- package/dist/sends/recipients.d.ts +29 -0
- package/dist/sends/recipients.d.ts.map +1 -0
- package/dist/sends/recipients.js +62 -0
- package/dist/sends/recipients.js.map +1 -0
- package/dist/server/lines.d.ts +9 -0
- package/dist/server/lines.d.ts.map +1 -0
- package/dist/server/lines.js +25 -0
- package/dist/server/lines.js.map +1 -0
- package/dist/server/server-connection.d.ts +35 -0
- package/dist/server/server-connection.d.ts.map +1 -0
- package/dist/server/server-connection.js +195 -0
- package/dist/server/server-connection.js.map +1 -0
- package/dist/server/server.d.ts +62 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +297 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/start.d.ts +12 -0
- package/dist/server/start.d.ts.map +1 -0
- package/dist/server/start.js +41 -0
- package/dist/server/start.js.map +1 -0
- package/dist/server/subscribe.d.ts +9 -0
- package/dist/server/subscribe.d.ts.map +1 -0
- package/dist/server/subscribe.js +26 -0
- package/dist/server/subscribe.js.map +1 -0
- package/dist/session/adopt.d.ts.map +1 -1
- package/dist/session/adopt.js +7 -6
- package/dist/session/adopt.js.map +1 -1
- package/dist/session/browser.d.ts +55 -0
- package/dist/session/browser.d.ts.map +1 -0
- package/dist/session/browser.js +319 -0
- package/dist/session/browser.js.map +1 -0
- package/dist/session/handshake.d.ts +2 -0
- package/dist/session/handshake.d.ts.map +1 -1
- package/dist/session/handshake.js +3 -1
- package/dist/session/handshake.js.map +1 -1
- package/dist/session/login.d.ts +20 -0
- package/dist/session/login.d.ts.map +1 -0
- package/dist/session/login.js +66 -0
- package/dist/session/login.js.map +1 -0
- package/dist/session/prompt.d.ts +3 -1
- package/dist/session/prompt.d.ts.map +1 -1
- package/dist/session/prompt.js +2 -2
- package/dist/session/prompt.js.map +1 -1
- package/dist/session/qr-terminal.d.ts +9 -0
- package/dist/session/qr-terminal.d.ts.map +1 -0
- package/dist/session/qr-terminal.js +34 -0
- package/dist/session/qr-terminal.js.map +1 -0
- package/dist/session/store.d.ts +4 -0
- package/dist/session/store.d.ts.map +1 -1
- package/dist/session/store.js +6 -0
- package/dist/session/store.js.map +1 -1
- package/dist/spec/define.d.ts.map +1 -1
- package/dist/spec/define.js +14 -1
- package/dist/spec/define.js.map +1 -1
- package/dist/spec/index.d.ts.map +1 -1
- package/dist/spec/index.js +38 -5
- package/dist/spec/index.js.map +1 -1
- package/dist/spec/operations/account.d.ts +20 -0
- package/dist/spec/operations/account.d.ts.map +1 -0
- package/dist/spec/operations/account.js +62 -0
- package/dist/spec/operations/account.js.map +1 -0
- package/dist/spec/operations/chats.d.ts +54 -0
- package/dist/spec/operations/chats.d.ts.map +1 -1
- package/dist/spec/operations/chats.js +121 -0
- package/dist/spec/operations/chats.js.map +1 -1
- package/dist/spec/operations/contacts.d.ts +19 -1
- package/dist/spec/operations/contacts.d.ts.map +1 -1
- package/dist/spec/operations/contacts.js +49 -6
- package/dist/spec/operations/contacts.js.map +1 -1
- package/dist/spec/operations/folders.d.ts +24 -0
- package/dist/spec/operations/folders.d.ts.map +1 -0
- package/dist/spec/operations/folders.js +64 -0
- package/dist/spec/operations/folders.js.map +1 -0
- package/dist/spec/operations/login.d.ts +64 -0
- package/dist/spec/operations/login.d.ts.map +1 -0
- package/dist/spec/operations/login.js +99 -0
- package/dist/spec/operations/login.js.map +1 -0
- package/dist/spec/operations/messages.d.ts +67 -3
- package/dist/spec/operations/messages.d.ts.map +1 -1
- package/dist/spec/operations/messages.js +126 -13
- package/dist/spec/operations/messages.js.map +1 -1
- package/dist/spec/operations/session.d.ts +7 -0
- package/dist/spec/operations/session.d.ts.map +1 -1
- package/dist/spec/operations/session.js +17 -0
- package/dist/spec/operations/session.js.map +1 -1
- package/dist/spec/operations/uploads.d.ts +18 -0
- package/dist/spec/operations/uploads.d.ts.map +1 -0
- package/dist/spec/operations/uploads.js +35 -0
- package/dist/spec/operations/uploads.js.map +1 -0
- package/dist/testing/mock-max.d.ts +15 -4
- package/dist/testing/mock-max.d.ts.map +1 -1
- package/dist/testing/mock-max.js +16 -3
- package/dist/testing/mock-max.js.map +1 -1
- package/dist/testing/sandbox.js +3 -0
- package/dist/testing/sandbox.js.map +1 -1
- package/dist/update.d.ts +36 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +70 -0
- package/dist/update.js.map +1 -0
- package/dist/upload.d.ts +10 -0
- package/dist/upload.d.ts.map +1 -0
- package/dist/upload.js +61 -0
- package/dist/upload.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +16 -3
- package/skills/max-cli/SKILL.md +23 -3
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { resolvePaths } from "@leemour/cli-core";
|
|
4
|
+
/**
|
|
5
|
+
* `<state dir>/sends/<profile>.jsonl` — beside `runs`, never in the cache directory, so that
|
|
6
|
+
* `max cache clear` cannot erase what was sent in the owner's name (the reason of `NEED-51`).
|
|
7
|
+
*/
|
|
8
|
+
export const sendsPathFor = (profile, env = process.env) => join(resolvePaths({ appName: "max-cli", prefix: "MAX", env }).state, "sends", `${profile}.jsonl`);
|
|
9
|
+
export class SendJournal {
|
|
10
|
+
path;
|
|
11
|
+
constructor(path) {
|
|
12
|
+
this.path = path;
|
|
13
|
+
}
|
|
14
|
+
append(entry) {
|
|
15
|
+
mkdirSync(dirname(this.path), { recursive: true, mode: 0o700 });
|
|
16
|
+
appendFileSync(this.path, `${JSON.stringify(entry)}\n`, { mode: 0o600 });
|
|
17
|
+
}
|
|
18
|
+
/** Oldest first. A line that does not parse is skipped: a torn last write must not block sending. */
|
|
19
|
+
entries() {
|
|
20
|
+
let text;
|
|
21
|
+
try {
|
|
22
|
+
text = readFileSync(this.path, "utf8");
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
return text
|
|
28
|
+
.split("\n")
|
|
29
|
+
.filter((line) => line.trim() !== "")
|
|
30
|
+
.flatMap((line) => {
|
|
31
|
+
try {
|
|
32
|
+
return [JSON.parse(line)];
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/sends/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAqDhD;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAE,MAAyB,OAAO,CAAC,GAAG,EAAU,EAAE,CAC5F,IAAI,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,QAAQ,CAAC,CAAA;AAEnG,MAAM,OAAO,WAAW;IACD;IAArB,YAAqB,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAErC,MAAM,CAAC,KAAgB;QACrB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC/D,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC1E,CAAC;IAED,qGAAqG;IACrG,OAAO;QACL,IAAI,IAAY,CAAA;QAChB,IAAI,CAAC;YACH,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAA;QACX,CAAC;QACD,OAAO,IAAI;aACR,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;aACpC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAChB,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,CAAC,CAAA;YACxC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAA;YACX,CAAC;QACH,CAAC,CAAC,CAAA;IACN,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Id } from "../domain/models.js";
|
|
2
|
+
export interface Recipient {
|
|
3
|
+
id: Id;
|
|
4
|
+
title: string | null;
|
|
5
|
+
addedAt: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A state file, not a setting: the configuration schema has deliberately no place for a chat id
|
|
9
|
+
* (`src/config.ts`), and this list is data about a profile rather than a preference.
|
|
10
|
+
*/
|
|
11
|
+
export declare const recipientsPathFor: (profile: string, env?: NodeJS.ProcessEnv) => string;
|
|
12
|
+
/**
|
|
13
|
+
* The chats a profile may send to. **No file means the check is off**; a file with no chats in it
|
|
14
|
+
* means nowhere. Optional by the owner's ruling (`NEED-159`).
|
|
15
|
+
*/
|
|
16
|
+
export declare class RecipientList {
|
|
17
|
+
#private;
|
|
18
|
+
readonly path: string;
|
|
19
|
+
constructor(path: string);
|
|
20
|
+
/** `undefined` when the list is off. A file that cannot be read refuses rather than opening up. */
|
|
21
|
+
read(): Recipient[] | undefined;
|
|
22
|
+
/** Whether it was new. */
|
|
23
|
+
add(recipient: Recipient): boolean;
|
|
24
|
+
/** The id or the title as it was stored; `undefined` when neither matched. */
|
|
25
|
+
remove(reference: string): Recipient | undefined;
|
|
26
|
+
/** Whether there was a list to turn off. */
|
|
27
|
+
off(): boolean;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=recipients.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipients.d.ts","sourceRoot":"","sources":["../../src/sends/recipients.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAE7C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,EAAE,CAAA;IACN,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,MAAM,EAAE,MAAK,MAAM,CAAC,UAAwB,KAAG,MACsB,CAAA;AAEhH;;;GAGG;AACH,qBAAa,aAAa;;IACZ,QAAQ,CAAC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAEjC,mGAAmG;IACnG,IAAI,IAAI,SAAS,EAAE,GAAG,SAAS;IAe/B,0BAA0B;IAC1B,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO;IAOlC,8EAA8E;IAC9E,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAUhD,4CAA4C;IAC5C,GAAG,IAAI,OAAO;CASf"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { CliError, resolvePaths, writeSecurely } from "@leemour/cli-core";
|
|
4
|
+
/**
|
|
5
|
+
* A state file, not a setting: the configuration schema has deliberately no place for a chat id
|
|
6
|
+
* (`src/config.ts`), and this list is data about a profile rather than a preference.
|
|
7
|
+
*/
|
|
8
|
+
export const recipientsPathFor = (profile, env = process.env) => join(resolvePaths({ appName: "max-cli", prefix: "MAX", env }).state, "profiles", `${profile}.recipients.json`);
|
|
9
|
+
/**
|
|
10
|
+
* The chats a profile may send to. **No file means the check is off**; a file with no chats in it
|
|
11
|
+
* means nowhere. Optional by the owner's ruling (`NEED-159`).
|
|
12
|
+
*/
|
|
13
|
+
export class RecipientList {
|
|
14
|
+
path;
|
|
15
|
+
constructor(path) {
|
|
16
|
+
this.path = path;
|
|
17
|
+
}
|
|
18
|
+
/** `undefined` when the list is off. A file that cannot be read refuses rather than opening up. */
|
|
19
|
+
read() {
|
|
20
|
+
if (!existsSync(this.path))
|
|
21
|
+
return undefined;
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(readFileSync(this.path, "utf8"));
|
|
24
|
+
if (!Array.isArray(parsed.chats))
|
|
25
|
+
throw new Error("no `chats` array");
|
|
26
|
+
return parsed.chats;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
throw new CliError("configuration_error", `the recipient list ${this.path} cannot be read (${error instanceof Error ? error.message : String(error)}) — ` +
|
|
30
|
+
"fix the file or turn the list off with `max recipients off`");
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Whether it was new. */
|
|
34
|
+
add(recipient) {
|
|
35
|
+
const chats = this.read() ?? [];
|
|
36
|
+
if (chats.some((chat) => chat.id === recipient.id))
|
|
37
|
+
return false;
|
|
38
|
+
this.#write([...chats, recipient]);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
/** The id or the title as it was stored; `undefined` when neither matched. */
|
|
42
|
+
remove(reference) {
|
|
43
|
+
const chats = this.read() ?? [];
|
|
44
|
+
const wanted = reference.trim();
|
|
45
|
+
const gone = chats.find((chat) => chat.id === wanted) ??
|
|
46
|
+
chats.find((chat) => chat.title?.toLocaleLowerCase() === wanted.toLocaleLowerCase());
|
|
47
|
+
if (gone)
|
|
48
|
+
this.#write(chats.filter((chat) => chat !== gone));
|
|
49
|
+
return gone;
|
|
50
|
+
}
|
|
51
|
+
/** Whether there was a list to turn off. */
|
|
52
|
+
off() {
|
|
53
|
+
if (!existsSync(this.path))
|
|
54
|
+
return false;
|
|
55
|
+
rmSync(this.path);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
#write(chats) {
|
|
59
|
+
writeSecurely(this.path, `${JSON.stringify({ chats }, null, 2)}\n`, 0o600);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=recipients.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipients.js","sourceRoot":"","sources":["../../src/sends/recipients.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One JSON value per line, **losslessly**: a request or an answer passing through `max serve`
|
|
3
|
+
* carries MAX's 18-digit message ids, which `JSON` would round into somebody else's message.
|
|
4
|
+
*/
|
|
5
|
+
export declare const toLine: (value: unknown) => string;
|
|
6
|
+
export declare const fromLine: (line: string) => Record<string, unknown>;
|
|
7
|
+
/** Calls `onLine` for each complete line `data` finishes, keeping the rest for next time. */
|
|
8
|
+
export declare const lineReader: (onLine: (line: string) => void) => (data: Buffer | string) => void;
|
|
9
|
+
//# sourceMappingURL=lines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.d.ts","sourceRoot":"","sources":["../../src/server/lines.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,MAAM,GAAI,OAAO,OAAO,KAAG,MAAiC,CAAA;AAEzE,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAG/B,CAAA;AAE/B,6FAA6F;AAC7F,eAAO,MAAM,UAAU,GAAI,QAAQ,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,MAE/C,MAAM,MAAM,GAAG,MAAM,SAU9B,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isInteger, isSafeNumber, parse, stringify } from "lossless-json";
|
|
2
|
+
/**
|
|
3
|
+
* One JSON value per line, **losslessly**: a request or an answer passing through `max serve`
|
|
4
|
+
* carries MAX's 18-digit message ids, which `JSON` would round into somebody else's message.
|
|
5
|
+
*/
|
|
6
|
+
export const toLine = (value) => `${stringify(value)}\n`;
|
|
7
|
+
export const fromLine = (line) => parse(line, undefined, {
|
|
8
|
+
parseNumber: (text) => (isInteger(text) && !isSafeNumber(text) ? BigInt(text) : Number(text)),
|
|
9
|
+
});
|
|
10
|
+
/** Calls `onLine` for each complete line `data` finishes, keeping the rest for next time. */
|
|
11
|
+
export const lineReader = (onLine) => {
|
|
12
|
+
let buffered = "";
|
|
13
|
+
return (data) => {
|
|
14
|
+
buffered += String(data);
|
|
15
|
+
let end = buffered.indexOf("\n");
|
|
16
|
+
while (end >= 0) {
|
|
17
|
+
const line = buffered.slice(0, end);
|
|
18
|
+
buffered = buffered.slice(end + 1);
|
|
19
|
+
if (line.trim() !== "")
|
|
20
|
+
onLine(line);
|
|
21
|
+
end = buffered.indexOf("\n");
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../src/server/lines.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEzE;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAA;AAEzE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAA2B,EAAE,CAChE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAC9F,CAA4B,CAAA;AAE/B,6FAA6F;AAC7F,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAA8B,EAAE,EAAE;IAC3D,IAAI,QAAQ,GAAG,EAAE,CAAA;IACjB,OAAO,CAAC,IAAqB,EAAE,EAAE;QAC/B,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAA;QACxB,IAAI,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAChC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;YACnC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;YAClC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,MAAM,CAAC,IAAI,CAAC,CAAA;YACpC,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Connection, type Wire, type WireEvent } from "../protocol/connection.js";
|
|
2
|
+
import { type Payload } from "../protocol/frame.js";
|
|
3
|
+
import type { SessionStore } from "../session/store.js";
|
|
4
|
+
/**
|
|
5
|
+
* **A command's connection that goes through `max serve`** when one is running (`MAX-16`).
|
|
6
|
+
*
|
|
7
|
+
* INIT and LOGIN are answered by the server's own login, so the command logs in without logging
|
|
8
|
+
* in. Reads go through the server's connection. **Anything else — a send, a reaction — makes this
|
|
9
|
+
* open a connection of its own and log in on it**, so it passes the send guards exactly as it does
|
|
10
|
+
* without a server (`NEED-185`). No server, a stale login, or a server that stops answering: the
|
|
11
|
+
* whole command falls back to its own connection before it has sent anything.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ServerConnection implements Wire {
|
|
14
|
+
#private;
|
|
15
|
+
constructor({ path, store, timeoutMs, direct, onUnreachable, }: {
|
|
16
|
+
path: string;
|
|
17
|
+
store: SessionStore;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
direct?: () => Connection;
|
|
20
|
+
/** The socket file is there and nobody answers — a server that died; start another. */
|
|
21
|
+
onUnreachable?: () => void;
|
|
22
|
+
});
|
|
23
|
+
open(): Promise<void>;
|
|
24
|
+
invoke(opcode: number, payload?: Payload, watch?: (event: WireEvent) => void): Promise<Payload>;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* What a command may ask for through the server — the server allows exactly these. **Nothing here
|
|
29
|
+
* changes anything**: sending, reacting, marking read and deleting never come this way, so no
|
|
30
|
+
* guard can be walked around.
|
|
31
|
+
*/
|
|
32
|
+
export declare const READS: Set<number>;
|
|
33
|
+
/** Asks a running server to stop. Resolves whether or not one was there. */
|
|
34
|
+
export declare const stopServer: (path: string) => Promise<boolean>;
|
|
35
|
+
//# sourceMappingURL=server-connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-connection.d.ts","sourceRoot":"","sources":["../../src/server/server-connection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAiB,KAAK,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAChG,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAUvD;;;;;;;;GAQG;AACH,qBAAa,gBAAiB,YAAW,IAAI;;gBAe/B,EACV,IAAI,EACJ,KAAK,EACL,SAAkB,EAClB,MAAM,EACN,aAAa,GACd,EAAE;QACD,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,YAAY,CAAA;QACnB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,MAAM,CAAC,EAAE,MAAM,UAAU,CAAA;QACzB,uFAAuF;QACvF,aAAa,CAAC,EAAE,MAAM,IAAI,CAAA;KAC3B;IAQK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAErB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,OAAY,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAkCnG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CA4F7B;AAED;;;;GAIG;AACH,eAAO,MAAM,KAAK,aAOhB,CAAA;AAEF,4EAA4E;AAC5E,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,OAAO,CAAC,OAAO,CAkBrD,CAAA"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { connect } from "node:net";
|
|
2
|
+
import { Opcode } from "../generated/opcodes.generated.js";
|
|
3
|
+
import { Connection, ProtocolError } from "../protocol/connection.js";
|
|
4
|
+
import { asId } from "../protocol/frame.js";
|
|
5
|
+
import { startSession } from "../session/handshake.js";
|
|
6
|
+
import { buildRequest } from "../spec/index.js";
|
|
7
|
+
import { fromLine, lineReader, toLine } from "./lines.js";
|
|
8
|
+
/**
|
|
9
|
+
* **A command's connection that goes through `max serve`** when one is running (`MAX-16`).
|
|
10
|
+
*
|
|
11
|
+
* INIT and LOGIN are answered by the server's own login, so the command logs in without logging
|
|
12
|
+
* in. Reads go through the server's connection. **Anything else — a send, a reaction — makes this
|
|
13
|
+
* open a connection of its own and log in on it**, so it passes the send guards exactly as it does
|
|
14
|
+
* without a server (`NEED-185`). No server, a stale login, or a server that stops answering: the
|
|
15
|
+
* whole command falls back to its own connection before it has sent anything.
|
|
16
|
+
*/
|
|
17
|
+
export class ServerConnection {
|
|
18
|
+
#path;
|
|
19
|
+
#store;
|
|
20
|
+
#timeoutMs;
|
|
21
|
+
#direct;
|
|
22
|
+
#onUnreachable;
|
|
23
|
+
#pending = new Map();
|
|
24
|
+
#socket;
|
|
25
|
+
#id = 0;
|
|
26
|
+
#login;
|
|
27
|
+
/** What the client sent as INIT; a fallback at LOGIN has to send it first, or MAX refuses. */
|
|
28
|
+
#init;
|
|
29
|
+
#own;
|
|
30
|
+
#ownLoggedIn = false;
|
|
31
|
+
constructor({ path, store, timeoutMs = 30_000, direct, onUnreachable, }) {
|
|
32
|
+
this.#onUnreachable = onUnreachable;
|
|
33
|
+
this.#path = path;
|
|
34
|
+
this.#store = store;
|
|
35
|
+
this.#timeoutMs = timeoutMs;
|
|
36
|
+
this.#direct = direct ?? (() => new Connection({ timeoutMs }));
|
|
37
|
+
}
|
|
38
|
+
async open() { }
|
|
39
|
+
async invoke(opcode, payload = {}, watch) {
|
|
40
|
+
if (this.#own)
|
|
41
|
+
return this.#ownRequest(opcode, payload, watch);
|
|
42
|
+
if (opcode === Opcode.SESSION_INIT) {
|
|
43
|
+
this.#init = payload;
|
|
44
|
+
this.#login = await this.#ask({ login: true }).catch((error) => {
|
|
45
|
+
if (error.code === "ECONNREFUSED" || error.code === "ENOENT")
|
|
46
|
+
this.#onUnreachable?.();
|
|
47
|
+
return undefined;
|
|
48
|
+
});
|
|
49
|
+
if (!this.#login)
|
|
50
|
+
return this.#fallBack(opcode, payload, watch);
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
if (opcode === Opcode.LOGIN) {
|
|
54
|
+
// A token being tried out (`max session start`) is not the one the server logged in with, and
|
|
55
|
+
// a server still logged in as the account this profile had before is not this profile's.
|
|
56
|
+
if (!this.#login || payload.token !== this.#store.readToken() || !this.#sameAccount(this.#login)) {
|
|
57
|
+
return this.#fallBack(opcode, payload, watch);
|
|
58
|
+
}
|
|
59
|
+
return this.#login;
|
|
60
|
+
}
|
|
61
|
+
if (!READS.has(opcode))
|
|
62
|
+
return this.#ownRequest(opcode, payload, watch);
|
|
63
|
+
watch?.({ phase: "sent", seq: this.#id + 1, opcode, bytes: 0 });
|
|
64
|
+
const answer = await this.#ask({ opcode, payload });
|
|
65
|
+
watch?.({ phase: "received", seq: this.#id, opcode, bytes: 0 });
|
|
66
|
+
return answer;
|
|
67
|
+
}
|
|
68
|
+
#sameAccount(login) {
|
|
69
|
+
const profile = login.profile;
|
|
70
|
+
const viewerId = this.#store.readState().viewerId;
|
|
71
|
+
return viewerId === undefined || asId(profile?.contact?.id) === viewerId;
|
|
72
|
+
}
|
|
73
|
+
async close() {
|
|
74
|
+
for (const { reject, timer } of this.#pending.values()) {
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
reject(new Error("the connection was closed before max serve answered"));
|
|
77
|
+
}
|
|
78
|
+
this.#pending.clear();
|
|
79
|
+
this.#socket?.destroy();
|
|
80
|
+
this.#socket = undefined;
|
|
81
|
+
await this.#own?.close();
|
|
82
|
+
}
|
|
83
|
+
/** Before anything was sent: the command simply runs as it would with no server. */
|
|
84
|
+
async #fallBack(opcode, payload, watch) {
|
|
85
|
+
this.#socket?.destroy();
|
|
86
|
+
this.#socket = undefined;
|
|
87
|
+
this.#own = this.#direct();
|
|
88
|
+
await this.#own.open();
|
|
89
|
+
if (opcode === Opcode.LOGIN && this.#init)
|
|
90
|
+
await this.#own.invoke(Opcode.SESSION_INIT, this.#init);
|
|
91
|
+
this.#ownLoggedIn = opcode === Opcode.LOGIN;
|
|
92
|
+
return this.#own.invoke(opcode, payload, watch);
|
|
93
|
+
}
|
|
94
|
+
/** A write mid-command: a connection of its own, logged in, then the request. */
|
|
95
|
+
async #ownRequest(opcode, payload, watch) {
|
|
96
|
+
if (!this.#own) {
|
|
97
|
+
this.#own = this.#direct();
|
|
98
|
+
await this.#own.open();
|
|
99
|
+
}
|
|
100
|
+
const own = this.#own;
|
|
101
|
+
if (!this.#ownLoggedIn && opcode !== Opcode.SESSION_INIT && opcode !== Opcode.LOGIN) {
|
|
102
|
+
const token = this.#store.readToken() ?? "";
|
|
103
|
+
await startSession((operation, request) => own.invoke(operation.opcode, buildRequest(operation, request)), {
|
|
104
|
+
token,
|
|
105
|
+
deviceId: this.#store.readState().deviceId,
|
|
106
|
+
});
|
|
107
|
+
this.#ownLoggedIn = true;
|
|
108
|
+
}
|
|
109
|
+
if (opcode === Opcode.LOGIN)
|
|
110
|
+
this.#ownLoggedIn = true;
|
|
111
|
+
return own.invoke(opcode, payload, watch);
|
|
112
|
+
}
|
|
113
|
+
async #ask(request) {
|
|
114
|
+
const socket = await this.#connected();
|
|
115
|
+
this.#id += 1;
|
|
116
|
+
const id = this.#id;
|
|
117
|
+
const answer = await new Promise((resolve, reject) => {
|
|
118
|
+
const timer = setTimeout(() => {
|
|
119
|
+
this.#pending.delete(id);
|
|
120
|
+
reject(new Error(`max serve did not answer within ${this.#timeoutMs}ms`));
|
|
121
|
+
}, this.#timeoutMs);
|
|
122
|
+
this.#pending.set(id, { resolve, reject, timer });
|
|
123
|
+
socket.write(toLine({ id, ...request }));
|
|
124
|
+
});
|
|
125
|
+
const error = answer.error;
|
|
126
|
+
if (error?.code === "refused") {
|
|
127
|
+
throw new ProtocolError(error.message ?? "MAX refused it", Number(request.opcode), error.payload ?? null);
|
|
128
|
+
}
|
|
129
|
+
if (error)
|
|
130
|
+
throw new Error(error.message ?? "max serve could not do it");
|
|
131
|
+
return (answer.payload ?? {});
|
|
132
|
+
}
|
|
133
|
+
async #connected() {
|
|
134
|
+
if (this.#socket)
|
|
135
|
+
return this.#socket;
|
|
136
|
+
const socket = connect(this.#path);
|
|
137
|
+
await new Promise((resolve, reject) => {
|
|
138
|
+
socket.once("connect", () => resolve());
|
|
139
|
+
socket.once("error", reject);
|
|
140
|
+
});
|
|
141
|
+
socket.on("data", lineReader((line) => {
|
|
142
|
+
const answer = fromLine(line);
|
|
143
|
+
const waiting = this.#pending.get(Number(answer.id));
|
|
144
|
+
if (!waiting)
|
|
145
|
+
return;
|
|
146
|
+
clearTimeout(waiting.timer);
|
|
147
|
+
this.#pending.delete(Number(answer.id));
|
|
148
|
+
waiting.resolve(answer);
|
|
149
|
+
}));
|
|
150
|
+
socket.on("error", () => { });
|
|
151
|
+
socket.on("close", () => {
|
|
152
|
+
for (const { reject, timer } of this.#pending.values()) {
|
|
153
|
+
clearTimeout(timer);
|
|
154
|
+
reject(new Error("max serve went away"));
|
|
155
|
+
}
|
|
156
|
+
this.#pending.clear();
|
|
157
|
+
this.#socket = undefined;
|
|
158
|
+
});
|
|
159
|
+
this.#socket = socket;
|
|
160
|
+
return socket;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* What a command may ask for through the server — the server allows exactly these. **Nothing here
|
|
165
|
+
* changes anything**: sending, reacting, marking read and deleting never come this way, so no
|
|
166
|
+
* guard can be walked around.
|
|
167
|
+
*/
|
|
168
|
+
export const READS = new Set([
|
|
169
|
+
Opcode.CHAT_HISTORY,
|
|
170
|
+
Opcode.CHATS_LIST,
|
|
171
|
+
Opcode.CONTACT_INFO,
|
|
172
|
+
Opcode.FILE_DOWNLOAD,
|
|
173
|
+
Opcode.VIDEO_PLAY,
|
|
174
|
+
Opcode.MSG_GET_REACTIONS,
|
|
175
|
+
]);
|
|
176
|
+
/** Asks a running server to stop. Resolves whether or not one was there. */
|
|
177
|
+
export const stopServer = (path) => new Promise((resolve) => {
|
|
178
|
+
const socket = connect(path);
|
|
179
|
+
const timer = setTimeout(() => {
|
|
180
|
+
socket.destroy();
|
|
181
|
+
resolve(false);
|
|
182
|
+
}, 2000);
|
|
183
|
+
socket.once("connect", () => socket.write(toLine({ id: 1, stop: true })));
|
|
184
|
+
// Nobody reads the answer, and a socket nobody reads never sees its end, so never closes.
|
|
185
|
+
socket.resume();
|
|
186
|
+
socket.once("error", () => {
|
|
187
|
+
clearTimeout(timer);
|
|
188
|
+
resolve(false);
|
|
189
|
+
});
|
|
190
|
+
socket.once("close", () => {
|
|
191
|
+
clearTimeout(timer);
|
|
192
|
+
resolve(true);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
//# sourceMappingURL=server-connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-connection.js","sourceRoot":"","sources":["../../src/server/server-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { CacheStore } from "../cache/store.js";
|
|
2
|
+
import { type MaxClientOptions } from "../client.js";
|
|
3
|
+
import type { MessageHit } from "../domain/models.js";
|
|
4
|
+
import { Connection, type ConnectionOptions } from "../protocol/connection.js";
|
|
5
|
+
import type { SessionStore } from "../session/store.js";
|
|
6
|
+
export type ServerEvent = {
|
|
7
|
+
event: "message";
|
|
8
|
+
message: MessageHit;
|
|
9
|
+
} | {
|
|
10
|
+
event: "status";
|
|
11
|
+
connected: boolean;
|
|
12
|
+
at: string;
|
|
13
|
+
};
|
|
14
|
+
export interface MaxServerOptions {
|
|
15
|
+
store: SessionStore;
|
|
16
|
+
cache?: CacheStore;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
/** One line for a person, on stderr. */
|
|
19
|
+
note: (line: string) => void;
|
|
20
|
+
/** Tests hand in a scripted MAX; the hooks must reach it. */
|
|
21
|
+
connection?: (hooks: Pick<ConnectionOptions, "onEvent" | "onClose">) => Connection;
|
|
22
|
+
pingEveryMs?: number;
|
|
23
|
+
/** The least time between two background logins after the snapshot went stale. */
|
|
24
|
+
refreshEveryMs?: number;
|
|
25
|
+
retryAfterMs?: (attempt: number) => number;
|
|
26
|
+
/**
|
|
27
|
+
* Stop after this long with nobody using it — no request, no `max watch`. Absent, it runs until
|
|
28
|
+
* stopped; a server started by a command gets one, or it would outlive every reason it had.
|
|
29
|
+
*/
|
|
30
|
+
idleMs?: number;
|
|
31
|
+
/** One event per request, for `--trace` and the run log — pings included. */
|
|
32
|
+
events?: MaxClientOptions["events"];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* **One logged-in connection per profile, kept open** (`MAX-16`), and a Unix socket beside the
|
|
36
|
+
* profile's state for local readers.
|
|
37
|
+
*
|
|
38
|
+
* It reopens REQUIREMENTS §3 and §18 on purpose and only here: every other command stays one-shot.
|
|
39
|
+
* What it does on the wire copies web.max.ru — a ping every 30 s, MAX's pings answered, each new
|
|
40
|
+
* message acknowledged (`Connection` with `live`). It never marks anything read and never sends.
|
|
41
|
+
*
|
|
42
|
+
* The socket answers `{"subscribe": true}` with a stream of `ServerEvent` lines and
|
|
43
|
+
* `{"status": true}` with one. For a command reusing the connection (`ServerConnection`) it answers
|
|
44
|
+
* `{"id", "login": true}` with the login it holds, and `{"id", "opcode", "payload"}` by passing the
|
|
45
|
+
* request to MAX — **reads only** (`NEED-185`). Anything that writes goes on the command's own
|
|
46
|
+
* connection, through the send guards, which live in the client and nowhere else.
|
|
47
|
+
*/
|
|
48
|
+
export declare class MaxServer {
|
|
49
|
+
#private;
|
|
50
|
+
/** Settles when the server stops — cleanly, or with the error that stopped it. */
|
|
51
|
+
readonly done: Promise<void>;
|
|
52
|
+
constructor(options: MaxServerOptions);
|
|
53
|
+
get connected(): boolean;
|
|
54
|
+
/** Logs in first: a token that does not work should fail here, before anything listens. */
|
|
55
|
+
start(): Promise<void>;
|
|
56
|
+
stop(error?: Error): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
/** Present while a server is being started in the background, so two commands do not start two. */
|
|
59
|
+
export declare const startingPath: (store: SessionStore) => string;
|
|
60
|
+
/** Whether something is listening on the socket — a live server, not a leftover file. */
|
|
61
|
+
export declare const answers: (path: string) => Promise<boolean>;
|
|
62
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAiB,MAAM,2BAA2B,CAAA;AAC7F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAIvD,MAAM,MAAM,WAAW,GACnB;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GACzC;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,YAAY,CAAA;IACnB,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wCAAwC;IACxC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5B,6DAA6D;IAC7D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,SAAS,CAAC,KAAK,UAAU,CAAA;IAClF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAA;IAC1C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,MAAM,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;CACpC;AAQD;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAS;;IAgBpB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;gBAEhB,OAAO,EAAE,gBAAgB;IAOrC,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,2FAA2F;IACrF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBtB,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;CAkNzC;AAKD,mGAAmG;AACnG,eAAO,MAAM,YAAY,GAAI,OAAO,YAAY,KAAG,MAA0C,CAAA;AAE7F,yFAAyF;AACzF,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,KAAG,OAAO,CAAC,OAAO,CAQlD,CAAA"}
|