@leemour/max-cli 0.2.0 → 0.4.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.
Files changed (109) hide show
  1. package/README.md +10 -3
  2. package/dist/cache/index.d.ts.map +1 -1
  3. package/dist/cache/index.js +3 -0
  4. package/dist/cache/index.js.map +1 -1
  5. package/dist/cache/schema.d.ts +4 -1
  6. package/dist/cache/schema.d.ts.map +1 -1
  7. package/dist/cache/schema.js +89 -2
  8. package/dist/cache/schema.js.map +1 -1
  9. package/dist/cache/store.d.ts +38 -11
  10. package/dist/cache/store.d.ts.map +1 -1
  11. package/dist/cache/store.js +123 -17
  12. package/dist/cache/store.js.map +1 -1
  13. package/dist/client.d.ts +41 -9
  14. package/dist/client.d.ts.map +1 -1
  15. package/dist/client.js +188 -49
  16. package/dist/client.js.map +1 -1
  17. package/dist/commands/account.js +1 -1
  18. package/dist/commands/account.js.map +1 -1
  19. package/dist/commands/body.d.ts +23 -0
  20. package/dist/commands/body.d.ts.map +1 -0
  21. package/dist/commands/body.js +36 -0
  22. package/dist/commands/body.js.map +1 -0
  23. package/dist/commands/cache.js +2 -2
  24. package/dist/commands/cache.js.map +1 -1
  25. package/dist/commands/chats.d.ts.map +1 -1
  26. package/dist/commands/chats.js +24 -3
  27. package/dist/commands/chats.js.map +1 -1
  28. package/dist/commands/config.d.ts +3 -0
  29. package/dist/commands/config.d.ts.map +1 -0
  30. package/dist/commands/config.js +55 -0
  31. package/dist/commands/config.js.map +1 -0
  32. package/dist/commands/contacts.d.ts.map +1 -1
  33. package/dist/commands/contacts.js +8 -3
  34. package/dist/commands/contacts.js.map +1 -1
  35. package/dist/commands/context.d.ts +27 -3
  36. package/dist/commands/context.d.ts.map +1 -1
  37. package/dist/commands/context.js +45 -8
  38. package/dist/commands/context.js.map +1 -1
  39. package/dist/commands/doctor.d.ts +18 -0
  40. package/dist/commands/doctor.d.ts.map +1 -0
  41. package/dist/commands/doctor.js +72 -0
  42. package/dist/commands/doctor.js.map +1 -0
  43. package/dist/commands/messages.d.ts.map +1 -1
  44. package/dist/commands/messages.js +129 -5
  45. package/dist/commands/messages.js.map +1 -1
  46. package/dist/commands/paging.d.ts +6 -3
  47. package/dist/commands/paging.d.ts.map +1 -1
  48. package/dist/commands/paging.js +14 -3
  49. package/dist/commands/paging.js.map +1 -1
  50. package/dist/commands/runs.d.ts.map +1 -1
  51. package/dist/commands/runs.js +4 -6
  52. package/dist/commands/runs.js.map +1 -1
  53. package/dist/commands/session.js +2 -2
  54. package/dist/commands/session.js.map +1 -1
  55. package/dist/commands/skill.d.ts +3 -0
  56. package/dist/commands/skill.d.ts.map +1 -0
  57. package/dist/commands/skill.js +23 -0
  58. package/dist/commands/skill.js.map +1 -0
  59. package/dist/config.d.ts +46 -2
  60. package/dist/config.d.ts.map +1 -1
  61. package/dist/config.js +103 -9
  62. package/dist/config.js.map +1 -1
  63. package/dist/deadline.d.ts +30 -0
  64. package/dist/deadline.d.ts.map +1 -0
  65. package/dist/deadline.js +45 -0
  66. package/dist/deadline.js.map +1 -0
  67. package/dist/diagnose.d.ts +68 -0
  68. package/dist/diagnose.d.ts.map +1 -0
  69. package/dist/diagnose.js +115 -0
  70. package/dist/diagnose.js.map +1 -0
  71. package/dist/domain/map.d.ts.map +1 -1
  72. package/dist/domain/map.js +42 -3
  73. package/dist/domain/map.js.map +1 -1
  74. package/dist/domain/models.d.ts +46 -0
  75. package/dist/domain/models.d.ts.map +1 -1
  76. package/dist/domain/models.js +11 -1
  77. package/dist/domain/models.js.map +1 -1
  78. package/dist/output.d.ts +7 -4
  79. package/dist/output.d.ts.map +1 -1
  80. package/dist/output.js +8 -11
  81. package/dist/output.js.map +1 -1
  82. package/dist/program.d.ts +2 -1
  83. package/dist/program.d.ts.map +1 -1
  84. package/dist/program.js +15 -2
  85. package/dist/program.js.map +1 -1
  86. package/dist/protocol/connection.d.ts +10 -0
  87. package/dist/protocol/connection.d.ts.map +1 -1
  88. package/dist/protocol/connection.js +20 -3
  89. package/dist/protocol/connection.js.map +1 -1
  90. package/dist/rendering/messages.d.ts +19 -0
  91. package/dist/rendering/messages.d.ts.map +1 -0
  92. package/dist/rendering/messages.js +138 -0
  93. package/dist/rendering/messages.js.map +1 -0
  94. package/dist/runs/events.d.ts +1 -1
  95. package/dist/runs/recording.d.ts +2 -2
  96. package/dist/runs/recording.d.ts.map +1 -1
  97. package/dist/runs/recording.js +3 -3
  98. package/dist/runs/recording.js.map +1 -1
  99. package/dist/testing/mock-max.d.ts.map +1 -1
  100. package/dist/testing/mock-max.js +16 -2
  101. package/dist/testing/mock-max.js.map +1 -1
  102. package/dist/testing/sandbox.d.ts +2 -0
  103. package/dist/testing/sandbox.d.ts.map +1 -0
  104. package/dist/testing/sandbox.js +31 -0
  105. package/dist/testing/sandbox.js.map +1 -0
  106. package/dist/version.d.ts +1 -1
  107. package/dist/version.js +1 -1
  108. package/package.json +7 -3
  109. package/skills/max-cli/SKILL.md +83 -0
