@mtcute/core 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/LICENSE +1 -1
  2. package/cjs/highlevel/methods/files/upload-file.js +9 -0
  3. package/cjs/highlevel/methods/files/upload-file.js.map +1 -1
  4. package/cjs/highlevel/types/files/utils.d.ts +9 -6
  5. package/cjs/highlevel/types/files/utils.js.map +1 -1
  6. package/cjs/network/network-manager.js +1 -1
  7. package/cjs/network/session-connection.js +9 -0
  8. package/cjs/network/session-connection.js.map +1 -1
  9. package/cjs/storage/index.d.ts +1 -0
  10. package/cjs/storage/index.js +1 -0
  11. package/cjs/storage/index.js.map +1 -1
  12. package/cjs/storage/sqlite/driver.d.ts +24 -0
  13. package/cjs/storage/sqlite/driver.js +129 -0
  14. package/cjs/storage/sqlite/driver.js.map +1 -0
  15. package/cjs/storage/sqlite/index.d.ts +17 -0
  16. package/cjs/storage/sqlite/index.js +35 -0
  17. package/cjs/storage/sqlite/index.js.map +1 -0
  18. package/cjs/storage/sqlite/repository/auth-keys.d.ts +20 -0
  19. package/cjs/storage/sqlite/repository/auth-keys.js +68 -0
  20. package/cjs/storage/sqlite/repository/auth-keys.js.map +1 -0
  21. package/cjs/storage/sqlite/repository/kv.d.ts +14 -0
  22. package/cjs/storage/sqlite/repository/kv.js +96 -0
  23. package/cjs/storage/sqlite/repository/kv.js.map +1 -0
  24. package/cjs/storage/sqlite/repository/peers.d.ts +16 -0
  25. package/cjs/storage/sqlite/repository/peers.js +77 -0
  26. package/cjs/storage/sqlite/repository/peers.js.map +1 -0
  27. package/cjs/storage/sqlite/repository/ref-messages.d.ts +16 -0
  28. package/cjs/storage/sqlite/repository/ref-messages.js +49 -0
  29. package/cjs/storage/sqlite/repository/ref-messages.js.map +1 -0
  30. package/cjs/storage/sqlite/types.d.ts +18 -0
  31. package/cjs/storage/sqlite/types.js +3 -0
  32. package/cjs/storage/sqlite/types.js.map +1 -0
  33. package/esm/highlevel/methods/files/upload-file.js +9 -0
  34. package/esm/highlevel/methods/files/upload-file.js.map +1 -1
  35. package/esm/highlevel/types/files/utils.d.ts +9 -6
  36. package/esm/highlevel/types/files/utils.js.map +1 -1
  37. package/esm/network/network-manager.js +1 -1
  38. package/esm/network/session-connection.js +9 -0
  39. package/esm/network/session-connection.js.map +1 -1
  40. package/esm/storage/index.d.ts +1 -0
  41. package/esm/storage/index.js +1 -0
  42. package/esm/storage/index.js.map +1 -1
  43. package/esm/storage/sqlite/driver.d.ts +24 -0
  44. package/esm/storage/sqlite/driver.js +125 -0
  45. package/esm/storage/sqlite/driver.js.map +1 -0
  46. package/esm/storage/sqlite/index.d.ts +17 -0
  47. package/esm/storage/sqlite/index.js +17 -0
  48. package/esm/storage/sqlite/index.js.map +1 -0
  49. package/esm/storage/sqlite/repository/auth-keys.d.ts +20 -0
  50. package/esm/storage/sqlite/repository/auth-keys.js +64 -0
  51. package/esm/storage/sqlite/repository/auth-keys.js.map +1 -0
  52. package/esm/storage/sqlite/repository/kv.d.ts +14 -0
  53. package/esm/storage/sqlite/repository/kv.js +92 -0
  54. package/esm/storage/sqlite/repository/kv.js.map +1 -0
  55. package/esm/storage/sqlite/repository/peers.d.ts +16 -0
  56. package/esm/storage/sqlite/repository/peers.js +73 -0
  57. package/esm/storage/sqlite/repository/peers.js.map +1 -0
  58. package/esm/storage/sqlite/repository/ref-messages.d.ts +16 -0
  59. package/esm/storage/sqlite/repository/ref-messages.js +45 -0
  60. package/esm/storage/sqlite/repository/ref-messages.js.map +1 -0
  61. package/esm/storage/sqlite/types.d.ts +18 -0
  62. package/esm/storage/sqlite/types.js +2 -0
  63. package/esm/storage/sqlite/types.js.map +1 -0
  64. package/package.json +4 -4
@@ -2,4 +2,5 @@ export * from './driver.js';
2
2
  export * from './memory/index.js';
3
3
  export * from './provider.js';
4
4
  export * from './repository/index.js';
5
+ export * from './sqlite/index.js';
5
6
  export * from './storage.js';
@@ -2,5 +2,6 @@ export * from './driver.js';
2
2
  export * from './memory/index.js';
3
3
  export * from './provider.js';
4
4
  export * from './repository/index.js';
