@openclaw/matrix 2026.7.2-beta.7 → 2026.8.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{account-selection-kqquRzCf.js → account-selection-CWuhuFn1.js} +7 -8
- package/dist/{accounts-DfngqebB.js → accounts-BCzyubQt.js} +3 -3
- package/dist/api.js +7 -10
- package/dist/{approval-handler.runtime-DSeaIsGa.js → approval-handler.runtime-CJXCUdRg.js} +5 -5
- package/dist/{approval-ids-BdJGPAJT.js → approval-ids-7rf7etWE.js} +1 -1
- package/dist/{approval-reaction-auth-BjOpELxu.js → approval-reaction-auth-wBwbEDpZ.js} +2 -2
- package/dist/{approval-reactions-D-BxBK_L.js → approval-reactions-tXh9KYrW.js} +2 -8
- package/dist/auth-presence.js +2 -2
- package/dist/{channel-vj788dNZ.js → channel-VSrHgTON.js} +156 -136
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CLoF2S9T.js → channel.runtime-pOOL0uT_.js} +70 -56
- package/dist/{config-schema-Djxw3C6b.js → channel.setup-PpxRP9Du.js} +50 -3
- package/dist/{cli-DMqfDE-q.js → cli-CkTfKC_c.js} +16 -16
- package/dist/{cli-metadata-C7D53SND.js → cli-metadata-B1d1aGM5.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-CeGw0G5S.js +784 -0
- package/dist/{client-bootstrap-XsIkHNt0.js → client-bootstrap-BFwT_2VT.js} +25 -61
- package/dist/{client-6eRENr7k.js → client-sJesKQmp.js} +4 -4
- package/dist/client-support-DLj4vDeu.js +93 -0
- package/dist/config-update-Bor_Pjsv.js +150 -0
- package/dist/contract-api.js +2 -2
- package/dist/{credentials-W2EmwRhu.js → credentials-BdAaWuiR.js} +2 -1
- package/dist/credentials-read-B37cQknZ.js +51 -0
- package/dist/credentials-state-B3cuUFwZ.js +27 -0
- package/dist/{credentials-write.runtime-Be9zNSUw.js → credentials-write.runtime-nAV2-5uR.js} +1 -1
- package/dist/{crypto-runtime-D9_6J5tZ.js → crypto-runtime-Bnz3zEcS.js} +55 -32
- package/dist/direct-room-RinHjtqX.js +71 -0
- package/dist/{directory-live-C8dVBiCc.js → directory-live-Bvg2wAnR.js} +1 -2
- package/dist/{doctor-CM8ijNpW.js → doctor-EWf9CDso.js} +2 -2
- package/dist/{doctor-contract-BMSJkkAE.js → doctor-contract-DEt4O4Zt.js} +2 -3
- package/dist/doctor-contract-api.js +202 -90
- package/dist/{draft-stream-CtvOXq0Z.js → draft-stream-BRi7PRRS.js} +20 -23
- package/dist/{encryption-guidance-CbEFe38F.js → encryption-guidance-DmLY8NiO.js} +1 -1
- package/dist/{env-auth-CQsYbz-p.js → env-auth-MVS-Vv41.js} +4 -3
- package/dist/{env-vars-B0NxQnPk.js → env-vars-dGqak9dN.js} +1 -1
- package/dist/{errors-C47hvAF8.js → errors-DKVS3_DO.js} +2 -5
- package/dist/{file-sync-store-DiiFsayX.js → file-sync-store-DjskBX2o.js} +24 -3
- package/dist/helper-api.js +2 -2
- package/dist/{idb-persistence-B6x7dMsF.js → idb-persistence-BM0P27Zg.js} +3 -2
- package/dist/{inbound-dedupe-CaBLblef.js → inbound-dedupe-RvSLqdsz.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{logger-D0GCSDQq.js → logger-B_71hN6W.js} +1 -1
- package/dist/{logging-DV-p52N0.js → logging-DRjvUOIh.js} +1 -1
- package/dist/{media-text-BTwzADS_.js → media-text-JudlYOSc.js} +1 -1
- package/dist/{messages-DxQJkhxs.js → messages-BW0s-6Y9.js} +7 -7
- package/dist/{monitor-VyWlSLwo.js → monitor-Ddfc-vjX.js} +394 -384
- package/dist/plugin-entry.handlers.runtime.js +3 -3
- package/dist/probe.runtime-Dr91B_X3.js +2 -0
- package/dist/profile-D-Wubo0A.js +108 -0
- package/dist/{profile-update-CffmyW_4.js → profile-update-BkgWYDIp.js} +3 -2
- package/dist/{reaction-events-B00WSi98.js → reaction-events-nfUbFLdV.js} +9 -6
- package/dist/{recovery-key-store-BNnHvXdk.js → recovery-key-store-CognuDys.js} +5 -4
- package/dist/{resolve-targets-nm2L48sh.js → resolve-targets-BJAPY4Vb.js} +1 -1
- package/dist/{resolver.runtime-DS6uPaEe.js → resolver.runtime-LWJELYq5.js} +1 -1
- package/dist/{room-info-CAFZ3Z9J.js → room-info-BXQA7y10.js} +12 -3
- package/dist/runtime-api.js +6 -3
- package/dist/{sdk-bUytQHx7.js → sdk-DjaQFCHc.js} +229 -120
- package/dist/{secret-contract-M3hRmGO-.js → secret-contract-CufozuyJ.js} +1 -1
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-BldGYG8g.js → send-ZDLU4JTk.js} +1462 -1196
- package/dist/session-binding-contract-api.js +1 -1
- package/dist/{setup-bootstrap-Deleiibz.js → setup-bootstrap-BaXkhgJg.js} +4 -4
- package/dist/{setup-core-BVfBv2ai.js → setup-core-DQn6b5vi.js} +17 -266
- package/dist/setup-plugin-api.js +1 -44
- package/dist/{setup-surface-BBq3WeqX.js → setup-surface-DlhJdrNI.js} +9 -11
- package/dist/{startup-verification-wm3_i88s.js → startup-verification-Cs08ca8u.js} +3 -3
- package/dist/{storage-BvAkgzvT.js → storage-BsGuHngK.js} +3 -3
- package/dist/{thread-bindings-DGbl3vDW.js → thread-bindings-CcHZP3w2.js} +7 -4
- package/dist/{tool-actions.runtime-uu9blSqO.js → tool-actions.runtime-DmdRL0bN.js} +35 -18
- package/dist/{verification-DYMQ1QpI.js → verification-C7ig-bQE.js} +2 -2
- package/openclaw.plugin.json +54 -1
- package/package.json +4 -4
- package/dist/active-client-DXvz2gCo.js +0 -20
- package/dist/client-Dbso3-0V.js +0 -30
- package/dist/create-client-BmSU-q-D.js +0 -61
- package/dist/credentials-read-DVmFCm7X.js +0 -77
- package/dist/exec-approval-resolver-BCgqRtZS.js +0 -16
- package/dist/preflight-audio.runtime-BZxxQsxY.js +0 -11
- package/dist/probe.runtime-BuieqmS3.js +0 -3
- package/dist/record-shared-CWWx6fvI.js +0 -2
- package/dist/shared-CUMWxcMz.js +0 -673
- package/dist/sync-state-CWbp0QSY.js +0 -12
- package/dist/{runtime-api-D1xI_cvh.js → runtime-api-BGO16Fu8.js} +3 -3
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
import { a as resolveMatrixDefaultOrOnlyAccountId, n as requiresExplicitMatrixDefaultAccount } from "./account-selection-
|
|
2
|
-
import { t as
|
|
1
|
+
import { a as resolveMatrixDefaultOrOnlyAccountId, n as requiresExplicitMatrixDefaultAccount } from "./account-selection-CWuhuFn1.js";
|
|
2
|
+
import { i as normalizeMatrixStoredCredentials, n as isMatrixCredentialRevocation, r as matrixCredentialsStoreKey, t as MATRIX_CREDENTIALS_NAMESPACE } from "./credentials-state-B3cuUFwZ.js";
|
|
3
3
|
import { r as resolveMatrixCredentialsDir } from "./storage-paths-gUmSydsW.js";
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
7
|
-
import { a as readLegacyMatrixSyncCacheState, i as openMatrixSyncCacheStoreOptions, o as writeMatrixSyncCacheStateToStore, r as hasMatrixSyncCacheStateInStore } from "./file-sync-store-DiiFsayX.js";
|
|
4
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DEt4O4Zt.js";
|
|
5
|
+
import { C as readLegacyMatrixRecoveryKeyState, O as writeMatrixIdbSnapshotJsonToStore, T as readMatrixIdbSnapshotJsonFromStore, a as openMatrixStorageMetaStoreOptions, b as openMatrixRecoveryKeyStoreOptions, f as MATRIX_IDB_SNAPSHOT_FILENAME, g as hasMatrixRecoveryKeyStateInStore, h as hasMatrixLegacyCryptoMigrationStateInStore, i as normalizeMatrixStorageMetadata, j as writeMatrixRecoveryKeyStateToStore, k as writeMatrixLegacyCryptoMigrationStateToStore, m as MATRIX_RECOVERY_KEY_FILENAME, n as hasMatrixStorageMetaStateInStore, p as MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME, u as writeMatrixStorageMetaStateToStore, v as openMatrixIdbSnapshotStoreOptions, x as readLegacyMatrixLegacyCryptoMigrationState, y as openMatrixLegacyCryptoMigrationStoreOptions } from "./storage-BsGuHngK.js";
|
|
6
|
+
import { a as readLegacyMatrixSyncCacheState, i as openMatrixSyncCacheStoreOptions, o as writeMatrixSyncCacheStateToStore, r as hasMatrixSyncCacheStateInStore } from "./file-sync-store-DjskBX2o.js";
|
|
8
7
|
import { n as MATRIX_IDB_SNAPSHOT_LOCK_OPTIONS } from "./idb-persistence-lock-DAJ49nZX.js";
|
|
9
|
-
import { r as readLegacyMatrixIdbSnapshotStateUnlocked, t as isValidMatrixIdbSnapshotJson } from "./idb-persistence-
|
|
10
|
-
import { a as resolveMatrixInboundDedupeStateNamespace, n as MATRIX_INBOUND_DEDUPE_TTL_MS, r as buildMatrixInboundDedupeEventKey } from "./inbound-dedupe-CaBLblef.js";
|
|
8
|
+
import { r as readLegacyMatrixIdbSnapshotStateUnlocked, t as isValidMatrixIdbSnapshotJson } from "./idb-persistence-BM0P27Zg.js";
|
|
11
9
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
10
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
13
|
-
import { archiveLegacyStateSource } from "openclaw/plugin-sdk/runtime-doctor";
|
|
14
11
|
import { createHash, randomUUID } from "node:crypto";
|
|
15
12
|
import path from "node:path";
|
|
13
|
+
import { archiveLegacyStateSource } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
16
14
|
import fs from "node:fs";
|
|
17
15
|
import fs$1 from "node:fs/promises";
|
|
18
16
|
import { isDeepStrictEqual } from "node:util";
|
|
19
17
|
import { withFileLock } from "openclaw/plugin-sdk/file-lock";
|
|
20
|
-
import { createPersistentDedupeImportEntry } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
21
18
|
//#region extensions/matrix/src/matrix/crypto-snapshot-doctor.ts
|
|
22
19
|
async function migrateLegacyMatrixIdbSnapshot(params) {
|
|
23
20
|
const snapshotPath = path.join(params.storageRootDir, MATRIX_IDB_SNAPSHOT_FILENAME);
|
|
@@ -101,21 +98,55 @@ async function archiveLegacyMatrixIdbSnapshot(params) {
|
|
|
101
98
|
//#endregion
|
|
102
99
|
//#region extensions/matrix/src/matrix/monitor/inbound-dedupe-migration.ts
|
|
103
100
|
const LEGACY_SQLITE_NAMESPACE = "inbound-dedupe";
|
|
104
|
-
const LEGACY_SQLITE_MAX_ENTRIES = 2e4;
|
|
105
101
|
const LEGACY_MARKERS_NAMESPACE = "inbound-dedupe-migrations";
|
|
106
|
-
const LEGACY_MARKERS_MAX_ENTRIES = 1e3;
|
|
107
102
|
const LEGACY_JSON_VERSION = 1;
|
|
103
|
+
const MATRIX_PLUGIN_ID = "matrix";
|
|
104
|
+
const MIGRATION_COMPLETION_NAMESPACE = "inbound-dedupe-migration-state";
|
|
105
|
+
const MIGRATION_COMPLETION_KEY = "sqlite-json-to-claimable-v1";
|
|
106
|
+
const STATE_DATABASE_RELATIVE_PATH = path.join("state", "openclaw.sqlite");
|
|
108
107
|
const STORAGE_META_FILENAME = "storage-meta.json";
|
|
109
108
|
const MATRIX_LEGACY_INBOUND_DEDUPE_FILENAME = "inbound-dedupe.json";
|
|
109
|
+
function openMatrixInboundDedupeMigrationCompletionStore(context, env) {
|
|
110
|
+
return context.openPluginStateKeyedStore({
|
|
111
|
+
namespace: MIGRATION_COMPLETION_NAMESPACE,
|
|
112
|
+
maxEntries: 4,
|
|
113
|
+
overflowPolicy: "reject-new",
|
|
114
|
+
env
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
async function hasCompletedMatrixInboundDedupeMigration(context, env) {
|
|
118
|
+
const marker = await openMatrixInboundDedupeMigrationCompletionStore(context, env).lookup(MIGRATION_COMPLETION_KEY);
|
|
119
|
+
return isRecord(marker) && marker.version === 1 && typeof marker.completedAt === "number" && Number.isFinite(marker.completedAt) && marker.completedAt >= 0;
|
|
120
|
+
}
|
|
121
|
+
async function recordMatrixInboundDedupeMigrationCompletion(context, env) {
|
|
122
|
+
await openMatrixInboundDedupeMigrationCompletionStore(context, env).register(MIGRATION_COMPLETION_KEY, {
|
|
123
|
+
version: 1,
|
|
124
|
+
completedAt: Date.now()
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Reserves the durable completion row before any legacy source is changed.
|
|
129
|
+
* The invalid timestamp keeps detection active after an interrupted run, while
|
|
130
|
+
* updating this same key after retirement remains possible at plugin capacity.
|
|
131
|
+
*/
|
|
132
|
+
async function reserveMatrixInboundDedupeMigrationCompletion(context, env) {
|
|
133
|
+
await openMatrixInboundDedupeMigrationCompletionStore(context, env).register(MIGRATION_COMPLETION_KEY, {
|
|
134
|
+
version: 1,
|
|
135
|
+
completedAt: -1
|
|
136
|
+
});
|
|
137
|
+
}
|
|
110
138
|
async function collectMatrixInboundDedupeSources(stateDir) {
|
|
111
139
|
const matrixRoot = path.join(stateDir, "matrix");
|
|
112
140
|
const sqliteRoots = /* @__PURE__ */ new Set();
|
|
113
141
|
const jsonRoots = /* @__PURE__ */ new Set();
|
|
114
|
-
|
|
142
|
+
const warnings = [];
|
|
143
|
+
async function visit(dir, allowMissing = false) {
|
|
115
144
|
let entries;
|
|
116
145
|
try {
|
|
117
146
|
entries = await fs$1.readdir(dir, { withFileTypes: true });
|
|
118
|
-
} catch {
|
|
147
|
+
} catch (err) {
|
|
148
|
+
if (allowMissing && err.code === "ENOENT") return;
|
|
149
|
+
warnings.push(`Failed scanning Matrix inbound dedupe sources under ${dir}: ${String(err)}`);
|
|
119
150
|
return;
|
|
120
151
|
}
|
|
121
152
|
for (const entry of entries) {
|
|
@@ -128,40 +159,41 @@ async function collectMatrixInboundDedupeSources(stateDir) {
|
|
|
128
159
|
if (entry.isDirectory()) await visit(entryPath);
|
|
129
160
|
}
|
|
130
161
|
}
|
|
131
|
-
await visit(matrixRoot);
|
|
162
|
+
await visit(matrixRoot, true);
|
|
132
163
|
const matrixRootResolved = path.resolve(matrixRoot);
|
|
133
164
|
const isAccountRoot = (root) => path.resolve(root) !== matrixRootResolved;
|
|
134
|
-
|
|
165
|
+
const roots = {
|
|
135
166
|
sqliteRoots: [...sqliteRoots].filter(isAccountRoot).toSorted(),
|
|
136
167
|
jsonRoots: [...jsonRoots].filter(isAccountRoot).toSorted()
|
|
137
168
|
};
|
|
169
|
+
return warnings.length === 0 ? {
|
|
170
|
+
status: "complete",
|
|
171
|
+
...roots
|
|
172
|
+
} : {
|
|
173
|
+
status: "incomplete",
|
|
174
|
+
...roots,
|
|
175
|
+
warnings
|
|
176
|
+
};
|
|
138
177
|
}
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
});
|
|
178
|
+
function selectLegacySqliteRows(db) {
|
|
179
|
+
if (!db.prepare(`SELECT 1 AS present
|
|
180
|
+
FROM sqlite_master
|
|
181
|
+
WHERE type = 'table' AND name = 'plugin_state_entries'`).get()) return [];
|
|
182
|
+
return db.prepare(`SELECT namespace, entry_key, value_json, expires_at
|
|
183
|
+
FROM plugin_state_entries
|
|
184
|
+
WHERE plugin_id = ? AND namespace IN (?, ?)
|
|
185
|
+
ORDER BY namespace ASC, created_at ASC, entry_key ASC`).all(MATRIX_PLUGIN_ID, LEGACY_SQLITE_NAMESPACE, LEGACY_MARKERS_NAMESPACE);
|
|
148
186
|
}
|
|
149
|
-
function
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
maxEntries: LEGACY_MARKERS_MAX_ENTRIES,
|
|
153
|
-
env: {
|
|
154
|
-
...io.env,
|
|
155
|
-
OPENCLAW_STATE_DIR: storageRootDir
|
|
156
|
-
}
|
|
157
|
-
});
|
|
187
|
+
function isLegacySqliteRowExpired(row, now) {
|
|
188
|
+
if (typeof row.expires_at === "bigint") return row.expires_at <= BigInt(now);
|
|
189
|
+
return row.expires_at !== null && row.expires_at <= now;
|
|
158
190
|
}
|
|
159
191
|
function normalizeLegacyTimestamp(raw) {
|
|
160
192
|
if (typeof raw !== "number" || !Number.isFinite(raw)) return null;
|
|
161
193
|
return Math.max(0, Math.floor(raw));
|
|
162
194
|
}
|
|
163
195
|
function parseLegacySqliteRow(row) {
|
|
164
|
-
const value = isRecord
|
|
196
|
+
const value = isRecord(row.value) ? row.value : {};
|
|
165
197
|
const roomId = typeof value.roomId === "string" ? value.roomId.trim() : "";
|
|
166
198
|
const eventId = typeof value.eventId === "string" ? value.eventId.trim() : "";
|
|
167
199
|
const ts = normalizeLegacyTimestamp(value.ts);
|
|
@@ -177,24 +209,63 @@ function parseLegacySqliteRow(row) {
|
|
|
177
209
|
ts
|
|
178
210
|
};
|
|
179
211
|
}
|
|
180
|
-
/**
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Reads one storage root's legacy SQLite dedupe rows without opening it through
|
|
214
|
+
* the current state runtime. Historical per-account databases can predate the
|
|
215
|
+
* current core schema, and detection must not upgrade them merely to inspect
|
|
216
|
+
* these retired plugin-state namespaces.
|
|
217
|
+
*/
|
|
218
|
+
async function readLegacyInboundDedupeSqliteSource(storageRootDir) {
|
|
219
|
+
const { openNodeSqliteDatabase } = await import("openclaw/plugin-sdk/sqlite-runtime");
|
|
220
|
+
const db = openNodeSqliteDatabase(path.join(storageRootDir, STATE_DATABASE_RELATIVE_PATH), { readOnly: true });
|
|
221
|
+
try {
|
|
222
|
+
const rows = selectLegacySqliteRows(db);
|
|
223
|
+
const markers = [];
|
|
224
|
+
const now = Date.now();
|
|
225
|
+
for (const row of rows) {
|
|
226
|
+
if (isLegacySqliteRowExpired(row, now)) continue;
|
|
227
|
+
const value = JSON.parse(row.value_json);
|
|
228
|
+
if (row.namespace !== LEGACY_SQLITE_NAMESPACE) continue;
|
|
229
|
+
const marker = parseLegacySqliteRow({
|
|
230
|
+
key: row.entry_key,
|
|
231
|
+
value
|
|
232
|
+
});
|
|
233
|
+
if (marker) markers.push(marker);
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
markers,
|
|
237
|
+
legacyRowCount: rows.length
|
|
238
|
+
};
|
|
239
|
+
} finally {
|
|
240
|
+
db.close();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/** Deletes only the two retired Matrix namespaces after a successful import. */
|
|
244
|
+
async function retireLegacyInboundDedupeSqliteRows(storageRootDir) {
|
|
245
|
+
const { openNodeSqliteDatabase, runSqliteImmediateTransactionSync } = await import("openclaw/plugin-sdk/sqlite-runtime");
|
|
246
|
+
const db = openNodeSqliteDatabase(path.join(storageRootDir, STATE_DATABASE_RELATIVE_PATH));
|
|
247
|
+
try {
|
|
248
|
+
if (selectLegacySqliteRows(db).length === 0) return;
|
|
249
|
+
runSqliteImmediateTransactionSync(db, () => {
|
|
250
|
+
if (selectLegacySqliteRows(db).length === 0) return;
|
|
251
|
+
db.prepare(`DELETE FROM plugin_state_entries
|
|
252
|
+
WHERE plugin_id = ? AND namespace IN (?, ?)`).run(MATRIX_PLUGIN_ID, LEGACY_SQLITE_NAMESPACE, LEGACY_MARKERS_NAMESPACE);
|
|
253
|
+
});
|
|
254
|
+
} finally {
|
|
255
|
+
db.close();
|
|
188
256
|
}
|
|
189
|
-
return {
|
|
190
|
-
markers,
|
|
191
|
-
legacyRowCount: rows.length + markerRows.length
|
|
192
|
-
};
|
|
193
257
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
await
|
|
197
|
-
|
|
258
|
+
async function verifyMatrixInboundDedupeSourcesRetired(stateDir) {
|
|
259
|
+
const warnings = [];
|
|
260
|
+
const remaining = await collectMatrixInboundDedupeSources(stateDir);
|
|
261
|
+
if (remaining.status === "incomplete") warnings.push(...remaining.warnings);
|
|
262
|
+
for (const storageRootDir of remaining.sqliteRoots) try {
|
|
263
|
+
if ((await readLegacyInboundDedupeSqliteSource(storageRootDir)).legacyRowCount > 0) warnings.push(`Matrix inbound dedupe rows remain after retirement for ${storageRootDir}`);
|
|
264
|
+
} catch (err) {
|
|
265
|
+
warnings.push(`Failed verifying retired Matrix inbound dedupe rows for ${storageRootDir}: ${String(err)}`);
|
|
266
|
+
}
|
|
267
|
+
for (const storageRootDir of remaining.jsonRoots) warnings.push(`Matrix inbound dedupe JSON remains after retirement for ${storageRootDir}`);
|
|
268
|
+
return warnings;
|
|
198
269
|
}
|
|
199
270
|
async function resolveJsonRootAccountId(storageRootDir) {
|
|
200
271
|
for (const filename of [STORAGE_META_FILENAME, `${STORAGE_META_FILENAME}.migrated`]) try {
|
|
@@ -217,11 +288,11 @@ async function readLegacyInboundDedupeJsonSource(storageRootDir) {
|
|
|
217
288
|
} catch {
|
|
218
289
|
return null;
|
|
219
290
|
}
|
|
220
|
-
if (!isRecord
|
|
291
|
+
if (!isRecord(parsed) || parsed.version !== LEGACY_JSON_VERSION || !Array.isArray(parsed.entries)) return null;
|
|
221
292
|
const accountId = await resolveJsonRootAccountId(storageRootDir);
|
|
222
293
|
const markers = [];
|
|
223
294
|
for (const entry of parsed.entries) {
|
|
224
|
-
if (!isRecord
|
|
295
|
+
if (!isRecord(entry) || typeof entry.key !== "string") continue;
|
|
225
296
|
const separator = entry.key.indexOf("|");
|
|
226
297
|
if (separator <= 0) continue;
|
|
227
298
|
const roomId = entry.key.slice(0, separator).trim();
|
|
@@ -239,14 +310,16 @@ async function readLegacyInboundDedupeJsonSource(storageRootDir) {
|
|
|
239
310
|
}
|
|
240
311
|
/**
|
|
241
312
|
* Imports the globally newest legacy markers into the claimable-dedupe store.
|
|
242
|
-
* Never exceeds capacity
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
313
|
+
* Never exceeds capacity, never replaces a post-upgrade destination row, and
|
|
314
|
+
* preserves source timestamps because eviction is ordered by row creation
|
|
315
|
+
* time. Throws on import or verification errors so the caller keeps the legacy
|
|
316
|
+
* sources for the next doctor attempt.
|
|
246
317
|
*/
|
|
247
318
|
async function importNewestInboundDedupeMarkers(params) {
|
|
319
|
+
const { createPersistentDedupeImportEntry } = await import("openclaw/plugin-sdk/persistent-dedupe");
|
|
320
|
+
const { buildMatrixInboundDedupeEventKey, MATRIX_INBOUND_DEDUPE_STATE_MAX_ENTRIES, MATRIX_INBOUND_DEDUPE_TTL_MS, resolveMatrixInboundDedupeStateNamespace } = await import("./inbound-dedupe-RvSLqdsz.js");
|
|
248
321
|
const now = params.now ?? Date.now();
|
|
249
|
-
const stateMaxEntries = params.stateMaxEntries ??
|
|
322
|
+
const stateMaxEntries = params.stateMaxEntries ?? MATRIX_INBOUND_DEDUPE_STATE_MAX_ENTRIES;
|
|
250
323
|
const newestByKey = /* @__PURE__ */ new Map();
|
|
251
324
|
for (const marker of params.markers) {
|
|
252
325
|
const key = buildMatrixInboundDedupeEventKey(marker);
|
|
@@ -264,24 +337,47 @@ async function importNewestInboundDedupeMarkers(params) {
|
|
|
264
337
|
defaultTtlMs: MATRIX_INBOUND_DEDUPE_TTL_MS,
|
|
265
338
|
env: params.io.env
|
|
266
339
|
});
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (capacity <= 0) break;
|
|
340
|
+
const existingEntries = await store.entries();
|
|
341
|
+
const existingKeys = new Set(existingEntries.map((entry) => entry.key));
|
|
342
|
+
const missingEntries = markers.flatMap((marker) => {
|
|
271
343
|
const remainingTtlMs = MATRIX_INBOUND_DEDUPE_TTL_MS - (now - marker.ts);
|
|
272
|
-
if (remainingTtlMs <= 0)
|
|
344
|
+
if (remainingTtlMs <= 0) return [];
|
|
273
345
|
const entry = createPersistentDedupeImportEntry({
|
|
274
346
|
key: marker.key,
|
|
275
347
|
seenAt: marker.ts,
|
|
276
348
|
ttlMs: Math.max(1, Math.floor(remainingTtlMs))
|
|
277
349
|
});
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
350
|
+
return existingKeys.has(entry.key) ? [] : [{
|
|
351
|
+
marker,
|
|
352
|
+
entry
|
|
353
|
+
}];
|
|
354
|
+
});
|
|
355
|
+
const namespaceCapacity = Math.max(0, stateMaxEntries - existingEntries.length);
|
|
356
|
+
const pluginCapacity = missingEntries.length > 0 ? params.io.context.getPluginStateCapacity?.() : void 0;
|
|
357
|
+
if (missingEntries.length > 0 && !pluginCapacity) throw new Error("plugin-wide Matrix inbound dedupe import capacity is unavailable");
|
|
358
|
+
const pluginRemainingCapacity = pluginCapacity ? Math.max(0, pluginCapacity.maxEntries - pluginCapacity.liveEntries) : namespaceCapacity;
|
|
359
|
+
const capacity = Math.min(namespaceCapacity, pluginRemainingCapacity);
|
|
360
|
+
const selectedEntries = missingEntries.slice(0, capacity);
|
|
361
|
+
if (selectedEntries.length > 0) {
|
|
362
|
+
const importEntries = params.io.context.importPluginStateEntries;
|
|
363
|
+
if (!importEntries) throw new Error("retention-aware Matrix inbound dedupe import is unavailable");
|
|
364
|
+
importEntries({
|
|
365
|
+
namespace: resolveMatrixInboundDedupeStateNamespace(),
|
|
366
|
+
maxEntries: stateMaxEntries,
|
|
367
|
+
defaultTtlMs: MATRIX_INBOUND_DEDUPE_TTL_MS,
|
|
368
|
+
env: params.io.env
|
|
369
|
+
}, selectedEntries.map(({ marker, entry }) => ({
|
|
370
|
+
key: entry.key,
|
|
371
|
+
value: entry.value,
|
|
372
|
+
createdAt: marker.ts,
|
|
373
|
+
...entry.ttlMs != null ? { ttlMs: entry.ttlMs } : {}
|
|
374
|
+
})));
|
|
375
|
+
const importedKeys = new Set((await store.entries()).map((entry) => entry.key));
|
|
376
|
+
const missingKey = selectedEntries.find(({ entry }) => !importedKeys.has(entry.key))?.entry.key;
|
|
377
|
+
if (missingKey) throw new Error(`retention-aware Matrix inbound dedupe import did not persist ${missingKey}`);
|
|
282
378
|
}
|
|
283
379
|
return {
|
|
284
|
-
imported,
|
|
380
|
+
imported: selectedEntries.length,
|
|
285
381
|
total: markers.length
|
|
286
382
|
};
|
|
287
383
|
}
|
|
@@ -444,22 +540,7 @@ const stateMigrations = [
|
|
|
444
540
|
id: "matrix-inbound-dedupe-to-claimable-dedupe",
|
|
445
541
|
label: "Matrix inbound dedupe markers",
|
|
446
542
|
async detectLegacyState(params) {
|
|
447
|
-
|
|
448
|
-
context: params.context,
|
|
449
|
-
env: params.env
|
|
450
|
-
};
|
|
451
|
-
const preview = [];
|
|
452
|
-
const sources = await collectMatrixInboundDedupeSources(params.stateDir);
|
|
453
|
-
for (const storageRootDir of sources.sqliteRoots) {
|
|
454
|
-
try {
|
|
455
|
-
if ((await readLegacyInboundDedupeSqliteSource(io, storageRootDir)).legacyRowCount === 0) continue;
|
|
456
|
-
} catch {
|
|
457
|
-
continue;
|
|
458
|
-
}
|
|
459
|
-
preview.push(`Matrix inbound dedupe rows can migrate to the claimable dedupe store: ${storageRootDir}`);
|
|
460
|
-
}
|
|
461
|
-
for (const storageRootDir of sources.jsonRoots) preview.push(`Matrix inbound dedupe JSON can migrate to the claimable dedupe store: ${path.join(storageRootDir, MATRIX_LEGACY_INBOUND_DEDUPE_FILENAME)}`);
|
|
462
|
-
return preview.length > 0 ? { preview } : null;
|
|
543
|
+
return await hasCompletedMatrixInboundDedupeMigration(params.context, params.env) ? null : { preview: ["Matrix inbound dedupe legacy sources need a one-time migration scan"] };
|
|
463
544
|
},
|
|
464
545
|
async migrateLegacyState(params) {
|
|
465
546
|
const io = {
|
|
@@ -468,11 +549,38 @@ const stateMigrations = [
|
|
|
468
549
|
};
|
|
469
550
|
const changes = [];
|
|
470
551
|
const warnings = [];
|
|
552
|
+
if (await hasCompletedMatrixInboundDedupeMigration(params.context, params.env)) return {
|
|
553
|
+
changes,
|
|
554
|
+
warnings
|
|
555
|
+
};
|
|
556
|
+
try {
|
|
557
|
+
await reserveMatrixInboundDedupeMigrationCompletion(params.context, params.env);
|
|
558
|
+
} catch (err) {
|
|
559
|
+
warnings.push(`Failed reserving Matrix inbound dedupe migration completion: ${String(err)}; left legacy sources in place`);
|
|
560
|
+
return {
|
|
561
|
+
changes,
|
|
562
|
+
warnings
|
|
563
|
+
};
|
|
564
|
+
}
|
|
471
565
|
const sources = await collectMatrixInboundDedupeSources(params.stateDir);
|
|
566
|
+
if (sources.status === "incomplete") warnings.push(...sources.warnings);
|
|
567
|
+
const recordCompletionIfClean = async (verifyRetirement = false) => {
|
|
568
|
+
if (warnings.length > 0) return;
|
|
569
|
+
if (verifyRetirement) {
|
|
570
|
+
warnings.push(...await verifyMatrixInboundDedupeSourcesRetired(params.stateDir));
|
|
571
|
+
if (warnings.length > 0) return;
|
|
572
|
+
}
|
|
573
|
+
try {
|
|
574
|
+
await recordMatrixInboundDedupeMigrationCompletion(params.context, params.env);
|
|
575
|
+
if (sources.sqliteRoots.length + sources.jsonRoots.length > 0) changes.push(`Recorded Matrix inbound dedupe migration completion (${sources.sqliteRoots.length} SQLite roots, ${sources.jsonRoots.length} JSON roots scanned)`);
|
|
576
|
+
} catch (err) {
|
|
577
|
+
warnings.push(`Failed recording Matrix inbound dedupe migration completion: ${String(err)}`);
|
|
578
|
+
}
|
|
579
|
+
};
|
|
472
580
|
const gathered = [];
|
|
473
581
|
const sqliteRootsToRetire = [];
|
|
474
582
|
for (const storageRootDir of sources.sqliteRoots) try {
|
|
475
|
-
const source = await readLegacyInboundDedupeSqliteSource(
|
|
583
|
+
const source = await readLegacyInboundDedupeSqliteSource(storageRootDir);
|
|
476
584
|
if (source.legacyRowCount === 0) continue;
|
|
477
585
|
gathered.push(...source.markers);
|
|
478
586
|
sqliteRootsToRetire.push(storageRootDir);
|
|
@@ -488,10 +596,13 @@ const stateMigrations = [
|
|
|
488
596
|
} catch (err) {
|
|
489
597
|
warnings.push(`Failed reading Matrix inbound dedupe JSON for ${storageRootDir}: ${String(err)}; left legacy file in place`);
|
|
490
598
|
}
|
|
491
|
-
if (sqliteRootsToRetire.length + jsonRootsToRetire.length === 0)
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
599
|
+
if (sqliteRootsToRetire.length + jsonRootsToRetire.length === 0) {
|
|
600
|
+
await recordCompletionIfClean();
|
|
601
|
+
return {
|
|
602
|
+
changes,
|
|
603
|
+
warnings
|
|
604
|
+
};
|
|
605
|
+
}
|
|
495
606
|
try {
|
|
496
607
|
const result = await importNewestInboundDedupeMarkers({
|
|
497
608
|
io,
|
|
@@ -506,7 +617,7 @@ const stateMigrations = [
|
|
|
506
617
|
};
|
|
507
618
|
}
|
|
508
619
|
for (const storageRootDir of sqliteRootsToRetire) try {
|
|
509
|
-
await retireLegacyInboundDedupeSqliteRows(
|
|
620
|
+
await retireLegacyInboundDedupeSqliteRows(storageRootDir);
|
|
510
621
|
changes.push(`Retired Matrix inbound dedupe rows for ${storageRootDir}`);
|
|
511
622
|
} catch (err) {
|
|
512
623
|
warnings.push(`Failed retiring Matrix inbound dedupe rows for ${storageRootDir}: ${String(err)}`);
|
|
@@ -518,6 +629,7 @@ const stateMigrations = [
|
|
|
518
629
|
changes,
|
|
519
630
|
warnings
|
|
520
631
|
});
|
|
632
|
+
await recordCompletionIfClean(true);
|
|
521
633
|
return {
|
|
522
634
|
changes,
|
|
523
635
|
warnings
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { E as MsgType, a as sendSingleTextMessageMatrix, l as prepareMatrixSingleText, t as editMessageMatrix } from "./send-ZDLU4JTk.js";
|
|
2
|
+
import { createFinalizableDraftStreamControlsForState } from "openclaw/plugin-sdk/channel-outbound";
|
|
3
3
|
//#region extensions/matrix/src/matrix/draft-stream.ts
|
|
4
4
|
const DEFAULT_THROTTLE_MS = 1e3;
|
|
5
5
|
function resolveDraftPreviewOptions(mode) {
|
|
@@ -19,22 +19,26 @@ function createMatrixDraftStream(params) {
|
|
|
19
19
|
let currentEventId;
|
|
20
20
|
let lastSentText = "";
|
|
21
21
|
let lastSentContent = "";
|
|
22
|
-
|
|
22
|
+
const streamState = {
|
|
23
|
+
stopped: false,
|
|
24
|
+
final: false
|
|
25
|
+
};
|
|
23
26
|
let sendFailed = false;
|
|
24
27
|
let finalizeInPlaceBlocked = false;
|
|
25
28
|
let liveFinalized = false;
|
|
26
29
|
let replyToId = params.replyToId;
|
|
27
30
|
const sendOrEdit = async (text) => {
|
|
28
31
|
const trimmed = text.trimEnd();
|
|
29
|
-
if (!trimmed) return false;
|
|
32
|
+
if (!trimmed.trim()) return false;
|
|
30
33
|
const preparedText = prepareMatrixSingleText(trimmed, {
|
|
31
34
|
cfg,
|
|
32
|
-
accountId
|
|
35
|
+
accountId,
|
|
36
|
+
preserveWhitespace: true
|
|
33
37
|
});
|
|
34
38
|
if (!preparedText.fitsInSingleEvent) {
|
|
35
39
|
finalizeInPlaceBlocked = true;
|
|
36
40
|
if (!currentEventId) sendFailed = true;
|
|
37
|
-
stopped = true;
|
|
41
|
+
streamState.stopped = true;
|
|
38
42
|
log?.(`draft-stream: preview exceeded single-event limit (${preparedText.convertedText.length} > ${preparedText.singleEventLimit})`);
|
|
39
43
|
return false;
|
|
40
44
|
}
|
|
@@ -73,13 +77,13 @@ function createMatrixDraftStream(params) {
|
|
|
73
77
|
log?.(`draft-stream: send/edit failed: ${String(err)}`);
|
|
74
78
|
if (err instanceof Error && err.message.startsWith("Matrix single-message text exceeds limit")) finalizeInPlaceBlocked = true;
|
|
75
79
|
if (!currentEventId) sendFailed = true;
|
|
76
|
-
stopped = true;
|
|
80
|
+
streamState.stopped = true;
|
|
77
81
|
return false;
|
|
78
82
|
}
|
|
79
83
|
};
|
|
80
|
-
const loop =
|
|
84
|
+
const { loop, update, stop: stopDraft, discardPending } = createFinalizableDraftStreamControlsForState({
|
|
81
85
|
throttleMs: DEFAULT_THROTTLE_MS,
|
|
82
|
-
|
|
86
|
+
state: streamState,
|
|
83
87
|
sendOrEditStreamMessage: sendOrEdit
|
|
84
88
|
});
|
|
85
89
|
log?.(`draft-stream: ready (throttleMs=${DEFAULT_THROTTLE_MS})`);
|
|
@@ -107,21 +111,16 @@ function createMatrixDraftStream(params) {
|
|
|
107
111
|
return true;
|
|
108
112
|
};
|
|
109
113
|
const stop = async () => {
|
|
110
|
-
await
|
|
111
|
-
stopped = true;
|
|
114
|
+
await stopDraft();
|
|
112
115
|
return currentEventId;
|
|
113
116
|
};
|
|
114
|
-
const discardPending = async () => {
|
|
115
|
-
stopped = true;
|
|
116
|
-
loop.stop();
|
|
117
|
-
await loop.waitForInFlight();
|
|
118
|
-
};
|
|
119
117
|
const reset = () => {
|
|
120
118
|
replyToId = params.preserveReplyId ? params.replyToId : void 0;
|
|
121
119
|
currentEventId = void 0;
|
|
122
120
|
lastSentText = "";
|
|
123
121
|
lastSentContent = "";
|
|
124
|
-
stopped = false;
|
|
122
|
+
streamState.stopped = false;
|
|
123
|
+
streamState.final = false;
|
|
125
124
|
sendFailed = false;
|
|
126
125
|
finalizeInPlaceBlocked = false;
|
|
127
126
|
liveFinalized = false;
|
|
@@ -129,10 +128,7 @@ function createMatrixDraftStream(params) {
|
|
|
129
128
|
loop.resetThrottleWindow();
|
|
130
129
|
};
|
|
131
130
|
return {
|
|
132
|
-
update
|
|
133
|
-
if (stopped) return;
|
|
134
|
-
loop.update(text);
|
|
135
|
-
},
|
|
131
|
+
update,
|
|
136
132
|
flush: loop.flush,
|
|
137
133
|
stop,
|
|
138
134
|
discardPending,
|
|
@@ -140,9 +136,10 @@ function createMatrixDraftStream(params) {
|
|
|
140
136
|
reset,
|
|
141
137
|
eventId: () => currentEventId,
|
|
142
138
|
content: () => lastSentContent || void 0,
|
|
143
|
-
matchesPreparedText: (text) => prepareMatrixSingleText(text, {
|
|
139
|
+
matchesPreparedText: (text) => prepareMatrixSingleText(text.trimEnd(), {
|
|
144
140
|
cfg,
|
|
145
|
-
accountId
|
|
141
|
+
accountId,
|
|
142
|
+
preserveWhitespace: true
|
|
146
143
|
}).trimmedText === lastSentText,
|
|
147
144
|
mustDeliverFinalNormally: () => sendFailed || finalizeInPlaceBlocked
|
|
148
145
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as resolveMatrixDefaultOrOnlyAccountId } from "./account-selection-
|
|
1
|
+
import { a as resolveMatrixDefaultOrOnlyAccountId } from "./account-selection-CWuhuFn1.js";
|
|
2
2
|
import { t as resolveMatrixConfigFieldPath } from "./config-paths-CnREYb1Y.js";
|
|
3
3
|
import { normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-id";
|
|
4
4
|
//#region extensions/matrix/src/matrix/encryption-guidance.ts
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { t as getMatrixScopedEnvVarNames } from "./env-vars-
|
|
1
|
+
import { t as getMatrixScopedEnvVarNames } from "./env-vars-dGqak9dN.js";
|
|
2
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
3
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
3
4
|
//#region extensions/matrix/src/matrix/client/env-auth.ts
|
|
4
5
|
function cleanEnv(value) {
|
|
5
|
-
return
|
|
6
|
+
return normalizeOptionalString(value) ?? "";
|
|
6
7
|
}
|
|
7
8
|
function resolveGlobalMatrixEnvConfig(env) {
|
|
8
9
|
return {
|
|
@@ -60,4 +61,4 @@ function resolveMatrixEnvAuthReadiness(accountId, env = process.env) {
|
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
//#endregion
|
|
63
|
-
export {
|
|
64
|
+
export { resolveMatrixEnvAuthReadiness as n, resolveScopedMatrixEnvConfig as r, resolveGlobalMatrixEnvConfig as t };
|
|
@@ -31,7 +31,7 @@ function decodeMatrixEnvAccountToken(token) {
|
|
|
31
31
|
if (hexEscape) {
|
|
32
32
|
const hex = hexEscape[1];
|
|
33
33
|
const codePoint = hex ? Number.parseInt(hex, 16) : NaN;
|
|
34
|
-
if (!Number.
|
|
34
|
+
if (!Number.isInteger(codePoint) || codePoint > 1114111) return;
|
|
35
35
|
decoded += String.fromCodePoint(codePoint);
|
|
36
36
|
index += hexEscape[0].length;
|
|
37
37
|
continue;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
2
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
3
3
|
//#region extensions/matrix/src/matrix/errors.ts
|
|
4
|
-
function formatMatrixErrorMessage(err) {
|
|
5
|
-
return formatErrorMessage(err);
|
|
6
|
-
}
|
|
7
4
|
function formatMatrixErrorReason(err) {
|
|
8
|
-
return normalizeLowercaseStringOrEmpty(
|
|
5
|
+
return normalizeLowercaseStringOrEmpty(formatErrorMessage(err));
|
|
9
6
|
}
|
|
10
7
|
function isMatrixNotFoundError(err) {
|
|
11
8
|
const errObj = err;
|
|
@@ -14,4 +11,4 @@ function isMatrixNotFoundError(err) {
|
|
|
14
11
|
return message.includes("m_not_found") || message.includes("[404]") || message.includes("not found");
|
|
15
12
|
}
|
|
16
13
|
//#endregion
|
|
17
|
-
export {
|
|
14
|
+
export { isMatrixNotFoundError as n, formatMatrixErrorReason as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { t as isRecord } from "./record-shared-CWWx6fvI.js";
|
|
3
2
|
import { t as getMatrixRuntime } from "./runtime-6S3DNFNv.js";
|
|
4
|
-
import { M as resolveMatrixSqliteStateEnv, t as claimCurrentTokenStorageState } from "./storage-
|
|
5
|
-
import { n as LogService } from "./logger-
|
|
3
|
+
import { M as resolveMatrixSqliteStateEnv, t as claimCurrentTokenStorageState } from "./storage-BsGuHngK.js";
|
|
4
|
+
import { n as LogService } from "./logger-B_71hN6W.js";
|
|
5
|
+
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
import fs from "node:fs/promises";
|
|
@@ -108,6 +108,7 @@ var SqliteBackedMatrixSyncStore = class extends MemoryStore {
|
|
|
108
108
|
this.savedSync = null;
|
|
109
109
|
this.cleanShutdown = false;
|
|
110
110
|
this.dirty = false;
|
|
111
|
+
this.frozen = false;
|
|
111
112
|
this.persistTimer = null;
|
|
112
113
|
this.persistPromise = null;
|
|
113
114
|
this.stateKey = SYNC_CACHE_STATE_KEY;
|
|
@@ -154,6 +155,7 @@ var SqliteBackedMatrixSyncStore = class extends MemoryStore {
|
|
|
154
155
|
return Promise.resolve(this.savedSync?.nextBatch ?? null);
|
|
155
156
|
}
|
|
156
157
|
setSyncData(syncData) {
|
|
158
|
+
if (this.frozen) return Promise.resolve();
|
|
157
159
|
this.accumulator.accumulate(syncData);
|
|
158
160
|
this.savedSync = this.accumulator.getJSON();
|
|
159
161
|
this.markDirtyAndSchedulePersist();
|
|
@@ -163,6 +165,7 @@ var SqliteBackedMatrixSyncStore = class extends MemoryStore {
|
|
|
163
165
|
return Promise.resolve(this.savedClientOptions ? cloneJson(this.savedClientOptions) : void 0);
|
|
164
166
|
}
|
|
165
167
|
storeClientOptions(options) {
|
|
168
|
+
if (this.frozen) return Promise.resolve();
|
|
166
169
|
this.savedClientOptions = cloneJson(options);
|
|
167
170
|
super.storeClientOptions(options);
|
|
168
171
|
this.markDirtyAndSchedulePersist();
|
|
@@ -195,6 +198,23 @@ var SqliteBackedMatrixSyncStore = class extends MemoryStore {
|
|
|
195
198
|
this.cleanShutdown = true;
|
|
196
199
|
this.dirty = true;
|
|
197
200
|
}
|
|
201
|
+
async freezeSyncCursorPersistence() {
|
|
202
|
+
this.frozen = true;
|
|
203
|
+
if (this.persistTimer) {
|
|
204
|
+
clearTimeout(this.persistTimer);
|
|
205
|
+
this.persistTimer = null;
|
|
206
|
+
}
|
|
207
|
+
await this.persistPromise;
|
|
208
|
+
}
|
|
209
|
+
discardPendingSyncCursorPersistence() {
|
|
210
|
+
this.frozen = true;
|
|
211
|
+
if (this.persistTimer) {
|
|
212
|
+
clearTimeout(this.persistTimer);
|
|
213
|
+
this.persistTimer = null;
|
|
214
|
+
}
|
|
215
|
+
this.cleanShutdown = false;
|
|
216
|
+
this.dirty = false;
|
|
217
|
+
}
|
|
198
218
|
async flush() {
|
|
199
219
|
if (this.persistTimer) {
|
|
200
220
|
clearTimeout(this.persistTimer);
|
|
@@ -208,6 +228,7 @@ var SqliteBackedMatrixSyncStore = class extends MemoryStore {
|
|
|
208
228
|
}
|
|
209
229
|
}
|
|
210
230
|
markDirtyAndSchedulePersist() {
|
|
231
|
+
if (this.frozen) return;
|
|
211
232
|
this.cleanShutdown = false;
|
|
212
233
|
this.dirty = true;
|
|
213
234
|
if (this.persistTimer) return;
|