package/README.md CHANGED
@@ -30,7 +30,7 @@ max messages list "Иван Петров"
30
30
  MAX схлопывает дубль — это измерено на реальном аккаунте, а не предположено.
31
31
  - **Имя чата не угадывается.** Часть названия, подходящая к двум чатам, — это отказ со списком
32
32
  кандидатов. Отправить не в тот разговор нельзя отменить.
33
- - **Диагностика, в которой нет содержимого.** `--verbose` показывает по строке на запрос,
33
+ - **Диагностика, в которой нет содержимого.** `--trace` показывает по строке на запрос,
34
34
  `--record` кладёт их в каталог запуска на 30 дней. Операция, опкод, идентификаторы, байты,
35
35
  длительности — да. Название чата, имя, текст, телефон, токен — никогда, ни обрезанными, ни
36
36
  хэшем.
@@ -115,7 +115,7 @@ max messages list 0 --before 2026-09-20T01:00:00Z
115
115
  Что делала команда:
116
116
 
117
117
  ```sh
118
- max chats list --verbose # показать по строке на запрос, ничего не сохраняя
118
+ max chats list --trace # показать по строке на запрос, ничего не сохраняя
119
119
  max chats list --record # сохранить, ничего не показывая
120
120
  max runs list # что делалось, новое сверху
121
121
  max runs show <id>
@@ -152,6 +152,13 @@ max chats list --json
152
152
  Ветвиться надо по коду возврата: `4` — нет сессии, `6` — не найдено, `9` — таймаут, `14` — исход
153
153
  неизвестен, `130` — прервано. Вся таблица — в [docs/commands.md](docs/commands.md).
154
154
 
155
+ **Инструкция для агента** — не список флагов, а ловушки и границы: что нельзя делать без просьбы,
156
+ почему id — строки, как повторять отправку. Ставится одной строкой, той же версии, что и `max`:
157
+
158
+ ```sh
159
+ mkdir -p ~/.claude/skills/max-cli && max skill show > ~/.claude/skills/max-cli/SKILL.md
160
+ ```
161
+
155
162
  ## Документация
156
163
 
157
164
  | | |
@@ -160,7 +167,7 @@ max chats list --json
160
167
  | [docs/usage.md](docs/usage.md) | вход, чтение, отправка, машинный режим |
161
168
  | [docs/sessions.md](docs/sessions.md) | токен, ключница, профили |
162
169
  | [docs/configuration.md](docs/configuration.md) | настройки, переменные, порядок разрешения |
163
- | [docs/diagnostics.md](docs/diagnostics.md) | `--verbose`, `--record`, `max runs` |
170
+ | [docs/diagnostics.md](docs/diagnostics.md) | `--trace`, `--record`, `max runs` |
164
171
  | [docs/security.md](docs/security.md) | что пишется на диск, а что никогда |
165
172
  | [docs/troubleshooting.md](docs/troubleshooting.md) | по симптому: что делать, когда не работает |
166
173
  | [docs/commands.md](docs/commands.md) | каждая команда и опция — **генерируется** из программы |
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAa,MAAM,YAAY,CAAA;AAEvD,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,qBAAkC,mBAAwB,KACzD,OAAO,CAAC,UAAU,GAAG,SAAS,CAehC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,UAAU,EAAa,MAAM,YAAY,CAAA;AAEvD,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,qBAAkC,mBAAwB,KACzD,OAAO,CAAC,UAAU,GAAG,SAAS,CAehC,CAAA"}
@@ -2,6 +2,7 @@ import { chmodSync, mkdirSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { resolvePaths } from "@leemour/cli-core";
4
4
  import { openCache } from "./open.js";
5
+ import { NewerCacheError } from "./schema.js";
5
6
  import { openStore } from "./store.js";
6
7
  /**
7
8
  * Opens this profile's record, **or gives up without failing the command**.
@@ -27,6 +28,8 @@ export const openProfileCache = async (profile, { env = process.env, onProblem }
27
28
  };
28
29
  /** The reason, never the path — a profile name and a home directory are nobody else's business. */
29
30
  const asReason = (error) => {
31
+ if (error instanceof NewerCacheError)
32
+ return error.message;
30
33
  const code = error?.code;
31
34
  return typeof code === "string" ? code : error instanceof Error ? error.name : "an unknown problem";
32
35
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAmB,SAAS,EAAE,MAAM,YAAY,CAAA;AAiBvD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,OAAe,EACf,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,KAA0B,EAAE,EACzB,EAAE;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACtE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,OAAO,KAAK,CAAC,CAAA;IAE/C,IAAI,CAAC;QACH,2FAA2F;QAC3F,uBAAuB;QACvB,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QACxD,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC5D,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACtB,OAAO,KAAK,CAAA;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,EAAE,CAAC,6DAA6D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC3F,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED,mGAAmG;AACnG,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAU,EAAE;IAC1C,MAAM,IAAI,GAAI,KAA4B,EAAE,IAAI,CAAA;IAChD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAA;AACrG,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAAmB,SAAS,EAAE,MAAM,YAAY,CAAA;AAiBvD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,OAAe,EACf,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,KAA0B,EAAE,EACzB,EAAE;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACtE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,OAAO,KAAK,CAAC,CAAA;IAE/C,IAAI,CAAC;QACH,2FAA2F;QAC3F,uBAAuB;QACvB,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QACxD,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC5D,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACtB,OAAO,KAAK,CAAA;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,EAAE,CAAC,6DAA6D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC3F,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED,mGAAmG;AACnG,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAU,EAAE;IAC1C,IAAI,KAAK,YAAY,eAAe;QAAE,OAAO,KAAK,CAAC,OAAO,CAAA;IAC1D,MAAM,IAAI,GAAI,KAA4B,EAAE,IAAI,CAAA;IAChD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAA;AACrG,CAAC,CAAA"}
@@ -3,7 +3,7 @@ import type { CacheDatabase } from "./driver.js";
3
3
  * **Raise this on every change to the statements below.** The second schema change is the one that
4
4
  * corrupts somebody's file, because the first is always made while the only copy is your own.
5
5
  */
6
- export declare const SCHEMA_VERSION = 2;
6
+ export declare const SCHEMA_VERSION = 4;
7
7
  /**
8
8
  * Brings a file up to date, and **refuses a file from the future** rather than writing to it.
9
9
  *
@@ -19,5 +19,8 @@ export declare const SCHEMA_VERSION = 2;
19
19
  * Contacts that are in no chat would be exactly that (`RES-7`), and the day they arrive this
20
20
  * becomes `ALTER TABLE … ADD COLUMN` and this paragraph gets rewritten.
21
21
  */
22
+ /** Ours, so its message is known to hold no path and can be shown as it is. */
23
+ export declare class NewerCacheError extends Error {
24
+ }
22
25
  export declare const migrate: (database: CacheDatabase) => void;
23
26
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/cache/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD;;;GAGG;AACH,eAAO,MAAM,cAAc,IAAI,CAAA;AAyH/B;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,OAAO,GAAI,UAAU,aAAa,KAAG,IAgBjD,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/cache/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD;;;GAGG;AACH,eAAO,MAAM,cAAc,IAAI,CAAA;AAqM/B;;;;;;;;;;;;;;GAcG;AACH,+EAA+E;AAC/E,qBAAa,eAAgB,SAAQ,KAAK;CAAG;AAE7C,eAAO,MAAM,OAAO,GAAI,UAAU,aAAa,KAAG,IAgBjD,CAAA"}
@@ -2,7 +2,7 @@
2
2
  * **Raise this on every change to the statements below.** The second schema change is the one that
3
3
  * corrupts somebody's file, because the first is always made while the only copy is your own.
4
4
  */
5
- export const SCHEMA_VERSION = 2;
5
+ export const SCHEMA_VERSION = 4;
6
6
  /**
7
7
  * Everything the cache holds, and the indexes are part of it rather than an afterthought — each
8
8
  * one exists for a query that is actually made.
@@ -78,6 +78,7 @@ const STATEMENTS = [
78
78
  text TEXT NOT NULL,
79
79
  outgoing INTEGER,
80
80
  attachments TEXT NOT NULL,
81
+ link TEXT,
81
82
  fetched_at INTEGER NOT NULL,
82
83
  PRIMARY KEY (chat_id, id)
83
84
  )`,