5
+ export * from './sqlite/index.js';
5
6
  export * from './storage.js';
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA","sourcesContent":["export * from './driver.js'\nexport * from './memory/index.js'\nexport * from './provider.js'\nexport * from './repository/index.js'\nexport * from './storage.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,mBAAmB,CAAA;AACjC,cAAc,cAAc,CAAA","sourcesContent":["export * from './driver.js'\nexport * from './memory/index.js'\nexport * from './provider.js'\nexport * from './repository/index.js'\nexport * from './sqlite/index.js'\nexport * from './storage.js'\n"]}
@@ -0,0 +1,24 @@
1
+ import { BaseStorageDriver } from '../driver.js';
2
+ import { ISqliteDatabase, ISqliteStatement } from './types.js';
3
+ type MigrationFunction = (db: ISqliteDatabase) => void;
4
+ export declare abstract class BaseSqliteStorageDriver extends BaseStorageDriver {
5
+ db: ISqliteDatabase;
6
+ private _pending;
7
+ private _runMany;
8
+ private _cleanup?;
9
+ private _migrations;
10
+ private _maxVersion;
11
+ private _legacyMigrations;
12
+ registerLegacyMigration(repo: string, migration: MigrationFunction): void;
13
+ registerMigration(repo: string, version: number, migration: MigrationFunction): void;
14
+ private _onLoad;
15
+ onLoad(cb: (db: ISqliteDatabase) => void): void;
16
+ _writeLater(stmt: ISqliteStatement, params: unknown[]): void;
17
+ private _runLegacyMigrations;
18
+ _initialize(): void;
19
+ abstract _createDatabase(): ISqliteDatabase;
20
+ _load(): void;
21
+ _save(): void;
22
+ _destroy(): void;
23
+ }
24
+ export {};
@@ -0,0 +1,125 @@
1
+ import { getPlatform } from '../../platform.js';
2
+ import { BaseStorageDriver } from '../driver.js';
3
+ const MIGRATIONS_TABLE_NAME = 'mtcute_migrations';
4
+ const MIGRATIONS_TABLE_SQL = `
5
+ create table if not exists ${MIGRATIONS_TABLE_NAME} (
6
+ repo text not null primary key,
7
+ version integer not null
8
+ );
9
+ `.trim();
10
+ export class BaseSqliteStorageDriver extends BaseStorageDriver {
11
+ constructor() {
12
+ super(...arguments);
13
+ this._pending = [];
14
+ this._migrations = new Map();
15
+ this._maxVersion = new Map();
16
+ // todo: remove in 1.0.0
17
+ this._legacyMigrations = new Map();
18
+ this._onLoad = new Set();
19
+ this._runLegacyMigrations = false;
20
+ }
21
+ registerLegacyMigration(repo, migration) {
22
+ if (this.loaded) {
23
+ throw new Error('Cannot register migrations after loading');
24
+ }
25
+ this._legacyMigrations.set(repo, migration);
26
+ }
27
+ registerMigration(repo, version, migration) {
28
+ if (this.loaded) {
29
+ throw new Error('Cannot register migrations after loading');
30
+ }
31
+ let map = this._migrations.get(repo);
32
+ if (!map) {
33
+ map = new Map();
34
+ this._migrations.set(repo, map);
35
+ }
36
+ if (map.has(version)) {
37
+ throw new Error(`Migration for ${repo} version ${version} is already registered`);
38
+ }
39
+ map.set(version, migration);
40
+ const prevMax = this._maxVersion.get(repo) ?? 0;
41
+ if (version > prevMax) {
42
+ this._maxVersion.set(repo, version);
43
+ }
44
+ }
45
+ onLoad(cb) {
46
+ if (this.loaded) {
47
+ cb(this.db);
48
+ }
49
+ else {
50
+ this._onLoad.add(cb);
51
+ }
52
+ }
53
+ _writeLater(stmt, params) {
54
+ this._pending.push([stmt, params]);
55
+ }
56
+ _initialize() {
57
+ const hasLegacyTables = this.db
58
+ .prepare("select name from sqlite_master where type = 'table' and name = 'kv'")
59
+ .get();
60
+ if (hasLegacyTables) {
61
+ this._log.info('legacy tables detected, will run migrations');
62
+ this._runLegacyMigrations = true;
63
+ }
64
+ this.db.exec(MIGRATIONS_TABLE_SQL);
65
+ const writeVersion = this.db.prepare(`insert or replace into ${MIGRATIONS_TABLE_NAME} (repo, version) values (?, ?)`);
66
+ const getVersion = this.db.prepare(`select version from ${MIGRATIONS_TABLE_NAME} where repo = ?`);
67
+ const didUpgrade = new Set();
68
+ for (const repo of this._migrations.keys()) {
69
+ const res = getVersion.get(repo);
70
+ const startVersion = res?.version ?? 0;
71
+ let fromVersion = startVersion;
72
+ const migrations = this._migrations.get(repo);
73
+ const targetVer = this._maxVersion.get(repo);
74
+ while (fromVersion < targetVer) {
75
+ const nextVersion = fromVersion + 1;
76
+ const migration = migrations.get(nextVersion);
77
+ if (!migration) {
78
+ throw new Error(`No migration for ${repo} to version ${nextVersion}`);
79
+ }
80
+ migration(this.db);
81
+ fromVersion = nextVersion;
82
+ didUpgrade.add(repo);
83
+ }
84
+ if (fromVersion !== startVersion) {
85
+ writeVersion.run(repo, targetVer);
86
+ }
87
+ }
88
+ }
89
+ _load() {
90
+ this.db = this._createDatabase();
91
+ this._runMany = this.db.transaction((stmts) => {
92
+ stmts.forEach((stmt) => {
93
+ stmt[0].run(stmt[1]);
94
+ });
95
+ });
96
+ this.db.transaction(() => this._initialize())();
97
+ this._cleanup = getPlatform().beforeExit(() => {
98
+ this._save();
99
+ this._destroy();
100
+ });
101
+ for (const cb of this._onLoad)
102
+ cb(this.db);
103
+ if (this._runLegacyMigrations) {
104
+ this.db.transaction(() => {
105
+ for (const migration of this._legacyMigrations.values()) {
106
+ migration(this.db);
107
+ }
108
+ // in case _writeLater was used
109
+ this._runMany(this._pending);
110
+ })();
111
+ }
112
+ }
113
+ _save() {
114
+ if (!this._pending.length)
115
+ return;
116
+ this._runMany(this._pending);
117
+ this._pending = [];
118
+ }
119
+ _destroy() {
120
+ this.db.close();
121
+ this._cleanup?.();
122
+ this._cleanup = undefined;
123
+ }
124
+ }
125
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../../src/storage/sqlite/driver.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPlatform } from '../../platform.js'\nimport { BaseStorageDriver } from '../driver.js'\nimport { ISqliteDatabase, ISqliteStatement } from './types.js'\n\nconst MIGRATIONS_TABLE_NAME = 'mtcute_migrations'\nconst MIGRATIONS_TABLE_SQL = `\ncreate table if not exists ${MIGRATIONS_TABLE_NAME} (\n repo text not null primary key,\n version integer not null\n);\n`.trim()\n\ntype MigrationFunction = (db: ISqliteDatabase) => void\n\nexport abstract class BaseSqliteStorageDriver extends BaseStorageDriver {\n db!: ISqliteDatabase\n\n private _pending: [ISqliteStatement, unknown[]][] = []\n private _runMany!: (stmts: [ISqliteStatement, unknown[]][]) => void\n private _cleanup?: () => void\n\n private _migrations: Map<string, Map<number, MigrationFunction>> = new Map()\n private _maxVersion: Map<string, number> = new Map()\n\n // todo: remove in 1.0.0\n private _legacyMigrations: Map<string, MigrationFunction> = new Map()\n\n registerLegacyMigration(repo: string, migration: MigrationFunction): void {\n if (this.loaded) {\n throw new Error('Cannot register migrations after loading')\n }\n\n this._legacyMigrations.set(repo, migration)\n }\n\n registerMigration(repo: string, version: number, migration: MigrationFunction): void {\n if (this.loaded) {\n throw new Error('Cannot register migrations after loading')\n }\n\n let map = this._migrations.get(repo)\n\n if (!map) {\n map = new Map()\n this._migrations.set(repo, map)\n }\n\n if (map.has(version)) {\n throw new Error(`Migration for ${repo} version ${version} is already registered`)\n }\n\n map.set(version, migration)\n\n const prevMax = this._maxVersion.get(repo) ?? 0\n\n if (version > prevMax) {\n this._maxVersion.set(repo, version)\n }\n }\n\n private _onLoad = new Set<(db: ISqliteDatabase) => void>()\n\n onLoad(cb: (db: ISqliteDatabase) => void): void {\n if (this.loaded) {\n cb(this.db)\n } else {\n this._onLoad.add(cb)\n }\n }\n\n _writeLater(stmt: ISqliteStatement, params: unknown[]): void {\n this._pending.push([stmt, params])\n }\n\n private _runLegacyMigrations = false\n\n _initialize(): void {\n const hasLegacyTables = this.db\n .prepare(\"select name from sqlite_master where type = 'table' and name = 'kv'\")\n .get()\n\n if (hasLegacyTables) {\n this._log.info('legacy tables detected, will run migrations')\n this._runLegacyMigrations = true\n }\n\n this.db.exec(MIGRATIONS_TABLE_SQL)\n\n const writeVersion = this.db.prepare(\n `insert or replace into ${MIGRATIONS_TABLE_NAME} (repo, version) values (?, ?)`,\n )\n const getVersion = this.db.prepare(`select version from ${MIGRATIONS_TABLE_NAME} where repo = ?`)\n\n const didUpgrade = new Set<string>()\n\n for (const repo of this._migrations.keys()) {\n const res = getVersion.get(repo) as { version: number } | undefined\n\n const startVersion = res?.version ?? 0\n let fromVersion = startVersion\n\n const migrations = this._migrations.get(repo)!\n const targetVer = this._maxVersion.get(repo)!\n\n while (fromVersion < targetVer) {\n const nextVersion = fromVersion + 1\n const migration = migrations.get(nextVersion)\n\n if (!migration) {\n throw new Error(`No migration for ${repo} to version ${nextVersion}`)\n }\n\n migration(this.db)\n\n fromVersion = nextVersion\n didUpgrade.add(repo)\n }\n\n if (fromVersion !== startVersion) {\n writeVersion.run(repo, targetVer)\n }\n }\n }\n\n abstract _createDatabase(): ISqliteDatabase\n\n _load(): void {\n this.db = this._createDatabase()\n\n this._runMany = this.db.transaction((stmts: [ISqliteStatement, unknown[]][]) => {\n stmts.forEach((stmt) => {\n stmt[0].run(stmt[1])\n })\n })\n\n this.db.transaction(() => this._initialize())()\n\n this._cleanup = getPlatform().beforeExit(() => {\n this._save()\n this._destroy()\n })\n for (const cb of this._onLoad) cb(this.db)\n\n if (this._runLegacyMigrations) {\n this.db.transaction(() => {\n for (const migration of this._legacyMigrations.values()) {\n migration(this.db)\n }\n\n // in case _writeLater was used\n this._runMany(this._pending)\n })()\n }\n }\n\n _save(): void {\n if (!this._pending.length) return\n\n this._runMany(this._pending)\n this._pending = []\n }\n\n _destroy(): void {\n this.db.close()\n this._cleanup?.()\n this._cleanup = undefined\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { ITelegramStorageProvider } from '../../highlevel/storage/provider.js';
2
+ import { IMtStorageProvider } from '../provider.js';
3
+ import { BaseSqliteStorageDriver } from './driver.js';
4
+ import { SqliteAuthKeysRepository } from './repository/auth-keys.js';
5
+ import { SqliteKeyValueRepository } from './repository/kv.js';
6
+ import { SqlitePeersRepository } from './repository/peers.js';
7
+ import { SqliteRefMessagesRepository } from './repository/ref-messages.js';
8
+ export { BaseSqliteStorageDriver };
9
+ export * from './types.js';
10
+ export declare class BaseSqliteStorage implements IMtStorageProvider, ITelegramStorageProvider {
11
+ readonly driver: BaseSqliteStorageDriver;
12
+ constructor(driver: BaseSqliteStorageDriver);
13
+ readonly authKeys: SqliteAuthKeysRepository;
14
+ readonly kv: SqliteKeyValueRepository;
15
+ readonly refMessages: SqliteRefMessagesRepository;
16
+ readonly peers: SqlitePeersRepository;
17
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseSqliteStorageDriver } from './driver.js';
2
+ import { SqliteAuthKeysRepository } from './repository/auth-keys.js';
3
+ import { SqliteKeyValueRepository } from './repository/kv.js';
4
+ import { SqlitePeersRepository } from './repository/peers.js';
5
+ import { SqliteRefMessagesRepository } from './repository/ref-messages.js';
6
+ export { BaseSqliteStorageDriver };
7
+ export * from './types.js';
8
+ export class BaseSqliteStorage {
9
+ constructor(driver) {
10
+ this.driver = driver;
11
+ this.authKeys = new SqliteAuthKeysRepository(this.driver);
12
+ this.kv = new SqliteKeyValueRepository(this.driver);
13
+ this.refMessages = new SqliteRefMessagesRepository(this.driver);
14
+ this.peers = new SqlitePeersRepository(this.driver);
15
+ }
16
+ }
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/storage/sqlite/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAA;AAE1E,OAAO,EAAE,uBAAuB,EAAE,CAAA;AAClC,cAAc,YAAY,CAAA;AAE1B,MAAM,OAAO,iBAAiB;IAC1B,YAAqB,MAA+B;QAA/B,WAAM,GAAN,MAAM,CAAyB;QAE3C,aAAQ,GAAG,IAAI,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACpD,OAAE,GAAG,IAAI,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC9C,gBAAW,GAAG,IAAI,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC1D,UAAK,GAAG,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IALA,CAAC;CAM3D","sourcesContent":["import { ITelegramStorageProvider } from '../../highlevel/storage/provider.js'\nimport { IMtStorageProvider } from '../provider.js'\nimport { BaseSqliteStorageDriver } from './driver.js'\nimport { SqliteAuthKeysRepository } from './repository/auth-keys.js'\nimport { SqliteKeyValueRepository } from './repository/kv.js'\nimport { SqlitePeersRepository } from './repository/peers.js'\nimport { SqliteRefMessagesRepository } from './repository/ref-messages.js'\n\nexport { BaseSqliteStorageDriver }\nexport * from './types.js'\n\nexport class BaseSqliteStorage implements IMtStorageProvider, ITelegramStorageProvider {\n constructor(readonly driver: BaseSqliteStorageDriver) {}\n\n readonly authKeys = new SqliteAuthKeysRepository(this.driver)\n readonly kv = new SqliteKeyValueRepository(this.driver)\n readonly refMessages = new SqliteRefMessagesRepository(this.driver)\n readonly peers = new SqlitePeersRepository(this.driver)\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import { IAuthKeysRepository } from '../../repository/auth-keys.js';
2
+ import { BaseSqliteStorageDriver } from '../driver.js';
3
+ export declare class SqliteAuthKeysRepository implements IAuthKeysRepository {
4
+ readonly _driver: BaseSqliteStorageDriver;
5
+ constructor(_driver: BaseSqliteStorageDriver);
6
+ private _set;
7
+ private _del;
8
+ set(dc: number, key: Uint8Array | null): void;
9
+ private _get;
10
+ get(dc: number): Uint8Array | null;
11
+ private _setTemp;
12
+ private _delTemp;
13
+ setTemp(dc: number, idx: number, key: Uint8Array | null, expires: number): void;
14
+ private _getTemp;
15
+ getTemp(dc: number, idx: number, now: number): Uint8Array | null;
16
+ private _delTempAll;
17
+ deleteByDc(dc: number): void;
18
+ private _delAll;
19
+ deleteAll(): void;
20
+ }
@@ -0,0 +1,64 @@
1
+ export class SqliteAuthKeysRepository {
2
+ constructor(_driver) {
3
+ this._driver = _driver;
4
+ _driver.registerMigration('auth_keys', 1, (db) => {
5
+ db.exec(`
6
+ create table if not exists auth_keys (
7
+ dc integer primary key,
8
+ key blob not null
9
+ );
10
+ create table if not exists temp_auth_keys (
11
+ dc integer not null,
12
+ idx integer not null,
13
+ key blob not null,
14
+ expires integer not null,
15
+ primary key (dc, idx)
16
+ );
17
+ `);
18
+ });
19
+ _driver.onLoad((db) => {
20
+ this._get = db.prepare('select key from auth_keys where dc = ?');
21
+ this._getTemp = db.prepare('select key from temp_auth_keys where dc = ? and idx = ? and expires > ?');
22
+ this._set = db.prepare('insert or replace into auth_keys (dc, key) values (?, ?)');
23
+ this._setTemp = this._driver.db.prepare('insert or replace into temp_auth_keys (dc, idx, key, expires) values (?, ?, ?, ?)');
24
+ this._del = db.prepare('delete from auth_keys where dc = ?');
25
+ this._delTemp = db.prepare('delete from temp_auth_keys where dc = ? and idx = ?');
26
+ this._delTempAll = db.prepare('delete from temp_auth_keys where dc = ?');
27
+ this._delAll = db.prepare('delete from auth_keys');
28
+ });
29
+ }
30
+ set(dc, key) {
31
+ if (!key) {
32
+ this._del.run(dc);
33
+ return;
34
+ }
35
+ this._set.run(dc, key);
36
+ }
37
+ get(dc) {
38
+ const row = this._get.get(dc);
39
+ if (!row)
40
+ return null;
41
+ return row.key;
42
+ }
43
+ setTemp(dc, idx, key, expires) {
44
+ if (!key) {
45
+ this._delTemp.run(dc, idx);
46
+ return;
47
+ }
48
+ this._setTemp.run(dc, idx, key, expires);
49
+ }
50
+ getTemp(dc, idx, now) {
51
+ const row = this._getTemp.get(dc, idx, now);
52
+ if (!row)
53
+ return null;
54
+ return row.key;
55
+ }
56
+ deleteByDc(dc) {
57
+ this._del.run(dc);
58
+ this._delTempAll.run(dc);
59
+ }
60
+ deleteAll() {
61
+ this._delAll.run();
62
+ }
63
+ }
64
+ //# sourceMappingURL=auth-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-keys.js","sourceRoot":"","sources":["../../../../../src/storage/sqlite/repository/auth-keys.ts"],"names":[],"mappings":"AAcA,MAAM,OAAO,wBAAwB;IACjC,YAAqB,OAAgC;QAAhC,YAAO,GAAP,OAAO,CAAyB;QACjD,OAAO,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;YAC7C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;aAYP,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;QACF,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;YAClB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAA;YAChE,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,yEAAyE,CAAC,CAAA;YAErG,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAA;YAClF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CACnC,mFAAmF,CACtF,CAAA;YAED,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAA;YAC5D,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,qDAAqD,CAAC,CAAA;YACjF,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAA;YACxE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAA;QACtD,CAAC,CAAC,CAAA;IACN,CAAC;IAID,GAAG,CAAC,EAAU,EAAE,GAAsB;QAClC,IAAI,CAAC,GAAG,EAAE;YACN,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAEjB,OAAM;SACT;QAED,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC1B,CAAC;IAGD,GAAG,CAAC,EAAU;QACV,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC7B,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,OAAQ,GAAkB,CAAC,GAAG,CAAA;IAClC,CAAC;IAID,OAAO,CAAC,EAAU,EAAE,GAAW,EAAE,GAAsB,EAAE,OAAe;QACpE,IAAI,CAAC,GAAG,EAAE;YACN,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;YAE1B,OAAM;SACT;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IAGD,OAAO,CAAC,EAAU,EAAE,GAAW,EAAE,GAAW;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,OAAQ,GAAsB,CAAC,GAAG,CAAA;IACtC,CAAC;IAGD,UAAU,CAAC,EAAU;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACjB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC5B,CAAC;IAGD,SAAS;QACL,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAA;IACtB,CAAC;CACJ","sourcesContent":["import { IAuthKeysRepository } from '../../repository/auth-keys.js'\nimport { BaseSqliteStorageDriver } from '../driver.js'\nimport { ISqliteStatement } from '../types.js'\n\ninterface AuthKeyDto {\n dc: number\n key: Uint8Array\n}\n\ninterface TempAuthKeyDto extends AuthKeyDto {\n expires?: number\n idx?: number\n}\n\nexport class SqliteAuthKeysRepository implements IAuthKeysRepository {\n constructor(readonly _driver: BaseSqliteStorageDriver) {\n _driver.registerMigration('auth_keys', 1, (db) => {\n db.exec(`\n create table if not exists auth_keys (\n dc integer primary key,\n key blob not null\n );\n create table if not exists temp_auth_keys (\n dc integer not null,\n idx integer not null,\n key blob not null,\n expires integer not null,\n primary key (dc, idx)\n );\n `)\n })\n _driver.onLoad((db) => {\n this._get = db.prepare('select key from auth_keys where dc = ?')\n this._getTemp = db.prepare('select key from temp_auth_keys where dc = ? and idx = ? and expires > ?')\n\n this._set = db.prepare('insert or replace into auth_keys (dc, key) values (?, ?)')\n this._setTemp = this._driver.db.prepare(\n 'insert or replace into temp_auth_keys (dc, idx, key, expires) values (?, ?, ?, ?)',\n )\n\n this._del = db.prepare('delete from auth_keys where dc = ?')\n this._delTemp = db.prepare('delete from temp_auth_keys where dc = ? and idx = ?')\n this._delTempAll = db.prepare('delete from temp_auth_keys where dc = ?')\n this._delAll = db.prepare('delete from auth_keys')\n })\n }\n\n private _set!: ISqliteStatement\n private _del!: ISqliteStatement\n set(dc: number, key: Uint8Array | null): void {\n if (!key) {\n this._del.run(dc)\n\n return\n }\n\n this._set.run(dc, key)\n }\n\n private _get!: ISqliteStatement\n get(dc: number): Uint8Array | null {\n const row = this._get.get(dc)\n if (!row) return null\n\n return (row as AuthKeyDto).key\n }\n\n private _setTemp!: ISqliteStatement\n private _delTemp!: ISqliteStatement\n setTemp(dc: number, idx: number, key: Uint8Array | null, expires: number): void {\n if (!key) {\n this._delTemp.run(dc, idx)\n\n return\n }\n\n this._setTemp.run(dc, idx, key, expires)\n }\n\n private _getTemp!: ISqliteStatement\n getTemp(dc: number, idx: number, now: number): Uint8Array | null {\n const row = this._getTemp.get(dc, idx, now)\n if (!row) return null\n\n return (row as TempAuthKeyDto).key\n }\n\n private _delTempAll!: ISqliteStatement\n deleteByDc(dc: number): void {\n this._del.run(dc)\n this._delTempAll.run(dc)\n }\n\n private _delAll!: ISqliteStatement\n deleteAll(): void {\n this._delAll.run()\n }\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import { IKeyValueRepository } from '../../repository/key-value.js';
2
+ import { BaseSqliteStorageDriver } from '../driver.js';
3
+ export declare class SqliteKeyValueRepository implements IKeyValueRepository {
4
+ readonly _driver: BaseSqliteStorageDriver;
5
+ constructor(_driver: BaseSqliteStorageDriver);
6
+ private _set;
7
+ set(key: string, value: Uint8Array): void;
8
+ private _get;
9
+ get(key: string): Uint8Array | null;
10
+ private _del;
11
+ delete(key: string): void;
12
+ private _delAll;
13
+ deleteAll(): void;
14
+ }
@@ -0,0 +1,92 @@
1
+ import { __tlReaderMap } from '@mtcute/tl/binary/reader.js';
2
+ import { __tlWriterMap } from '@mtcute/tl/binary/writer.js';
3
+ import { CurrentUserService } from '../../../highlevel/storage/service/current-user.js';
4
+ import { UpdatesStateService } from '../../../highlevel/storage/service/updates.js';
5
+ import { DefaultDcsService } from '../../service/default-dcs.js';
6
+ export class SqliteKeyValueRepository {
7
+ constructor(_driver) {
8
+ this._driver = _driver;
9
+ _driver.registerMigration('kv', 1, (db) => {
10
+ db.exec(`
11
+ create table key_value (
12
+ key text primary key,
13
+ value blob not null
14
+ );
15
+ `);
16
+ });
17
+ _driver.onLoad((db) => {
18
+ this._get = db.prepare('select value from key_value where key = ?');
19
+ this._set = db.prepare('insert or replace into key_value (key, value) values (?, ?)');
20
+ this._del = db.prepare('delete from key_value where key = ?');
21
+ this._delAll = db.prepare('delete from key_value');
22
+ });
23
+ // awkward dependencies, unsafe code, awful crutches
24
+ // all in the name of backwards compatibility
25
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
26
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-floating-promises */
27
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
28
+ _driver.registerLegacyMigration('kv', (db) => {
29
+ // fetch all values from the old table
30
+ const all = db.prepare('select key, value from kv').all();
31
+ const obj = {};
32
+ for (const { key, value } of all) {
33
+ obj[key] = JSON.parse(value);
34
+ }
35
+ db.exec('drop table kv');
36
+ // lol
37
+ const options = {
38
+ driver: this._driver,
39
+ readerMap: __tlReaderMap,
40
+ writerMap: __tlWriterMap,
41
+ // eslint-disable-next-line dot-notation
42
+ log: this._driver['_log'],
43
+ };
44
+ if (obj.self) {
45
+ new CurrentUserService(this, options).store({
46
+ userId: obj.self.userId,
47
+ isBot: obj.self.isBot,
48
+ isPremium: false,
49
+ usernames: [],
50
+ });
51
+ }
52
+ if (obj.pts) {
53
+ const svc = new UpdatesStateService(this, options);
54
+ svc.setPts(obj.pts);
55
+ if (obj.qts)
56
+ svc.setQts(obj.qts);
57
+ if (obj.date)
58
+ svc.setDate(obj.date);
59
+ if (obj.seq)
60
+ svc.setSeq(obj.seq);
61
+ // also fetch channel states. they were moved to kv from a separate table
62
+ const channels = db.prepare('select * from pts').all();
63
+ for (const channel of channels) {
64
+ svc.setChannelPts(channel.channel_id, channel.pts);
65
+ }
66
+ }
67
+ db.exec('drop table pts');
68
+ if (obj.def_dc) {
69
+ new DefaultDcsService(this, options).store(obj.def_dc);
70
+ }
71
+ });
72
+ /* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
73
+ /* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-floating-promises */
74
+ /* eslint-enable @typescript-eslint/no-unsafe-argument */
75
+ }
76
+ set(key, value) {
77
+ this._driver._writeLater(this._set, [key, value]);
78
+ }
79
+ get(key) {
80
+ const res = this._get.get(key);
81
+ if (!res)
82
+ return null;
83
+ return res.value;
84
+ }
85
+ delete(key) {
86
+ this._del.run(key);
87
+ }
88
+ deleteAll() {
89
+ this._delAll.run();
90
+ }
91
+ }
92
+ //# sourceMappingURL=kv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kv.js","sourceRoot":"","sources":["../../../../../src/storage/sqlite/repository/kv.ts"],"names":[],"mappings":"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","sourcesContent":["import { __tlReaderMap } from '@mtcute/tl/binary/reader.js'\nimport { __tlWriterMap } from '@mtcute/tl/binary/writer.js'\n\nimport { CurrentUserService } from '../../../highlevel/storage/service/current-user.js'\nimport { UpdatesStateService } from '../../../highlevel/storage/service/updates.js'\nimport { IKeyValueRepository } from '../../repository/key-value.js'\nimport { ServiceOptions } from '../../service/base.js'\nimport { DefaultDcsService } from '../../service/default-dcs.js'\nimport { BaseSqliteStorageDriver } from '../driver.js'\nimport { ISqliteStatement } from '../types.js'\n\ninterface KeyValueDto {\n key: string\n value: Uint8Array\n}\n\nexport class SqliteKeyValueRepository implements IKeyValueRepository {\n constructor(readonly _driver: BaseSqliteStorageDriver) {\n _driver.registerMigration('kv', 1, (db) => {\n db.exec(`\n create table key_value (\n key text primary key,\n value blob not null\n );\n `)\n })\n _driver.onLoad((db) => {\n this._get = db.prepare('select value from key_value where key = ?')\n this._set = db.prepare('insert or replace into key_value (key, value) values (?, ?)')\n this._del = db.prepare('delete from key_value where key = ?')\n this._delAll = db.prepare('delete from key_value')\n })\n\n // awkward dependencies, unsafe code, awful crutches\n // all in the name of backwards compatibility\n /* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */\n /* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-floating-promises */\n /* eslint-disable @typescript-eslint/no-unsafe-argument */\n _driver.registerLegacyMigration('kv', (db) => {\n // fetch all values from the old table\n const all = db.prepare('select key, value from kv').all() as { key: string; value: string }[]\n const obj: Record<string, any> = {}\n\n for (const { key, value } of all) {\n obj[key] = JSON.parse(value)\n }\n\n db.exec('drop table kv')\n\n // lol\n const options: ServiceOptions = {\n driver: this._driver,\n readerMap: __tlReaderMap,\n writerMap: __tlWriterMap,\n // eslint-disable-next-line dot-notation\n log: this._driver['_log'],\n }\n\n if (obj.self) {\n new CurrentUserService(this, options).store({\n userId: obj.self.userId,\n isBot: obj.self.isBot,\n isPremium: false,\n usernames: [],\n })\n }\n\n if (obj.pts) {\n const svc = new UpdatesStateService(this, options)\n svc.setPts(obj.pts)\n if (obj.qts) svc.setQts(obj.qts)\n if (obj.date) svc.setDate(obj.date)\n if (obj.seq) svc.setSeq(obj.seq)\n\n // also fetch channel states. they were moved to kv from a separate table\n const channels = db.prepare('select * from pts').all() as any[]\n\n for (const channel of channels) {\n svc.setChannelPts(channel.channel_id, channel.pts)\n }\n }\n db.exec('drop table pts')\n\n if (obj.def_dc) {\n new DefaultDcsService(this, options).store(obj.def_dc)\n }\n })\n /* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */\n /* eslint-enable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-floating-promises */\n /* eslint-enable @typescript-eslint/no-unsafe-argument */\n }\n\n private _set!: ISqliteStatement\n set(key: string, value: Uint8Array): void {\n this._driver._writeLater(this._set, [key, value])\n }\n\n private _get!: ISqliteStatement\n get(key: string): Uint8Array | null {\n const res = this._get.get(key)\n if (!res) return null\n\n return (res as KeyValueDto).value\n }\n\n private _del!: ISqliteStatement\n delete(key: string): void {\n this._del.run(key)\n }\n\n private _delAll!: ISqliteStatement\n deleteAll(): void {\n this._delAll.run()\n }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { IPeersRepository } from '../../../highlevel/storage/repository/peers.js';
2
+ import { BaseSqliteStorageDriver } from '../driver.js';
3
+ export declare class SqlitePeersRepository implements IPeersRepository {
4
+ readonly _driver: BaseSqliteStorageDriver;
5
+ constructor(_driver: BaseSqliteStorageDriver);
6
+ private _store;
7
+ store(peer: IPeersRepository.PeerInfo): void;
8
+ private _getById;
9
+ getById(id: number): IPeersRepository.PeerInfo | null;
10
+ private _getByUsername;
11
+ getByUsername(username: string): IPeersRepository.PeerInfo | null;
12
+ private _getByPhone;
13
+ getByPhone(phone: string): IPeersRepository.PeerInfo | null;
14
+ private _delAll;
15
+ deleteAll(): void;
16
+ }
@@ -0,0 +1,73 @@
1
+ function mapPeerDto(dto) {
2
+ return {
3
+ id: dto.id,
4
+ accessHash: dto.hash,
5
+ usernames: JSON.parse(dto.usernames),
6
+ updated: dto.updated,
7
+ phone: dto.phone || undefined,
8
+ complete: dto.complete,
9
+ };
10
+ }
11
+ export class SqlitePeersRepository {
12
+ constructor(_driver) {
13
+ this._driver = _driver;
14
+ _driver.registerMigration('peers', 1, (db) => {
15
+ db.exec(`
16
+ create table peers (
17
+ id integer primary key,
18
+ hash text not null,
19
+ usernames json not null,
20
+ updated integer not null,
21
+ phone text,
22
+ complete blob
23
+ );
24
+ create index idx_peers_usernames on peers (usernames);
25
+ create index idx_peers_phone on peers (phone);
26
+ `);
27
+ });
28
+ _driver.onLoad((db) => {
29
+ this._store = db.prepare('insert or replace into peers (id, hash, usernames, updated, phone, complete) values (?, ?, ?, ?, ?, ?)');
30
+ this._getById = db.prepare('select * from peers where id = ?');
31
+ this._getByUsername = db.prepare('select * from peers where exists (select 1 from json_each(usernames) where value = ?)');
32
+ this._getByPhone = db.prepare('select * from peers where phone = ?');
33
+ this._delAll = db.prepare('delete from peers');
34
+ });
35
+ _driver.registerLegacyMigration('peers', (db) => {
36
+ // not too important information, just drop the table
37
+ db.exec('drop table entities');
38
+ });
39
+ }
40
+ store(peer) {
41
+ this._driver._writeLater(this._store, [
42
+ peer.id,
43
+ peer.accessHash,
44
+ // add commas to make it easier to search with LIKE
45
+ JSON.stringify(peer.usernames),
46
+ peer.updated,
47
+ peer.phone,
48
+ peer.complete,
49
+ ]);
50
+ }
51
+ getById(id) {
52
+ const row = this._getById.get(id);
53
+ if (!row)
54
+ return null;
55
+ return mapPeerDto(row);
56
+ }
57
+ getByUsername(username) {
58
+ const row = this._getByUsername.get(username);
59
+ if (!row)
60
+ return null;
61
+ return mapPeerDto(row);
62
+ }
63
+ getByPhone(phone) {
64
+ const row = this._getByPhone.get(phone);
65
+ if (!row)
66
+ return null;
67
+ return mapPeerDto(row);
68
+ }
69
+ deleteAll() {
70
+ this._delAll.run();
71
+ }
72
+ }
73
+ //# sourceMappingURL=peers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peers.js","sourceRoot":"","sources":["../../../../../src/storage/sqlite/repository/peers.ts"],"names":[],"mappings":"AAcA,SAAS,UAAU,CAAC,GAAY;IAC5B,OAAO;QACH,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,UAAU,EAAE,GAAG,CAAC,IAAI;QACpB,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAa;QAChD,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,SAAS;QAC7B,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACzB,CAAA;AACL,CAAC;AAED,MAAM,OAAO,qBAAqB;IAC9B,YAAqB,OAAgC;QAAhC,YAAO,GAAP,OAAO,CAAyB;QACjD,OAAO,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;YACzC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;aAWP,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;QACF,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;YAClB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,OAAO,CACpB,wGAAwG,CAC3G,CAAA;YAED,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAA;YAC9D,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,OAAO,CAC5B,uFAAuF,CAC1F,CAAA;YACD,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAA;YAEpE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAA;QAClD,CAAC,CAAC,CAAA;QACF,OAAO,CAAC,uBAAuB,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;YAC5C,qDAAqD;YACrD,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;QAClC,CAAC,CAAC,CAAA;IACN,CAAC;IAGD,KAAK,CAAC,IAA+B;QACjC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE;YAClC,IAAI,CAAC,EAAE;YACP,IAAI,CAAC,UAAU;YACf,mDAAmD;YACnD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9B,IAAI,CAAC,OAAO;YACZ,IAAI,CAAC,KAAK;YACV,IAAI,CAAC,QAAQ;SAChB,CAAC,CAAA;IACN,CAAC;IAGD,OAAO,CAAC,EAAU;QACd,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACjC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,OAAO,UAAU,CAAC,GAAc,CAAC,CAAA;IACrC,CAAC;IAGD,aAAa,CAAC,QAAgB;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC7C,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,OAAO,UAAU,CAAC,GAAc,CAAC,CAAA;IACrC,CAAC;IAGD,UAAU,CAAC,KAAa;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACvC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,OAAO,UAAU,CAAC,GAAc,CAAC,CAAA;IACrC,CAAC;IAGD,SAAS;QACL,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAA;IACtB,CAAC;CACJ","sourcesContent":["import { IPeersRepository } from '../../../highlevel/storage/repository/peers.js'\nimport { BaseSqliteStorageDriver } from '../driver.js'\nimport { ISqliteStatement } from '../types.js'\n\ninterface PeerDto {\n id: number\n hash: string\n usernames: string\n updated: number\n phone: string | null\n // eslint-disable-next-line no-restricted-globals\n complete: Buffer\n}\n\nfunction mapPeerDto(dto: PeerDto): IPeersRepository.PeerInfo {\n return {\n id: dto.id,\n accessHash: dto.hash,\n usernames: JSON.parse(dto.usernames) as string[],\n updated: dto.updated,\n phone: dto.phone || undefined,\n complete: dto.complete,\n }\n}\n\nexport class SqlitePeersRepository implements IPeersRepository {\n constructor(readonly _driver: BaseSqliteStorageDriver) {\n _driver.registerMigration('peers', 1, (db) => {\n db.exec(`\n create table peers (\n id integer primary key,\n hash text not null,\n usernames json not null,\n updated integer not null,\n phone text,\n complete blob\n );\n create index idx_peers_usernames on peers (usernames);\n create index idx_peers_phone on peers (phone);\n `)\n })\n _driver.onLoad((db) => {\n this._store = db.prepare(\n 'insert or replace into peers (id, hash, usernames, updated, phone, complete) values (?, ?, ?, ?, ?, ?)',\n )\n\n this._getById = db.prepare('select * from peers where id = ?')\n this._getByUsername = db.prepare(\n 'select * from peers where exists (select 1 from json_each(usernames) where value = ?)',\n )\n this._getByPhone = db.prepare('select * from peers where phone = ?')\n\n this._delAll = db.prepare('delete from peers')\n })\n _driver.registerLegacyMigration('peers', (db) => {\n // not too important information, just drop the table\n db.exec('drop table entities')\n })\n }\n\n private _store!: ISqliteStatement\n store(peer: IPeersRepository.PeerInfo): void {\n this._driver._writeLater(this._store, [\n peer.id,\n peer.accessHash,\n // add commas to make it easier to search with LIKE\n JSON.stringify(peer.usernames),\n peer.updated,\n peer.phone,\n peer.complete,\n ])\n }\n\n private _getById!: ISqliteStatement\n getById(id: number): IPeersRepository.PeerInfo | null {\n const row = this._getById.get(id)\n if (!row) return null\n\n return mapPeerDto(row as PeerDto)\n }\n\n private _getByUsername!: ISqliteStatement\n getByUsername(username: string): IPeersRepository.PeerInfo | null {\n const row = this._getByUsername.get(username)\n if (!row) return null\n\n return mapPeerDto(row as PeerDto)\n }\n\n private _getByPhone!: ISqliteStatement\n getByPhone(phone: string): IPeersRepository.PeerInfo | null {\n const row = this._getByPhone.get(phone)\n if (!row) return null\n\n return mapPeerDto(row as PeerDto)\n }\n\n private _delAll!: ISqliteStatement\n deleteAll(): void {\n this._delAll.run()\n }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { IReferenceMessagesRepository } from '@mtcute/core';
2
+ import { BaseSqliteStorageDriver } from '../driver.js';
3
+ export declare class SqliteRefMessagesRepository implements IReferenceMessagesRepository {
4
+ readonly _driver: BaseSqliteStorageDriver;
5
+ constructor(_driver: BaseSqliteStorageDriver);
6
+ private _store;
7
+ store(peerId: number, chatId: number, msgId: number): void;
8
+ private _getByPeer;
9
+ getByPeer(peerId: number): [number, number] | null;
10
+ private _del;
11
+ delete(chatId: number, msgIds: number[]): void;
12
+ private _delByPeer;
13
+ deleteByPeer(peerId: number): void;
14
+ private _delAll;
15
+ deleteAll(): void;
16
+ }
@@ -0,0 +1,45 @@
1
+ export class SqliteRefMessagesRepository {
2
+ constructor(_driver) {
3
+ this._driver = _driver;
4
+ _driver.registerMigration('ref_messages', 1, (db) => {
5
+ db.exec(`
6
+ create table if not exists message_refs (
7
+ peer_id integer not null,
8
+ chat_id integer not null,
9
+ msg_id integer not null
10
+ );
11
+ create index if not exists idx_message_refs_peer on message_refs (peer_id);
12
+ create index if not exists idx_message_refs on message_refs (chat_id, msg_id);
13
+ `);
14
+ });
15
+ _driver.onLoad(() => {
16
+ this._store = this._driver.db.prepare('insert or replace into message_refs (peer_id, chat_id, msg_id) values (?, ?, ?)');
17
+ this._getByPeer = this._driver.db.prepare('select chat_id, msg_id from message_refs where peer_id = ?');
18
+ this._del = this._driver.db.prepare('delete from message_refs where chat_id = ? and msg_id = ?');
19
+ this._delByPeer = this._driver.db.prepare('delete from message_refs where peer_id = ?');
20
+ this._delAll = this._driver.db.prepare('delete from message_refs');
21
+ });
22
+ }
23
+ store(peerId, chatId, msgId) {
24
+ this._store.run(peerId, chatId, msgId);
25
+ }
26
+ getByPeer(peerId) {
27
+ const res = this._getByPeer.get(peerId);
28
+ if (!res)
29
+ return null;
30
+ const res_ = res;
31
+ return [res_.chat_id, res_.msg_id];
32
+ }
33
+ delete(chatId, msgIds) {
34
+ for (const msgId of msgIds) {
35
+ this._driver._writeLater(this._del, [chatId, msgId]);
36
+ }
37
+ }
38
+ deleteByPeer(peerId) {
39
+ this._delByPeer.run(peerId);
40
+ }
41
+ deleteAll() {
42
+ this._delAll.run();
43
+ }
44
+ }
45
+ //# sourceMappingURL=ref-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref-messages.js","sourceRoot":"","sources":["../../../../../src/storage/sqlite/repository/ref-messages.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,2BAA2B;IACpC,YAAqB,OAAgC;QAAhC,YAAO,GAAP,OAAO,CAAyB;QACjD,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE;YAChD,EAAE,CAAC,IAAI,CAAC;;;;;;;;aAQP,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;QACF,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE;YAChB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CACjC,iFAAiF,CACpF,CAAA;YAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,4DAA4D,CAAC,CAAA;YAEvG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAAA;YAChG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAA;YACvF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAA;QACtE,CAAC,CAAC,CAAA;IACN,CAAC;IAGD,KAAK,CAAC,MAAc,EAAE,MAAc,EAAE,KAAa;QAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;IAC1C,CAAC;IAGD,SAAS,CAAC,MAAc;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACvC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,MAAM,IAAI,GAAG,GAA0B,CAAA;QAEvC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;IACtC,CAAC;IAGD,MAAM,CAAC,MAAc,EAAE,MAAgB;QACnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;YACxB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;SACvD;IACL,CAAC;IAGD,YAAY,CAAC,MAAc;QACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC/B,CAAC;IAGD,SAAS;QACL,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAA;IACtB,CAAC;CACJ","sourcesContent":["import { IReferenceMessagesRepository } from '@mtcute/core'\n\nimport { BaseSqliteStorageDriver } from '../driver.js'\nimport { ISqliteStatement } from '../types.js'\n\ninterface ReferenceMessageDto {\n peer_id: number\n chat_id: number\n msg_id: number\n}\n\nexport class SqliteRefMessagesRepository implements IReferenceMessagesRepository {\n constructor(readonly _driver: BaseSqliteStorageDriver) {\n _driver.registerMigration('ref_messages', 1, (db) => {\n db.exec(`\n create table if not exists message_refs (\n peer_id integer not null,\n chat_id integer not null,\n msg_id integer not null\n );\n create index if not exists idx_message_refs_peer on message_refs (peer_id);\n create index if not exists idx_message_refs on message_refs (chat_id, msg_id);\n `)\n })\n _driver.onLoad(() => {\n this._store = this._driver.db.prepare(\n 'insert or replace into message_refs (peer_id, chat_id, msg_id) values (?, ?, ?)',\n )\n\n this._getByPeer = this._driver.db.prepare('select chat_id, msg_id from message_refs where peer_id = ?')\n\n this._del = this._driver.db.prepare('delete from message_refs where chat_id = ? and msg_id = ?')\n this._delByPeer = this._driver.db.prepare('delete from message_refs where peer_id = ?')\n this._delAll = this._driver.db.prepare('delete from message_refs')\n })\n }\n\n private _store!: ISqliteStatement\n store(peerId: number, chatId: number, msgId: number): void {\n this._store.run(peerId, chatId, msgId)\n }\n\n private _getByPeer!: ISqliteStatement\n getByPeer(peerId: number): [number, number] | null {\n const res = this._getByPeer.get(peerId)\n if (!res) return null\n\n const res_ = res as ReferenceMessageDto\n\n return [res_.chat_id, res_.msg_id]\n }\n\n private _del!: ISqliteStatement\n delete(chatId: number, msgIds: number[]): void {\n for (const msgId of msgIds) {\n this._driver._writeLater(this._del, [chatId, msgId])\n }\n }\n\n private _delByPeer!: ISqliteStatement\n deleteByPeer(peerId: number): void {\n this._delByPeer.run(peerId)\n }\n\n private _delAll!: ISqliteStatement\n deleteAll(): void {\n this._delAll.run()\n }\n}\n"]}