@@ -106,6 +107,77 @@ const STATEMENTS = [
106
107
  kind TEXT PRIMARY KEY,
107
108
  at INTEGER NOT NULL
108
109
  )`,
110
+ /**
111
+ * **Search, as three indexes over tables that already hold the text.**
112
+ *
113
+ * `content=` means FTS5 stores the index and **not a second copy of the words** — it reads the
114
+ * columns back from the base table by rowid. That matters twice: the file does not double, and
115
+ * message bodies do not get a second home in it.
116
+ *
117
+ * ⚠ **`trigram`, not `unicode61`, and the difference is the whole point.** Measured 2026-09-22
118
+ * on both runtimes: `unicode61` matches whole words or prefixes, so searching `етро` finds
119
+ * nothing, while `trigram` matches inside a word and finds `Иван Петров`. `chats.resolve`
120
+ * already matches with `includes()`, so substring is the behaviour that was already promised.
121
+ *
122
+ * Both tokenizers fold case for any alphabet, which `LIKE`, `lower()` and `COLLATE NOCASE` do
123
+ * **not** — those are ASCII-only, and a name search built on them silently misses half a Russian
124
+ * address book. That measurement is why this is FTS5 at all.
125
+ *
126
+ * ⚠ **A trigram index cannot answer a query shorter than three characters.** It returns nothing
127
+ * rather than failing, so the caller refuses such a query instead of printing an empty list —
128
+ * `src/client.ts`, and it refuses on every path so the answer cannot depend on whether a cache
129
+ * happens to exist.
130
+ */
131
+ `CREATE VIRTUAL TABLE IF NOT EXISTS chats_fts USING fts5(title, content='chats', tokenize='trigram')`,
132
+ `CREATE VIRTUAL TABLE IF NOT EXISTS people_fts USING fts5(name, username, content='people', tokenize='trigram')`,
133
+ `CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(text, content='messages', tokenize='trigram')`,
134
+ /**
135
+ * **Triggers, because an external-content index does not follow its table on its own.**
136
+ *
137
+ * Measured: rename a chat with no trigger in place and a search for the *old* title still
138
+ * matches the row, handing back the new name. Nothing errors; the index is simply a lie. And
139
+ * SQLite reuses a freed rowid, so a deleted chat can bequeath its words to the next one.
140
+ *
141
+ * They are triggers rather than writes in TypeScript because there is more than one write path
142
+ * — the chat list, the people upsert, the delta merge, the message window — and the failure of
143
+ * forgetting one is invisible.
144
+ *
145
+ * ⚠ Verified on this project's real statements, not on a plain `UPDATE`: our writes are
146
+ * `INSERT … ON CONFLICT DO UPDATE`, and `people` resolves its columns with `coalesce`, so the
147
+ * trigger has to index the row that results rather than the values that arrived. `new.*` in an
148
+ * `AFTER UPDATE` trigger is the finished row, which is what makes a re-sent person with no name
149
+ * keep the name we already had.
150
+ */
151
+ `CREATE TRIGGER IF NOT EXISTS chats_fts_ai AFTER INSERT ON chats BEGIN
152
+ INSERT INTO chats_fts(rowid, title) VALUES (new.rowid, new.title);
153
+ END`,
154
+ `CREATE TRIGGER IF NOT EXISTS chats_fts_ad AFTER DELETE ON chats BEGIN
155
+ INSERT INTO chats_fts(chats_fts, rowid, title) VALUES ('delete', old.rowid, old.title);
156
+ END`,
157
+ `CREATE TRIGGER IF NOT EXISTS chats_fts_au AFTER UPDATE ON chats BEGIN
158
+ INSERT INTO chats_fts(chats_fts, rowid, title) VALUES ('delete', old.rowid, old.title);
159
+ INSERT INTO chats_fts(rowid, title) VALUES (new.rowid, new.title);
160
+ END`,
161
+ `CREATE TRIGGER IF NOT EXISTS people_fts_ai AFTER INSERT ON people BEGIN
162
+ INSERT INTO people_fts(rowid, name, username) VALUES (new.rowid, new.name, new.username);
163
+ END`,
164
+ `CREATE TRIGGER IF NOT EXISTS people_fts_ad AFTER DELETE ON people BEGIN
165
+ INSERT INTO people_fts(people_fts, rowid, name, username) VALUES ('delete', old.rowid, old.name, old.username);
166
+ END`,
167
+ `CREATE TRIGGER IF NOT EXISTS people_fts_au AFTER UPDATE ON people BEGIN
168
+ INSERT INTO people_fts(people_fts, rowid, name, username) VALUES ('delete', old.rowid, old.name, old.username);
169
+ INSERT INTO people_fts(rowid, name, username) VALUES (new.rowid, new.name, new.username);
170
+ END`,
171
+ `CREATE TRIGGER IF NOT EXISTS messages_fts_ai AFTER INSERT ON messages BEGIN
172
+ INSERT INTO messages_fts(rowid, text) VALUES (new.rowid, new.text);
173
+ END`,
174
+ `CREATE TRIGGER IF NOT EXISTS messages_fts_ad AFTER DELETE ON messages BEGIN
175
+ INSERT INTO messages_fts(messages_fts, rowid, text) VALUES ('delete', old.rowid, old.text);
176
+ END`,
177
+ `CREATE TRIGGER IF NOT EXISTS messages_fts_au AFTER UPDATE ON messages BEGIN
178
+ INSERT INTO messages_fts(messages_fts, rowid, text) VALUES ('delete', old.rowid, old.text);
179
+ INSERT INTO messages_fts(rowid, text) VALUES (new.rowid, new.text);
180
+ END`,
109
181
  `CREATE TABLE IF NOT EXISTS fetch_lease (
110
182
  chat_id TEXT NOT NULL,
111
183
  anchor TEXT NOT NULL,
@@ -129,10 +201,13 @@ const STATEMENTS = [
129
201
  * Contacts that are in no chat would be exactly that (`RES-7`), and the day they arrive this
130
202
  * becomes `ALTER TABLE … ADD COLUMN` and this paragraph gets rewritten.
131
203
  */
204
+ /** Ours, so its message is known to hold no path and can be shown as it is. */
205
+ export class NewerCacheError extends Error {
206
+ }
132
207
  export const migrate = (database) => {
133
208
  const current = Number(database.prepare("PRAGMA user_version").get()?.user_version ?? 0);
134
209
  if (current > SCHEMA_VERSION) {
135
- throw new Error(`this cache was written by a newer max (schema ${current}, this one speaks ${SCHEMA_VERSION}) — ` +
210
+ throw new NewerCacheError(`this cache was written by a newer max (schema ${current}, this one speaks ${SCHEMA_VERSION}) — ` +
136
211
  "run `max cache clear`, or use the newer version");
137
212
  }
138
213
  if (current > 0 && current < SCHEMA_VERSION)
@@ -150,6 +225,18 @@ export const migrate = (database) => {
150
225
  * and keeping it would claim a sweep whose rows have just been thrown away.
151
226
  */
152
227
  const rebuild = (database) => {
228
+ // ⚠ **Virtual tables first.** An FTS5 index keeps four shadow tables of its own, and
229
+ // `sqlite_master` lists them as ordinary tables. Dropping one of those out from under a live
230
+ // index is how a rebuild leaves a corrupt file behind. Dropping the virtual table takes its
231
+ // shadows with it, and the second pass then finds only real tables.
232
+ //
233
+ // It happens to work without this today, because `sqlite_master` returns them in creation order
234
+ // and `IF EXISTS` swallows the leftovers. That is an accident of ordering, not a guarantee.
235
+ const virtual = database
236
+ .prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND sql LIKE 'CREATE VIRTUAL TABLE%'")
237
+ .all();
238
+ for (const { name } of virtual)
239
+ database.exec(`DROP TABLE IF EXISTS "${String(name)}"`);
153
240
  const tables = database
154
241
  .prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'")
155
242
  .all();
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/cache/schema.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAE/B;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG;IACjB;;;;;;;;;KASG;IACH,6EAA6E;IAE7E;;;;;;;;;OASG;IACH;;;;;;;;KAQG;IACH,gFAAgF;IAEhF;;;;OAIG;IACH;;;;KAIG;IACH,0EAA0E;IAE1E;;;;;;;OAOG;IACH;;;KAGG;IAEH;;;;;;;;;;;;KAYG;IACH,8EAA8E;IAC9E,kFAAkF;IAClF,8FAA8F;IAC9F,4DAA4D;IAE5D;;;;OAIG;IACH;;;;;KAKG;IACH,0EAA0E;IAE1E;;;;OAIG;IACH;;;KAGG;IAEH;;;;;;KAMG;CACJ,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAuB,EAAQ,EAAE;IACvD,MAAM,OAAO,GAAG,MAAM,CACnB,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,GAAG,EAAgC,EAAE,YAAY,IAAI,CAAC,CAChG,CAAA;IAED,IAAI,OAAO,GAAG,cAAc,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,iDAAiD,OAAO,qBAAqB,cAAc,MAAM;YAC/F,iDAAiD,CACpD,CAAA;IACH,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,cAAc;QAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9D,KAAK,MAAM,SAAS,IAAI,UAAU;QAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5D,QAAQ,CAAC,IAAI,CAAC,yBAAyB,cAAc,EAAE,CAAC,CAAA;AAC1D,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,GAAG,CAAC,QAAuB,EAAQ,EAAE;IAChD,MAAM,MAAM,GAAG,QAAQ;SACpB,OAAO,CAAC,kFAAkF,CAAC;SAC3F,GAAG,EAAE,CAAA;IAER,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,MAAM;QAAE,QAAQ,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxF,CAAC,CAAA"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/cache/schema.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAA;AAE/B;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAG;IACjB;;;;;;;;;KASG;IACH,6EAA6E;IAE7E;;;;;;;;;OASG;IACH;;;;;;;;KAQG;IACH,gFAAgF;IAEhF;;;;OAIG;IACH;;;;KAIG;IACH,0EAA0E;IAE1E;;;;;;;OAOG;IACH;;;KAGG;IAEH;;;;;;;;;;;;;KAaG;IACH,8EAA8E;IAC9E,kFAAkF;IAClF,8FAA8F;IAC9F,4DAA4D;IAE5D;;;;OAIG;IACH;;;;;KAKG;IACH,0EAA0E;IAE1E;;;;OAIG;IACH;;;KAGG;IAEH;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,qGAAqG;IACrG,gHAAgH;IAChH,0GAA0G;IAE1G;;;;;;;;;;;;;;;;OAgBG;IACH;;OAEK;IACL;;OAEK;IACL;;;OAGK;IAEL;;OAEK;IACL;;OAEK;IACL;;;OAGK;IAEL;;OAEK;IACL;;OAEK;IACL;;;OAGK;IAEL;;;;;;KAMG;CACJ,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,+EAA+E;AAC/E,MAAM,OAAO,eAAgB,SAAQ,KAAK;CAAG;AAE7C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAuB,EAAQ,EAAE;IACvD,MAAM,OAAO,GAAG,MAAM,CACnB,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,GAAG,EAAgC,EAAE,YAAY,IAAI,CAAC,CAChG,CAAA;IAED,IAAI,OAAO,GAAG,cAAc,EAAE,CAAC;QAC7B,MAAM,IAAI,eAAe,CACvB,iDAAiD,OAAO,qBAAqB,cAAc,MAAM;YAC/F,iDAAiD,CACpD,CAAA;IACH,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,cAAc;QAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9D,KAAK,MAAM,SAAS,IAAI,UAAU;QAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAC5D,QAAQ,CAAC,IAAI,CAAC,yBAAyB,cAAc,EAAE,CAAC,CAAA;AAC1D,CAAC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,GAAG,CAAC,QAAuB,EAAQ,EAAE;IAChD,qFAAqF;IACrF,6FAA6F;IAC7F,4FAA4F;IAC5F,oEAAoE;IACpE,EAAE;IACF,gGAAgG;IAChG,4FAA4F;IAC5F,MAAM,OAAO,GAAG,QAAQ;SACrB,OAAO,CAAC,0FAA0F,CAAC;SACnG,GAAG,EAAE,CAAA;IACR,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,OAAO;QAAE,QAAQ,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAEvF,MAAM,MAAM,GAAG,QAAQ;SACpB,OAAO,CAAC,kFAAkF,CAAC;SAC3F,GAAG,EAAE,CAAA;IAER,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,MAAM;QAAE,QAAQ,CAAC,IAAI,CAAC,yBAAyB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxF,CAAC,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { Chat, Contact, Id, Message } from "../domain/models.js";
1
+ import type { Chat, ChatKind, Contact, Id, Message, MessageHit } from "../domain/models.js";
2
2
  import type { CacheDatabase } from "./driver.js";
3
3
  /** How we came to know a person. Diagnostic — what makes somebody a *contact* is the query. */
4
4
  export type PersonSource = "login" | "info" | "participant" | "sync";
@@ -7,6 +7,21 @@ export interface PageOptions {
7
7
  order: PersonOrder;
8
8
  limit: number;
9
9
  offset: number;
10
+ /** Part of a name, already checked to be long enough for the index (`src/client.ts`). */
11
+ query?: string;
12
+ }
13
+ export interface ChatPageOptions {
14
+ limit: number;
15
+ offset: number;
16
+ query?: string;
17
+ kind?: ChatKind;
18
+ }
19
+ export interface MessageSearch {
20
+ query: string;
21
+ /** One chat, or every chat we hold when absent. */
22
+ chatId?: Id;
23
+ limit: number;
24
+ offset: number;
10
25
  }
11
26
  /**
12
27
  * One login's worth of change: the chats that moved, the people that changed, who is in which
@@ -47,11 +62,12 @@ export interface CacheStore {
47
62
  read(freshForMs: number): Chat[] | undefined;
48
63
  write(chats: Chat[]): void;
49
64
  /** One page, newest first, in SQL rather than by building the whole list and slicing it. */
50
- page(options: {
51
- limit: number;
52
- offset: number;
53
- }): Chat[];
54
- count(): number;
65
+ page(options: ChatPageOptions): Chat[];
66
+ /** ⚠ Takes the same filter as `page`, or the two disagree about whether a next page exists. */
67
+ count(options?: {
68
+ query?: string;
69
+ kind?: ChatKind;
70
+ }): number;
55
71
  };
56
72
  people: {
57
73
  /**
@@ -63,7 +79,9 @@ export interface CacheStore {
63
79
  */
64
80
  contacts(options: PageOptions): Contact[];
65
81
  /** How many that query would return, so a page can say whether another one exists. */
66
- countContacts(): number;
82
+ countContacts(options?: {
83
+ query?: string;
84
+ }): number;
67
85
  /** Everyone we can put a name to, contact or not. */
68
86
  page(options: PageOptions): Contact[];
69
87
  /** Everyone, counted — what `max contacts sync` reports as known. */
@@ -72,6 +90,8 @@ export interface CacheStore {
72
90
  upsert(people: Contact[], source: PersonSource): void;
73
91
  /** The chats this person is in — which, every chat here being one we are in, is the shared set. */
74
92
  chatsWith(personId: Id): Id[];
93
+ /** The names we hold for these people; anyone unnamed or unknown is absent from the map. */
94
+ names(ids: Id[]): Map<Id, string>;
75
95
  /**
76
96
  * Recomputes `last_messaged_at` from the dialogs we hold.
77
97
  *
@@ -95,13 +115,20 @@ export interface CacheStore {
95
115
  write(chatId: Id, messages: Message[]): void;
96
116
  /** After a send, what we hold for that chat is missing the message we just added. */
97
117
  invalidate(chatId: Id): void;
118
+ /** `before` messages up to and including `time`, and `after` messages later than it, oldest first. */
119
+ window(chatId: Id, time: number, before: number, after: number): Message[];
98
120
  /**
99
- * When a message was sent, for `messages list --before <id>`.
121
+ * Messages whose text contains `query`, newest first, across every chat we hold or one.
100
122
  *
101
- * `undefined` for an id we have never stored — which is exactly what a deleted message looks
102
- * like, since it is no longer in the history MAX returns either.
123
+ * ⚠ **It answers from this database and never asks MAX**, because MAX has no search operation
124
+ * we know of. So it finds what has been read, not what exists — `src/client.ts` is where that
125
+ * is said out loud rather than left for somebody to discover.
103
126
  */
104
- timeOf(id: Id): number | undefined;
127
+ search(options: MessageSearch): MessageHit[];
128
+ countSearch(options: {
129
+ query: string;
130
+ chatId?: Id;
131
+ }): number;
105
132
  };
106
133
  /** True when this process may go to MAX for that window; false when somebody else already is. */
107
134
  claim(chatId: Id, anchor: string, holder: string, forMs: number): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,43 @@
1
1
  import { migrate } from "./schema.js";
2
2
  export const openStore = ({ database, now = () => Date.now() }) => {
3
3
  migrate(database);
4
+ /**
5
+ * **What the person typed is data, not a query.** FTS5 reads its argument as an expression, so
6
+ * `O'Brien` is a syntax error, `a-b` is a column that does not exist and a bare `"` never
7
+ * terminates — a chat whose name has an apostrophe would take the command down with it.
8
+ *
9
+ * Wrapping in double quotes makes the whole thing one literal phrase, and doubling any quote
10
+ * inside keeps it that way. This is the only place a MATCH argument is built; nowhere else
11
+ * concatenates one.
12
+ */
13
+ const phrase = (query) => `"${query.replace(/"/g, '""')}"`;
14
+ /**
15
+ * The `WHERE` for a chat listing, built once and handed to both the page and its count.
16
+ *
17
+ * ⚠ They have to come from the same function. A page that filters and a count that does not is
18
+ * a `hasMore` that lies, and it lies quietly — the reader simply never sees the last page.
19
+ */
20
+ const chatWhere = ({ query, kind }) => {
21
+ const clauses = [];
22
+ const values = [];
23
+ if (query !== undefined) {
24
+ clauses.push("c.rowid IN (SELECT rowid FROM chats_fts WHERE chats_fts MATCH ?)");
25
+ values.push(phrase(query));
26
+ }
27
+ if (kind !== undefined) {
28
+ clauses.push("c.kind = ?");
29
+ values.push(kind);
30
+ }
31
+ return { sql: clauses.length === 0 ? "" : ` WHERE ${clauses.join(" AND ")}`, values };
32
+ };
33
+ const peopleWhere = ({ query }) => {
34
+ if (query === undefined)
35
+ return { sql: "", values: [] };
36
+ return {
37
+ sql: " AND p.rowid IN (SELECT rowid FROM people_fts WHERE people_fts MATCH ?)",
38
+ values: [phrase(query)],
39
+ };
40
+ };
4
41
  const markFetched = database.prepare("INSERT INTO fetched (kind, at) VALUES (?, ?) ON CONFLICT(kind) DO UPDATE SET at = excluded.at");
5
42
  const fetchedAt = database.prepare("SELECT at FROM fetched WHERE kind = ?");
6
43
  const isFresh = (kind, freshForMs) => {
@@ -108,11 +145,12 @@ export const openStore = ({ database, now = () => Date.now() }) => {
108
145
  * the point of it.
109
146
  */
110
147
  const putMessage = database.prepare(`
111
- INSERT INTO messages (chat_id, id, sender_id, sender_name, time, update_time, text, outgoing, attachments, fetched_at)
112
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
148
+ INSERT INTO messages (chat_id, id, sender_id, sender_name, time, update_time, text, outgoing, attachments, link, fetched_at)
149
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
113
150
  ON CONFLICT(chat_id, id) DO UPDATE SET
114
151
  sender_name = excluded.sender_name, update_time = excluded.update_time, text = excluded.text,
115
- outgoing = excluded.outgoing, attachments = excluded.attachments, fetched_at = excluded.fetched_at
152
+ outgoing = excluded.outgoing, attachments = excluded.attachments, link = excluded.link,
153
+ fetched_at = excluded.fetched_at
116
154
  WHERE coalesce(excluded.update_time, 0) >= coalesce(messages.update_time, 0)`);
117
155
  const toChat = (row) => ({
118
156
  id: String(row.id),
@@ -132,6 +170,11 @@ export const openStore = ({ database, now = () => Date.now() }) => {
132
170
  text: String(row.text),
133
171
  outgoing: row.outgoing === null ? null : row.outgoing === 1,
134
172
  attachments: JSON.parse(String(row.attachments)),
173
+ replyTo: null,
174
+ forwardedFrom: null,
175
+ ...(row.link === null || row.link === undefined
176
+ ? {}
177
+ : JSON.parse(String(row.link))),
135
178
  });
136
179
  const epoch = (iso) => (iso === null ? null : new Date(iso).getTime());
137
180
  return {
@@ -141,11 +184,18 @@ export const openStore = ({ database, now = () => Date.now() }) => {
141
184
  return undefined;
142
185
  return database.prepare("SELECT * FROM chats ORDER BY last_message_at DESC").all().map(toChat);
143
186
  },
144
- page: ({ limit, offset }) => database
145
- .prepare("SELECT * FROM chats ORDER BY last_message_at DESC LIMIT ? OFFSET ?")
146
- .all(limit, offset)
147
- .map(toChat),
148
- count: () => Number(database.prepare("SELECT COUNT(*) AS n FROM chats").get()?.n ?? 0),
187
+ page: ({ limit, offset, query, kind }) => {
188
+ const where = chatWhere({ query, kind });
189
+ return database
190
+ .prepare(`SELECT c.* FROM chats c${where.sql} ORDER BY c.last_message_at DESC LIMIT ? OFFSET ?`)
191
+ .all(...where.values, limit, offset)
192
+ .map(toChat);
193
+ },
194
+ count: ({ query, kind } = {}) => {
195
+ const where = chatWhere({ query, kind });
196
+ const row = database.prepare(`SELECT COUNT(*) AS n FROM chats c${where.sql}`).get(...where.values);
197
+ return Number(row?.n ?? 0);
198
+ },
149
199
  write: (chats) => {
150
200
  const at = now();
151
201
  for (const chat of chats) {
@@ -155,11 +205,20 @@ export const openStore = ({ database, now = () => Date.now() }) => {
155
205
  },
156
206
  },
157
207
  people: {
158
- contacts: ({ order, limit, offset }) => database
159
- .prepare(`SELECT DISTINCT p.* ${CONTACTS_FROM} ORDER BY ${ORDER[order]} LIMIT ? OFFSET ?`)
160
- .all(limit, offset)
161
- .map(toContact),
162
- countContacts: () => Number(database.prepare(`SELECT COUNT(DISTINCT p.id) AS n ${CONTACTS_FROM}`).get()?.n ?? 0),
208
+ contacts: ({ order, limit, offset, query }) => {
209
+ const where = peopleWhere({ query });
210
+ return database
211
+ .prepare(`SELECT DISTINCT p.* ${CONTACTS_FROM}${where.sql} ORDER BY ${ORDER[order]} LIMIT ? OFFSET ?`)
212
+ .all(...where.values, limit, offset)
213
+ .map(toContact);
214
+ },
215
+ countContacts: ({ query } = {}) => {
216
+ const where = peopleWhere({ query });
217
+ const row = database
218
+ .prepare(`SELECT COUNT(DISTINCT p.id) AS n ${CONTACTS_FROM}${where.sql}`)
219
+ .get(...where.values);
220
+ return Number(row?.n ?? 0);
221
+ },
163
222
  page: ({ order, limit, offset }) => database
164
223
  .prepare(`SELECT p.* FROM people p ORDER BY ${ORDER[order]} LIMIT ? OFFSET ?`)
165
224
  .all(limit, offset)
@@ -171,6 +230,16 @@ export const openStore = ({ database, now = () => Date.now() }) => {
171
230
  .prepare("SELECT chat_id FROM chat_members WHERE person_id = ?")
172
231
  .all(personId)
173
232
  .map((row) => String(row.chat_id)),
233
+ names: (ids) => {
234
+ const named = new Map();
235
+ const one = database.prepare("SELECT name FROM people WHERE id = ? AND name IS NOT NULL");
236
+ for (const id of new Set(ids)) {
237
+ const row = one.get(id);
238
+ if (row?.name)
239
+ named.set(id, String(row.name));
240
+ }
241
+ return named;
242
+ },
174
243
  },
175
244
  syncMarker: () => database.prepare("SELECT marker FROM sync_marker WHERE id = 1").get()
176
245
  ?.marker,
@@ -234,7 +303,9 @@ export const openStore = ({ database, now = () => Date.now() }) => {
234
303
  return;
235
304
  const at = now();
236
305
  for (const message of messages) {
237
- putMessage.run(chatId, message.id, message.senderId, message.senderName, epoch(message.timestamp) ?? 0, epoch(message.editedAt), message.text, message.outgoing === null ? null : Number(message.outgoing), JSON.stringify(message.attachments), at);
306
+ putMessage.run(chatId, message.id, message.senderId, message.senderName, epoch(message.timestamp) ?? 0, epoch(message.editedAt), message.text, message.outgoing === null ? null : Number(message.outgoing), JSON.stringify(message.attachments), message.replyTo || message.forwardedFrom
307
+ ? JSON.stringify({ replyTo: message.replyTo, forwardedFrom: message.forwardedFrom })
308
+ : null, at);
238
309
  }
239
310
  const times = messages.map((message) => epoch(message.timestamp) ?? 0);
240
311
  database
@@ -246,9 +317,44 @@ export const openStore = ({ database, now = () => Date.now() }) => {
246
317
  invalidate: (chatId) => {
247
318
  database.prepare("DELETE FROM fetched WHERE kind = ?").run(`messages:${chatId}`);
248
319
  },
249
- timeOf: (id) => {
250
- const row = database.prepare("SELECT time FROM messages WHERE id = ? LIMIT 1").get(id);
251
- return row?.time === undefined ? undefined : Number(row.time);
320
+ search: ({ query, chatId, limit, offset }) => {
321
+ const values = [phrase(query)];
322
+ let sql = `SELECT m.*, c.title AS chat_title FROM messages_fts f
323
+ JOIN messages m ON m.rowid = f.rowid
324
+ LEFT JOIN chats c ON c.id = m.chat_id
325
+ WHERE messages_fts MATCH ?`;
326
+ if (chatId !== undefined) {
327
+ sql += " AND m.chat_id = ?";
328
+ values.push(chatId);
329
+ }
330
+ sql += " ORDER BY m.time DESC LIMIT ? OFFSET ?";
331
+ values.push(limit, offset);
332
+ return database
333
+ .prepare(sql)
334
+ .all(...values)
335
+ .map((row) => ({
336
+ ...toMessage(row),
337
+ chatTitle: row.chat_title === null || row.chat_title === undefined ? null : String(row.chat_title),
338
+ }));
339
+ },
340
+ countSearch: ({ query, chatId }) => {
341
+ const values = [phrase(query)];
342
+ let sql = `SELECT COUNT(*) AS n FROM messages_fts f JOIN messages m ON m.rowid = f.rowid
343
+ WHERE messages_fts MATCH ?`;
344
+ if (chatId !== undefined) {
345
+ sql += " AND m.chat_id = ?";
346
+ values.push(chatId);
347
+ }
348
+ return Number(database.prepare(sql).get(...values)?.n ?? 0);
349
+ },
350
+ window: (chatId, time, before, after) => {
351
+ const earlier = database
352
+ .prepare("SELECT * FROM messages WHERE chat_id = ? AND time <= ? ORDER BY time DESC LIMIT ?")
353
+ .all(chatId, time, before);
354
+ const later = database
355
+ .prepare("SELECT * FROM messages WHERE chat_id = ? AND time > ? ORDER BY time ASC LIMIT ?")
356
+ .all(chatId, time, after);
357
+ return [...earlier.reverse(), ...later].map(toMessage);
252
358
  },
253
359
  },
254
360
  claim: (chatId, anchor, holder, forMs) => {
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"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"}