@senguoyun/dsh-arkme 0.1.59 → 0.1.60
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/docs/dsh-input-system-topic.md +7 -3
- package/lib/client.js +3355 -1674
- package/lib/client.js.map +1 -1
- package/lib/harness-sidebar-client.js +214 -23
- package/lib/index.js +4 -1
- package/lib/persistent-extension.js +1 -1
- package/lib/{persistent-runtime-ByM3JB3z.js → persistent-runtime-DqPfc6RO.js} +396 -59
- package/lib/types/arkme-service.d.ts +3 -0
- package/lib/types/arkme-service.d.ts.map +1 -1
- package/lib/types/client/ArkmeCalendarSurface.d.ts +22 -1
- package/lib/types/client/ArkmeCalendarSurface.d.ts.map +1 -1
- package/lib/types/client/ArkmeDshMenu.d.ts +38 -0
- package/lib/types/client/ArkmeDshMenu.d.ts.map +1 -0
- package/lib/types/client/ArkmeGroupChatControls.d.ts +4 -0
- package/lib/types/client/ArkmeGroupChatControls.d.ts.map +1 -1
- package/lib/types/client/ArkmeProductNavigation.d.ts.map +1 -1
- package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
- package/lib/types/client/ArkmeSourceBreadcrumb.d.ts +6 -2
- package/lib/types/client/ArkmeSourceBreadcrumb.d.ts.map +1 -1
- package/lib/types/client/ArkmeTopicDirectoryPopover.d.ts +4 -2
- package/lib/types/client/ArkmeTopicDirectoryPopover.d.ts.map +1 -1
- package/lib/types/client/ArkmeVirtualWorkspace.d.ts.map +1 -1
- package/lib/types/client/DeepSeekHarnessSurface.d.ts.map +1 -1
- package/lib/types/client/PrivateChatActions.d.ts +15 -3
- package/lib/types/client/PrivateChatActions.d.ts.map +1 -1
- package/lib/types/client/calendar-invalidation-store.d.ts +10 -1
- package/lib/types/client/calendar-invalidation-store.d.ts.map +1 -1
- package/lib/types/client/calendar-month-cache.d.ts +37 -0
- package/lib/types/client/calendar-month-cache.d.ts.map +1 -0
- package/lib/types/client/conversation-export.d.ts +18 -0
- package/lib/types/client/conversation-export.d.ts.map +1 -0
- package/lib/types/client/conversation-menu-layer.d.ts +27 -0
- package/lib/types/client/conversation-menu-layer.d.ts.map +1 -0
- package/lib/types/client/conversation-menu-scrollbars.d.ts +3 -0
- package/lib/types/client/conversation-menu-scrollbars.d.ts.map +1 -0
- package/lib/types/client/conversation-selector-style.d.ts +34 -0
- package/lib/types/client/conversation-selector-style.d.ts.map +1 -0
- package/lib/types/client/harness-session-dropdown.d.ts.map +1 -1
- package/lib/types/client/harness-session-hover.d.ts +1 -1
- package/lib/types/client/harness-session-hover.d.ts.map +1 -1
- package/lib/types/client/harness-session-menu-bridge.d.ts +2 -0
- package/lib/types/client/harness-session-menu-bridge.d.ts.map +1 -1
- package/lib/types/client/harness-surface-viewport.d.ts +7 -0
- package/lib/types/client/harness-surface-viewport.d.ts.map +1 -0
- package/lib/types/client/navigation-cache.d.ts +6 -1
- package/lib/types/client/navigation-cache.d.ts.map +1 -1
- package/lib/types/client/provider-instance-runtime.d.ts.map +1 -1
- package/lib/types/client/realtime-client-events.d.ts.map +1 -1
- package/lib/types/client/self-topic-directory-cache.d.ts +42 -0
- package/lib/types/client/self-topic-directory-cache.d.ts.map +1 -0
- package/lib/types/client/self-topic-expansion-preference.d.ts +23 -0
- package/lib/types/client/self-topic-expansion-preference.d.ts.map +1 -0
- package/lib/types/client/self-topic-menu-bridge.d.ts +20 -0
- package/lib/types/client/self-topic-menu-bridge.d.ts.map +1 -0
- package/lib/types/client/self-topic-menu-hover.d.ts +3 -0
- package/lib/types/client/self-topic-menu-hover.d.ts.map +1 -0
- package/lib/types/client/use-calendar-month.d.ts +4 -0
- package/lib/types/client/use-calendar-month.d.ts.map +1 -0
- package/lib/types/dsh-agent-input-source.d.ts +2 -0
- package/lib/types/dsh-agent-input-source.d.ts.map +1 -1
- package/lib/types/host-api.d.ts.map +1 -1
- package/lib/types/services/calendar-service.d.ts +10 -0
- package/lib/types/services/calendar-service.d.ts.map +1 -1
- package/lib/types/services/chat-realtime-service.d.ts +3 -1
- package/lib/types/services/chat-realtime-service.d.ts.map +1 -1
- package/lib/types/services/chat-service.d.ts +3 -1
- package/lib/types/services/chat-service.d.ts.map +1 -1
- package/lib/types/services/record-service.d.ts.map +1 -1
- package/lib/types/services/service.d.ts +5 -0
- package/lib/types/services/service.d.ts.map +1 -1
- package/lib/types/services/source-service.d.ts +3 -0
- package/lib/types/services/source-service.d.ts.map +1 -1
- package/lib/types/types.d.ts +3 -1
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1153,6 +1153,51 @@ var ServiceRuntime = class {
|
|
|
1153
1153
|
readRevision(scope) {
|
|
1154
1154
|
return this.readRevisions.get(scope) ?? 0;
|
|
1155
1155
|
}
|
|
1156
|
+
calendarRevisions = /* @__PURE__ */ new Map();
|
|
1157
|
+
calendarVersion(scope) {
|
|
1158
|
+
let value = this.calendarRevisions.get(scope);
|
|
1159
|
+
if (!value) {
|
|
1160
|
+
value = {
|
|
1161
|
+
epoch: 0,
|
|
1162
|
+
revision: 0,
|
|
1163
|
+
dates: /* @__PURE__ */ new Map()
|
|
1164
|
+
};
|
|
1165
|
+
this.calendarRevisions.set(scope, value);
|
|
1166
|
+
}
|
|
1167
|
+
return value;
|
|
1168
|
+
}
|
|
1169
|
+
calendarReadRevision(scope, start, end, timezone) {
|
|
1170
|
+
const value = this.calendarVersion(scope);
|
|
1171
|
+
const format = new Intl.DateTimeFormat("en-CA", {
|
|
1172
|
+
timeZone: timezone === "local" ? void 0 : timezone,
|
|
1173
|
+
year: "numeric",
|
|
1174
|
+
month: "2-digit",
|
|
1175
|
+
day: "2-digit"
|
|
1176
|
+
});
|
|
1177
|
+
let revision = 0;
|
|
1178
|
+
for (const [stamp, changed] of value.dates) {
|
|
1179
|
+
const day = format.format(new Date(stamp));
|
|
1180
|
+
if (day >= start && day <= end) revision = Math.max(revision, changed);
|
|
1181
|
+
}
|
|
1182
|
+
return `${value.epoch}:${revision}`;
|
|
1183
|
+
}
|
|
1184
|
+
/** Chat deltas invalidate only affected composite month results (in any timezone). */
|
|
1185
|
+
invalidateCalendarDates(scope, stamps) {
|
|
1186
|
+
const dates = [...new Set(stamps.filter((stamp) => Number.isFinite(stamp) && stamp > 0))];
|
|
1187
|
+
if (!dates.length) {
|
|
1188
|
+
this.invalidateKey(scope, "calendar:");
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1191
|
+
const value = this.calendarVersion(scope);
|
|
1192
|
+
if (value.dates.size + dates.length > 256) {
|
|
1193
|
+
value.epoch++;
|
|
1194
|
+
value.dates.clear();
|
|
1195
|
+
}
|
|
1196
|
+
for (const stamp of dates) value.dates.set(stamp, ++value.revision);
|
|
1197
|
+
this.readRevisions.set(scope, this.readRevision(scope) + 1);
|
|
1198
|
+
this.requestCoordinator.invalidateKey(scope, "calendar:");
|
|
1199
|
+
this.requestCoordinator.invalidateKey(scope, "owner-read:");
|
|
1200
|
+
}
|
|
1156
1201
|
async withOwnerReadInvalidation(route, operation) {
|
|
1157
1202
|
const session = await this.requireSession();
|
|
1158
1203
|
try {
|
|
@@ -1194,16 +1239,25 @@ var ServiceRuntime = class {
|
|
|
1194
1239
|
});
|
|
1195
1240
|
}
|
|
1196
1241
|
invalidateScope(scope) {
|
|
1242
|
+
const calendar = this.calendarVersion(scope);
|
|
1243
|
+
calendar.epoch++;
|
|
1244
|
+
calendar.dates.clear();
|
|
1197
1245
|
this.readRevisions.set(scope, this.readRevision(scope) + 1);
|
|
1198
1246
|
this.requestCoordinator.invalidateScope(scope);
|
|
1199
1247
|
}
|
|
1200
1248
|
invalidateKey(scope, key) {
|
|
1249
|
+
if (key.startsWith("calendar:")) {
|
|
1250
|
+
const calendar = this.calendarVersion(scope);
|
|
1251
|
+
calendar.epoch++;
|
|
1252
|
+
calendar.dates.clear();
|
|
1253
|
+
}
|
|
1201
1254
|
this.readRevisions.set(scope, this.readRevision(scope) + 1);
|
|
1202
1255
|
this.requestCoordinator.invalidateKey(scope, key);
|
|
1203
1256
|
this.requestCoordinator.invalidateKey(scope, "owner-read:");
|
|
1204
1257
|
}
|
|
1205
1258
|
dispose() {
|
|
1206
1259
|
this.refreshInFlightByUserId.clear();
|
|
1260
|
+
this.calendarRevisions.clear();
|
|
1207
1261
|
this.requestCoordinator.dispose();
|
|
1208
1262
|
}
|
|
1209
1263
|
async requireSession() {
|
|
@@ -35608,6 +35662,8 @@ var SourceService = class {
|
|
|
35608
35662
|
chatSourceCache = /* @__PURE__ */ new Map();
|
|
35609
35663
|
sourceListCache = /* @__PURE__ */ new Map();
|
|
35610
35664
|
sourceListInFlight = new SharedReadGroup();
|
|
35665
|
+
selfDirectoryContexts = /* @__PURE__ */ new Map();
|
|
35666
|
+
selfDirectoryContextReads = new SharedReadGroup();
|
|
35611
35667
|
groupAvatarSnapshotCache = /* @__PURE__ */ new Map();
|
|
35612
35668
|
topicDissolveProgress = /* @__PURE__ */ new Map();
|
|
35613
35669
|
constructor(runtime, profile, recordReader, privacy = new ArkmePrivacyVisibilityService(runtime)) {
|
|
@@ -35886,6 +35942,8 @@ var SourceService = class {
|
|
|
35886
35942
|
this.chatSourceCache.clear();
|
|
35887
35943
|
this.sourceListCache.clear();
|
|
35888
35944
|
this.sourceListInFlight.clear();
|
|
35945
|
+
this.selfDirectoryContexts.clear();
|
|
35946
|
+
this.selfDirectoryContextReads.clear();
|
|
35889
35947
|
this.groupAvatarSnapshotCache.clear();
|
|
35890
35948
|
this.topicDissolveProgress.clear();
|
|
35891
35949
|
}
|
|
@@ -36224,7 +36282,7 @@ var SourceService = class {
|
|
|
36224
36282
|
const movedParentUid = stringValue$2(moved.parent_topic_uid).trim();
|
|
36225
36283
|
const siblingOrder = numberValue$26(moved.sibling_order);
|
|
36226
36284
|
if (movedTopicUid !== topic.ownerRef || movedParentUid !== (nextParentUid ?? "") || siblingOrder <= 0) throw new ArkmePluginError("topic-hierarchy-move-contract-invalid", "主题移动响应不完整,请刷新后重试", true, 502);
|
|
36227
|
-
this.
|
|
36285
|
+
this.invalidateSourceListCache(session.userId, "send_to_self");
|
|
36228
36286
|
return {
|
|
36229
36287
|
sourceRef,
|
|
36230
36288
|
...nextParentSourceRef === void 0 ? {} : { parentSourceRef: nextParentSourceRef },
|
|
@@ -36286,6 +36344,10 @@ var SourceService = class {
|
|
|
36286
36344
|
options.signal?.throwIfAborted();
|
|
36287
36345
|
const limit = Math.min(directory === "send_to_self" ? 100 : 50, Math.max(1, Math.trunc(options.limit ?? 30)));
|
|
36288
36346
|
const cursor = options.cursor?.trim() ?? "";
|
|
36347
|
+
if (directory === "send_to_self" && options.refresh === true && cursor === "") {
|
|
36348
|
+
this.selfDirectoryContexts.delete(session.userId);
|
|
36349
|
+
this.selfDirectoryContextReads.invalidate((key) => key === String(session.userId));
|
|
36350
|
+
}
|
|
36289
36351
|
const cacheKey = `${String(session.userId)}:${directory}:${String(limit)}:${cursor}:${options.firstPaint === true ? "first" : "full"}`;
|
|
36290
36352
|
this.pruneSourceListCache();
|
|
36291
36353
|
const cached = this.sourceListCache.get(cacheKey);
|
|
@@ -36464,19 +36526,34 @@ var SourceService = class {
|
|
|
36464
36526
|
}
|
|
36465
36527
|
throw new ArkmePluginError("directory-groups-pagination-limit", "群聊列表超过安全分页上限", false, 502);
|
|
36466
36528
|
}
|
|
36529
|
+
async selfDirectoryContext(session, signal) {
|
|
36530
|
+
const cached = this.selfDirectoryContexts.get(session.userId);
|
|
36531
|
+
if (cached && cached.expiresAtMillis > Date.now()) return cached.value;
|
|
36532
|
+
return this.selfDirectoryContextReads.run(String(session.userId), async (inner, isCurrent) => {
|
|
36533
|
+
const [hierarchyData, [summaryResult, latestRecordsResult]] = await Promise.all([this.runtime.authenticatedPost("/api/v1/topics/hierarchy/relations/list", {}, session, inner).catch(() => void 0), Promise.allSettled([this.recordReader.summary(), this.runtime.authenticatedPost("/api/v1/records/uncategorized/query", { limit: 10 }, session, inner)])]);
|
|
36534
|
+
const value = {
|
|
36535
|
+
hierarchyData,
|
|
36536
|
+
summaryResult,
|
|
36537
|
+
latestRecordsResult
|
|
36538
|
+
};
|
|
36539
|
+
if (isCurrent()) this.selfDirectoryContexts.set(session.userId, {
|
|
36540
|
+
value,
|
|
36541
|
+
expiresAtMillis: Date.now() + SOURCE_LIST_CACHE_TTL_MS
|
|
36542
|
+
});
|
|
36543
|
+
return value;
|
|
36544
|
+
}, signal);
|
|
36545
|
+
}
|
|
36467
36546
|
async listSourcesUncached(session, directory, options, limit, sessionKind) {
|
|
36468
36547
|
if (directory === "send_to_self") {
|
|
36469
36548
|
const lockedRecordUids = await this.privacy.lockedRecordUids(session, options.signal);
|
|
36470
36549
|
const topicPage = options.cursor === void 0 || options.cursor.trim() === "" ? void 0 : this.decodeTopicDirectoryCursor(options.cursor);
|
|
36471
|
-
const [data, hierarchyData] = await Promise.all([this.runtime.authenticatedPost("/api/v1/topics/display/list", {
|
|
36550
|
+
const [data, { hierarchyData, summaryResult, latestRecordsResult }] = await Promise.all([this.runtime.authenticatedPost("/api/v1/topics/display/list", {
|
|
36472
36551
|
limit: Math.min(100, Math.max(1, limit)),
|
|
36473
36552
|
keyword: "",
|
|
36474
36553
|
privacy_state: 1,
|
|
36475
36554
|
...topicPage?.pageCursor === void 0 ? {} : { page_cursor: topicPage.pageCursor },
|
|
36476
36555
|
...topicPage?.offset === void 0 ? {} : { offset: topicPage.offset }
|
|
36477
|
-
}, session, options.signal), this.
|
|
36478
|
-
options.signal?.throwIfAborted();
|
|
36479
|
-
const [summaryResult, latestRecordsResult] = await Promise.allSettled([this.recordReader.summary(), this.runtime.authenticatedPost("/api/v1/records/uncategorized/query", { limit: 10 }, session, options.signal)]);
|
|
36556
|
+
}, session, options.signal), this.selfDirectoryContext(session, options.signal)]);
|
|
36480
36557
|
options.signal?.throwIfAborted();
|
|
36481
36558
|
const cached = summaryResult.status === "rejected" || latestRecordsResult.status === "rejected" ? await this.runtime.stateStore.cachedSnapshot(session.userId).catch(() => void 0) : void 0;
|
|
36482
36559
|
const defaultRecordCount = summaryResult.status === "fulfilled" ? summaryResult.value.recordCount : cached?.summary?.recordCount;
|
|
@@ -36512,6 +36589,7 @@ var SourceService = class {
|
|
|
36512
36589
|
const item = objectValue$2(raw);
|
|
36513
36590
|
if (arkmePrivacyLockedTopic(item)) continue;
|
|
36514
36591
|
const core = objectValue$2(item.topic_core);
|
|
36592
|
+
if (numberValue$26(core.kind) === 3) continue;
|
|
36515
36593
|
const status = core.status ?? item.status;
|
|
36516
36594
|
if (status !== void 0 && numberValue$26(status) !== 1) continue;
|
|
36517
36595
|
const summary = objectValue$2(item.summary);
|
|
@@ -36690,6 +36768,10 @@ var SourceService = class {
|
|
|
36690
36768
|
};
|
|
36691
36769
|
}
|
|
36692
36770
|
invalidateSourceListCache(userId, directory) {
|
|
36771
|
+
if (directory === void 0 || directory === "send_to_self") {
|
|
36772
|
+
this.selfDirectoryContexts.delete(userId);
|
|
36773
|
+
this.selfDirectoryContextReads.invalidate((key) => key === String(userId));
|
|
36774
|
+
}
|
|
36693
36775
|
if (directory === void 0 || directory === "root") this.runtime.invalidateKey(this.runtime.requestScope(userId), "directory:root:");
|
|
36694
36776
|
const prefix = `${String(userId)}:`;
|
|
36695
36777
|
const matches = (key) => key.startsWith(prefix) && (directory === void 0 || key.startsWith(`${prefix}${directory}:`));
|
|
@@ -37879,10 +37961,29 @@ var BotConversationService = class {
|
|
|
37879
37961
|
return context.reference.target.kind === "subject" ? this.subject : this.chatAdapter;
|
|
37880
37962
|
}
|
|
37881
37963
|
};
|
|
37964
|
+
/** Authoritative wire fields only: ordinary topics may have the same title. */
|
|
37965
|
+
function isDshAgentInputRawRecord(raw) {
|
|
37966
|
+
const object = (value) => value !== null && typeof value === "object" ? value : {};
|
|
37967
|
+
const item = object(raw);
|
|
37968
|
+
const core = object(item.record_core);
|
|
37969
|
+
const topic = object(item.topic_core);
|
|
37970
|
+
return Number(item.creation_source ?? item.creationSource ?? core.creation_source ?? core.creationSource) === 3 || Number(topic.kind ?? item.topicKind) === 3;
|
|
37971
|
+
}
|
|
37882
37972
|
//#endregion
|
|
37883
37973
|
//#region src/services/calendar-service.ts
|
|
37884
37974
|
const MAX_CALENDAR_RANGE_DAYS = 62;
|
|
37885
37975
|
const MAX_DAY_RECORD_LIMIT = 50;
|
|
37976
|
+
async function mapBounded(items, project) {
|
|
37977
|
+
const result = new Array(items.length);
|
|
37978
|
+
let index = 0;
|
|
37979
|
+
await Promise.all(Array.from({ length: Math.min(4, items.length) }, async () => {
|
|
37980
|
+
while (index < items.length) {
|
|
37981
|
+
const current = index++;
|
|
37982
|
+
result[current] = await project(items[current]);
|
|
37983
|
+
}
|
|
37984
|
+
}));
|
|
37985
|
+
return result;
|
|
37986
|
+
}
|
|
37886
37987
|
function numberValue$23(value) {
|
|
37887
37988
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
37888
37989
|
}
|
|
@@ -37943,6 +38044,12 @@ var CalendarService = class {
|
|
|
37943
38044
|
media;
|
|
37944
38045
|
record;
|
|
37945
38046
|
source;
|
|
38047
|
+
months = /* @__PURE__ */ new Map();
|
|
38048
|
+
monthReads = new SharedReadGroup();
|
|
38049
|
+
dispose() {
|
|
38050
|
+
this.months.clear();
|
|
38051
|
+
this.monthReads.clear();
|
|
38052
|
+
}
|
|
37946
38053
|
constructor(runtime, privacy, media, record, source) {
|
|
37947
38054
|
this.runtime = runtime;
|
|
37948
38055
|
this.privacy = privacy;
|
|
@@ -37951,6 +38058,44 @@ var CalendarService = class {
|
|
|
37951
38058
|
this.source = source;
|
|
37952
38059
|
}
|
|
37953
38060
|
async bucketPage(options) {
|
|
38061
|
+
options.signal?.throwIfAborted();
|
|
38062
|
+
const session = await this.runtime.requireSession();
|
|
38063
|
+
const timezone = readTimezone(options.timezone);
|
|
38064
|
+
const key = JSON.stringify([
|
|
38065
|
+
session.userId,
|
|
38066
|
+
options.sourceRef ?? "global",
|
|
38067
|
+
options.startDate,
|
|
38068
|
+
options.endDate,
|
|
38069
|
+
timezone
|
|
38070
|
+
]);
|
|
38071
|
+
const revision = () => this.runtime.calendarReadRevision?.(`user:${session.userId}`, options.startDate, options.endDate, timezone) ?? "0";
|
|
38072
|
+
const version = revision();
|
|
38073
|
+
const cached = this.months.get(key);
|
|
38074
|
+
if (cached && cached.revision === version && cached.expires > Date.now()) {
|
|
38075
|
+
this.months.delete(key);
|
|
38076
|
+
this.months.set(key, cached);
|
|
38077
|
+
return structuredClone(cached.value);
|
|
38078
|
+
}
|
|
38079
|
+
return structuredClone(await this.monthReads.run(`${key}:${version}`, async (signal, isCurrent) => {
|
|
38080
|
+
const value = await this.bucketPageUncached({
|
|
38081
|
+
...options,
|
|
38082
|
+
timezone,
|
|
38083
|
+
signal
|
|
38084
|
+
});
|
|
38085
|
+
signal.throwIfAborted();
|
|
38086
|
+
if (isCurrent() && revision() === version) {
|
|
38087
|
+
this.months.delete(key);
|
|
38088
|
+
this.months.set(key, {
|
|
38089
|
+
revision: version,
|
|
38090
|
+
expires: Date.now() + 6e4,
|
|
38091
|
+
value
|
|
38092
|
+
});
|
|
38093
|
+
while (this.months.size > 48) this.months.delete(this.months.keys().next().value);
|
|
38094
|
+
}
|
|
38095
|
+
return value;
|
|
38096
|
+
}, options.signal));
|
|
38097
|
+
}
|
|
38098
|
+
async bucketPageUncached(options) {
|
|
37954
38099
|
const startDate = readCalendarDate(options.startDate, "start_date");
|
|
37955
38100
|
const endDate = readCalendarDate(options.endDate, "end_date");
|
|
37956
38101
|
const startDay = calendarDayNumber(startDate);
|
|
@@ -37959,25 +38104,60 @@ var CalendarService = class {
|
|
|
37959
38104
|
if (endDay - startDay + 1 > MAX_CALENDAR_RANGE_DAYS) throw new ArkmePluginError("calendar-range-too-wide", `日历范围最多查询 ${MAX_CALENDAR_RANGE_DAYS} 天`, false);
|
|
37960
38105
|
const timezone = readTimezone(options.timezone);
|
|
37961
38106
|
const session = await this.runtime.requireSession();
|
|
37962
|
-
await this.privacy.lockedRecordUids(session, options.signal);
|
|
37963
|
-
const
|
|
37964
|
-
|
|
37965
|
-
|
|
37966
|
-
|
|
37967
|
-
|
|
37968
|
-
|
|
37969
|
-
|
|
37970
|
-
|
|
37971
|
-
|
|
37972
|
-
|
|
38107
|
+
const locked = await this.privacy.lockedRecordUids(session, options.signal);
|
|
38108
|
+
const scope = await this.resolveScope(options.sourceRef, session, options.signal);
|
|
38109
|
+
const pages = await mapBounded(scope.buckets, async (bucket) => {
|
|
38110
|
+
return {
|
|
38111
|
+
bucket,
|
|
38112
|
+
days: listValue$20((await this.runtime.authenticatedCalendarPost("/api/v1/calendar/buckets/query", {
|
|
38113
|
+
bucket_scope_kind: bucket.kind,
|
|
38114
|
+
bucket_scope_uid: bucket.uid,
|
|
38115
|
+
start_date: startDate,
|
|
38116
|
+
end_date: endDate,
|
|
38117
|
+
timezone
|
|
38118
|
+
}, session, options.signal, {
|
|
38119
|
+
key: `calendar:buckets:${bucket.kind === 1 ? "self" : `topic:${bucket.uid}`}:${startDate}:${endDate}:${timezone}`,
|
|
38120
|
+
cacheMs: 3e4,
|
|
38121
|
+
lane: options.background ? "background-read" : "interactive-read",
|
|
38122
|
+
failureCooldownMs: 2e3
|
|
38123
|
+
})).daily_data).map((raw) => this.bucketDay(raw)).filter((day) => day !== void 0)
|
|
38124
|
+
};
|
|
38125
|
+
});
|
|
38126
|
+
const days = await mapBounded([...new Set(pages.flatMap((page) => page.days.map((day) => day.bucketDate)))].sort(), async (bucketDate) => {
|
|
38127
|
+
const contributors = pages.flatMap((page) => {
|
|
38128
|
+
const day = page.days.find((day) => day.bucketDate === bucketDate);
|
|
38129
|
+
return day?.hasRecords ? [{
|
|
38130
|
+
bucket: page.bucket,
|
|
38131
|
+
day
|
|
38132
|
+
}] : [];
|
|
38133
|
+
});
|
|
38134
|
+
if (scope.kind === "self") return contributors[0]?.day ?? {
|
|
38135
|
+
bucketDate,
|
|
38136
|
+
count: 0,
|
|
38137
|
+
protectedCount: 0,
|
|
38138
|
+
hasRecords: false
|
|
38139
|
+
};
|
|
38140
|
+
const records = /* @__PURE__ */ new Map();
|
|
38141
|
+
for (const { bucket } of contributors) {
|
|
38142
|
+
const rows = await this.scopedDayRows(bucket, scope.kind, bucketDate, timezone, Infinity, void 0, session, locked, options.signal, options.background);
|
|
38143
|
+
for (const { item } of rows) records.set(item.recordUid, item);
|
|
38144
|
+
}
|
|
38145
|
+
const first = Math.min(...[...records.values()].map((item) => item.sendAtMillis));
|
|
38146
|
+
return {
|
|
38147
|
+
bucketDate,
|
|
38148
|
+
count: records.size,
|
|
38149
|
+
protectedCount: 0,
|
|
38150
|
+
hasRecords: records.size > 0,
|
|
38151
|
+
...Number.isFinite(first) ? { firstSendAtMillis: first } : {}
|
|
38152
|
+
};
|
|
37973
38153
|
});
|
|
37974
38154
|
return {
|
|
37975
|
-
scope:
|
|
38155
|
+
scope: scope.kind,
|
|
37976
38156
|
startDate,
|
|
37977
38157
|
endDate,
|
|
37978
|
-
timezone
|
|
38158
|
+
timezone,
|
|
37979
38159
|
refreshedAtMillis: Date.now(),
|
|
37980
|
-
days
|
|
38160
|
+
days
|
|
37981
38161
|
};
|
|
37982
38162
|
}
|
|
37983
38163
|
async dayRecords(options) {
|
|
@@ -37988,7 +38168,21 @@ var CalendarService = class {
|
|
|
37988
38168
|
const cursorRecordUid = options.cursor?.recordUid.trim() ?? "";
|
|
37989
38169
|
const session = await this.runtime.requireSession();
|
|
37990
38170
|
const lockedRecordUids = await this.privacy.lockedRecordUids(session, options.signal);
|
|
37991
|
-
const
|
|
38171
|
+
const scope = await this.resolveScope(options.sourceRef, session, options.signal);
|
|
38172
|
+
let data;
|
|
38173
|
+
if (scope.kind !== "self") {
|
|
38174
|
+
const streams = await mapBounded(scope.buckets, (bucket) => this.scopedDayRows(bucket, scope.kind, bucketDate, timezone, limit + 1, options.cursor, session, lockedRecordUids, options.signal));
|
|
38175
|
+
const sorted = [...new Map(streams.flat().map((row) => [row.item.recordUid, row])).values()].sort((a, b) => b.item.sendAtMillis - a.item.sendAtMillis || b.item.recordUid.localeCompare(a.item.recordUid));
|
|
38176
|
+
const last = sorted[Math.min(limit, sorted.length) - 1]?.item;
|
|
38177
|
+
data = {
|
|
38178
|
+
items: sorted.slice(0, limit).map((row) => row.raw),
|
|
38179
|
+
has_more: sorted.length > limit,
|
|
38180
|
+
...sorted.length > limit && last ? {
|
|
38181
|
+
next_cursor_send_at: last.sendAtMillis,
|
|
38182
|
+
next_cursor_record_uid: last.recordUid
|
|
38183
|
+
} : {}
|
|
38184
|
+
};
|
|
38185
|
+
} else data = await this.runtime.authenticatedCalendarPost("/api/v1/calendar/records/query", {
|
|
37992
38186
|
bucket_scope_kind: 1,
|
|
37993
38187
|
bucket_scope_uid: "",
|
|
37994
38188
|
bucket_date: bucketDate,
|
|
@@ -38034,7 +38228,7 @@ var CalendarService = class {
|
|
|
38034
38228
|
}
|
|
38035
38229
|
const media = await this.media.hydrateRecordMediaPage(rows.filter((row) => row.item.accessState === "available").map((row) => row.raw), session, options.signal);
|
|
38036
38230
|
return {
|
|
38037
|
-
scope:
|
|
38231
|
+
scope: scope.kind,
|
|
38038
38232
|
bucketDate,
|
|
38039
38233
|
timezone: stringValue$2(data.timezone).trim() || timezone,
|
|
38040
38234
|
refreshedAtMillis: Date.now(),
|
|
@@ -38064,6 +38258,96 @@ var CalendarService = class {
|
|
|
38064
38258
|
} } : {}
|
|
38065
38259
|
};
|
|
38066
38260
|
}
|
|
38261
|
+
async resolveScope(sourceRef, session, signal) {
|
|
38262
|
+
if (sourceRef === void 0) return {
|
|
38263
|
+
kind: "self",
|
|
38264
|
+
buckets: [{
|
|
38265
|
+
kind: 1,
|
|
38266
|
+
uid: ""
|
|
38267
|
+
}]
|
|
38268
|
+
};
|
|
38269
|
+
const source = await this.source.openSourceRef(sourceRef, session.userId);
|
|
38270
|
+
if (source.kind === "send_to_self") return {
|
|
38271
|
+
kind: "send_to_self",
|
|
38272
|
+
buckets: [{
|
|
38273
|
+
kind: 1,
|
|
38274
|
+
uid: ""
|
|
38275
|
+
}]
|
|
38276
|
+
};
|
|
38277
|
+
if (source.kind === "default_category") return {
|
|
38278
|
+
kind: "uncategorized",
|
|
38279
|
+
buckets: [{
|
|
38280
|
+
kind: 1,
|
|
38281
|
+
uid: ""
|
|
38282
|
+
}]
|
|
38283
|
+
};
|
|
38284
|
+
if (source.kind !== "topic") throw new ArkmePluginError("calendar-source-invalid", "此日历仅支持发给自己和主题", false, 400);
|
|
38285
|
+
const metadata = await readTopicMetadata(this.runtime, session, source.ownerRef, signal);
|
|
38286
|
+
if (metadata.privacyState === 2) throw new ArkmePluginError("topic-privacy-locked", "隐私锁主题不能在 Arkme 插件中查看", false, 403);
|
|
38287
|
+
if (metadata.topicKind === 3) return {
|
|
38288
|
+
kind: "topic",
|
|
38289
|
+
buckets: []
|
|
38290
|
+
};
|
|
38291
|
+
return {
|
|
38292
|
+
kind: "topic",
|
|
38293
|
+
buckets: (await mapBounded(await this.source.topicSubtreeSources(sourceRef, signal), async (topic) => {
|
|
38294
|
+
const opened = await this.source.openSourceRef(topic.sourceRef, session.userId);
|
|
38295
|
+
const meta = opened.ownerRef === source.ownerRef ? metadata : await readTopicMetadata(this.runtime, session, opened.ownerRef, signal);
|
|
38296
|
+
return meta.privacyState === 2 || meta.topicKind === 3 ? [] : [{
|
|
38297
|
+
kind: 2,
|
|
38298
|
+
uid: opened.ownerRef
|
|
38299
|
+
}];
|
|
38300
|
+
})).flat()
|
|
38301
|
+
};
|
|
38302
|
+
}
|
|
38303
|
+
/** Read only one calendar day; backfill filtered rows and reject stalled cursors. */
|
|
38304
|
+
async scopedDayRows(bucket, scope, bucketDate, timezone, count, cursor, session, locked, signal, background = false) {
|
|
38305
|
+
const rows = /* @__PURE__ */ new Map();
|
|
38306
|
+
const visited = /* @__PURE__ */ new Set();
|
|
38307
|
+
for (let page = 0; page < 1e3; page++) {
|
|
38308
|
+
signal?.throwIfAborted();
|
|
38309
|
+
const key = `${cursor?.sendAtMillis ?? 0}:${cursor?.recordUid ?? ""}`;
|
|
38310
|
+
if (visited.has(key)) throw new ArkmePluginError("calendar-cursor-invalid", "日历分页未推进,请重试", true, 502);
|
|
38311
|
+
visited.add(key);
|
|
38312
|
+
const data = await this.runtime.authenticatedCalendarPost("/api/v1/calendar/records/query", {
|
|
38313
|
+
bucket_scope_kind: bucket.kind,
|
|
38314
|
+
bucket_scope_uid: bucket.uid,
|
|
38315
|
+
bucket_date: bucketDate,
|
|
38316
|
+
timezone,
|
|
38317
|
+
limit: MAX_DAY_RECORD_LIMIT,
|
|
38318
|
+
...cursor ? {
|
|
38319
|
+
cursor_send_at: cursor.sendAtMillis,
|
|
38320
|
+
cursor_record_uid: cursor.recordUid
|
|
38321
|
+
} : {}
|
|
38322
|
+
}, session, signal, {
|
|
38323
|
+
key: `calendar:records:${bucket.kind === 1 ? "self" : `topic:${bucket.uid}`}:${bucketDate}:${timezone}:50:${key}`,
|
|
38324
|
+
cacheMs: 1e4,
|
|
38325
|
+
failureCooldownMs: 2e3,
|
|
38326
|
+
lane: background ? "background-read" : "interactive-read"
|
|
38327
|
+
});
|
|
38328
|
+
for (const raw of listValue$20(data.items)) {
|
|
38329
|
+
const item = this.dayRecord(raw);
|
|
38330
|
+
if (!item || locked.has(item.recordUid)) continue;
|
|
38331
|
+
if (isDshAgentInputRawRecord(raw)) continue;
|
|
38332
|
+
if (scope === "uncategorized" && item.isUncategorized !== true) continue;
|
|
38333
|
+
if (scope === "send_to_self" && item.sourceKind !== "self" && item.sourceKind !== "topic") continue;
|
|
38334
|
+
rows.set(item.recordUid, {
|
|
38335
|
+
raw,
|
|
38336
|
+
item
|
|
38337
|
+
});
|
|
38338
|
+
if (rows.size >= count) return [...rows.values()];
|
|
38339
|
+
}
|
|
38340
|
+
if (data.has_more !== true) return [...rows.values()];
|
|
38341
|
+
const sendAtMillis = Math.trunc(numberValue$23(data.next_cursor_send_at));
|
|
38342
|
+
const recordUid = stringValue$2(data.next_cursor_record_uid).trim();
|
|
38343
|
+
if (sendAtMillis <= 0 || recordUid === "") throw new ArkmePluginError("calendar-cursor-invalid", "日历分页信息缺失,请重试", true, 502);
|
|
38344
|
+
cursor = {
|
|
38345
|
+
sendAtMillis,
|
|
38346
|
+
recordUid
|
|
38347
|
+
};
|
|
38348
|
+
}
|
|
38349
|
+
throw new ArkmePluginError("calendar-pagination-limit", "日历当日记录尚未加载完整,请重试", true, 502);
|
|
38350
|
+
}
|
|
38067
38351
|
bucketDay(raw) {
|
|
38068
38352
|
const item = objectValue$2(raw);
|
|
38069
38353
|
const bucketDate = stringValue$2(item.bucket_date).trim();
|
|
@@ -38103,7 +38387,7 @@ var CalendarService = class {
|
|
|
38103
38387
|
preview,
|
|
38104
38388
|
...stringValue$2(topic.title).trim() === "" ? {} : { topicTitle: stringValue$2(topic.title).trim() },
|
|
38105
38389
|
sourceKind: sourceKind(item),
|
|
38106
|
-
creationSource: Math.trunc(numberValue$23(core.creation_source)),
|
|
38390
|
+
creationSource: isDshAgentInputRawRecord(raw) ? 3 : Math.trunc(numberValue$23(core.creation_source)),
|
|
38107
38391
|
templateKind: Math.trunc(numberValue$23(core.template_kind)),
|
|
38108
38392
|
displayKind: Math.trunc(numberValue$23(core.display_kind)),
|
|
38109
38393
|
protected: false,
|
|
@@ -40341,7 +40625,7 @@ var ChatRealtimeService = class {
|
|
|
40341
40625
|
console.warn("dsh-arkme: Chat read receipt invalidation failed:", safeFailureMessage$5(error));
|
|
40342
40626
|
}
|
|
40343
40627
|
}
|
|
40344
|
-
async invalidateRecordProjection() {
|
|
40628
|
+
async invalidateRecordProjection(options = {}) {
|
|
40345
40629
|
try {
|
|
40346
40630
|
const session = await this.runtime.sessionStore.read();
|
|
40347
40631
|
if (session === void 0) return;
|
|
@@ -40350,7 +40634,8 @@ var ChatRealtimeService = class {
|
|
|
40350
40634
|
this.emitChatClientEvent({
|
|
40351
40635
|
type: "projection-invalidated",
|
|
40352
40636
|
revision: this.nextChatClientRevision(),
|
|
40353
|
-
projection: "record"
|
|
40637
|
+
projection: "record",
|
|
40638
|
+
...options.contentOnly ? { retainTopicCounts: true } : {}
|
|
40354
40639
|
});
|
|
40355
40640
|
} catch (error) {
|
|
40356
40641
|
console.warn("dsh-arkme: Record projection invalidation failed:", safeFailureMessage$5(error));
|
|
@@ -40975,7 +41260,7 @@ var ChatRealtimeService = class {
|
|
|
40975
41260
|
if (ownerGeneration !== this.attentionOwnerGeneration) return [];
|
|
40976
41261
|
if (updates.length > 0) {
|
|
40977
41262
|
this.source.invalidateSourceListCache(session.userId, "root");
|
|
40978
|
-
this.runtime.
|
|
41263
|
+
this.runtime.invalidateCalendarDates(this.runtime.requestScope(session.userId), updates.flatMap((update) => [update.source.activeAtMillis, ...update.timelineItems.map((item) => item.sendAtMillis)]));
|
|
40979
41264
|
this.emitChatClientEvent({
|
|
40980
41265
|
type: "sessions-delta",
|
|
40981
41266
|
revision: this.nextChatClientRevision(),
|
|
@@ -41864,7 +42149,6 @@ function numberValue$20(value) {
|
|
|
41864
42149
|
function listValue$17(value) {
|
|
41865
42150
|
return Array.isArray(value) ? value : [];
|
|
41866
42151
|
}
|
|
41867
|
-
const DSH_AGENT_INPUT_CREATION_SOURCE = 3;
|
|
41868
42152
|
const MAX_DEFAULT_CATEGORY_FILTER_BACKFILL_PAGES = 5;
|
|
41869
42153
|
const RECORD_REEDIT_SUPPORTED_TEMPLATE_KINDS = /* @__PURE__ */ new Set([
|
|
41870
42154
|
1,
|
|
@@ -41886,7 +42170,7 @@ function recordCreationSource(raw) {
|
|
|
41886
42170
|
return integerLikeValue$1(item.creation_source ?? item.creationSource ?? core.creation_source ?? core.creationSource);
|
|
41887
42171
|
}
|
|
41888
42172
|
function isDSHAgentInputRecord(raw) {
|
|
41889
|
-
return
|
|
42173
|
+
return isDshAgentInputRawRecord(raw);
|
|
41890
42174
|
}
|
|
41891
42175
|
function safeFailureMessage$4(error) {
|
|
41892
42176
|
if (error instanceof ArkmePluginError) return error.message;
|
|
@@ -45030,9 +45314,13 @@ var ChatService = class {
|
|
|
45030
45314
|
const opened = await this.source.openSourceRef(topic.sourceRef, session.userId);
|
|
45031
45315
|
if (opened.kind !== "topic") throw new ArkmePluginError("topic-subtree-source-invalid", "下级主题信息无效,请刷新后重试", true, 409);
|
|
45032
45316
|
const records = [];
|
|
45317
|
+
const visited = /* @__PURE__ */ new Set();
|
|
45033
45318
|
let pageCursor = cursor;
|
|
45034
45319
|
for (let pageIndex = 0; pageIndex < 100; pageIndex += 1) {
|
|
45035
45320
|
signal?.throwIfAborted();
|
|
45321
|
+
const key = JSON.stringify(pageCursor ?? {});
|
|
45322
|
+
if (visited.has(key)) throw new ArkmePluginError("topic-record-page-invalid", "主题快记分页未推进,请重试", true, 502);
|
|
45323
|
+
visited.add(key);
|
|
45036
45324
|
const page = await readTopicRecordPage(this.runtime, session, opened.ownerRef, {
|
|
45037
45325
|
limit,
|
|
45038
45326
|
...pageCursor === void 0 ? {} : { cursor: pageCursor },
|
|
@@ -45047,24 +45335,35 @@ var ChatService = class {
|
|
|
45047
45335
|
hasMore: false
|
|
45048
45336
|
};
|
|
45049
45337
|
}
|
|
45338
|
+
let filtered = false;
|
|
45050
45339
|
for (const raw of page.records) {
|
|
45051
|
-
if (arkmePrivacyLockedRecord(raw) || lockedRecordUids.has(this.record.recordUid(raw)))
|
|
45340
|
+
if (isDshAgentInputRawRecord(raw) || arkmePrivacyLockedRecord(raw) || lockedRecordUids.has(this.record.recordUid(raw))) {
|
|
45341
|
+
filtered = true;
|
|
45342
|
+
continue;
|
|
45343
|
+
}
|
|
45052
45344
|
records.push(raw);
|
|
45053
45345
|
}
|
|
45054
|
-
if (!merged) return {
|
|
45346
|
+
if (!merged && !filtered && records.length <= limit) return {
|
|
45055
45347
|
topic,
|
|
45056
45348
|
topicUid: opened.ownerRef,
|
|
45057
45349
|
records,
|
|
45058
45350
|
hasMore: page.hasMore,
|
|
45059
45351
|
...page.nextCursor === void 0 ? {} : { nextCursor: page.nextCursor }
|
|
45060
45352
|
};
|
|
45061
|
-
if (records.length >= limit)
|
|
45062
|
-
|
|
45063
|
-
|
|
45064
|
-
|
|
45065
|
-
|
|
45066
|
-
|
|
45067
|
-
|
|
45353
|
+
if (records.length >= limit) {
|
|
45354
|
+
const last = objectValue$2(records[limit - 1]);
|
|
45355
|
+
const nextCursor = records.length > limit ? {
|
|
45356
|
+
sendAtMillis: numberValue$19(last.send_at ?? objectValue$2(last.record_core).send_at),
|
|
45357
|
+
itemUid: this.record.recordUid(last)
|
|
45358
|
+
} : page.nextCursor;
|
|
45359
|
+
return {
|
|
45360
|
+
topic,
|
|
45361
|
+
topicUid: opened.ownerRef,
|
|
45362
|
+
records: records.slice(0, limit),
|
|
45363
|
+
hasMore: records.length > limit || page.hasMore,
|
|
45364
|
+
...nextCursor === void 0 ? {} : { nextCursor }
|
|
45365
|
+
};
|
|
45366
|
+
}
|
|
45068
45367
|
if (!page.hasMore) return {
|
|
45069
45368
|
topic,
|
|
45070
45369
|
topicUid: opened.ownerRef,
|
|
@@ -45103,13 +45402,55 @@ var ChatService = class {
|
|
|
45103
45402
|
const limit = Math.min(100, Math.max(1, Math.trunc(options.limit ?? 30)));
|
|
45104
45403
|
if (source.kind === "send_to_self") {
|
|
45105
45404
|
const lockedRecordUids = await this.privacy.lockedRecordUids(session, options.signal);
|
|
45106
|
-
const
|
|
45107
|
-
|
|
45108
|
-
|
|
45109
|
-
|
|
45110
|
-
|
|
45111
|
-
|
|
45112
|
-
|
|
45405
|
+
const rawRecords = [];
|
|
45406
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45407
|
+
const visited = /* @__PURE__ */ new Set();
|
|
45408
|
+
let cursor = options.cursor;
|
|
45409
|
+
let hasMore = false;
|
|
45410
|
+
let nextCursor;
|
|
45411
|
+
for (let pageIndex = 0; pageIndex < 100; pageIndex++) {
|
|
45412
|
+
options.signal?.throwIfAborted();
|
|
45413
|
+
const key = `${cursor?.sendAtMillis ?? 0}:${cursor?.itemUid ?? ""}`;
|
|
45414
|
+
if (visited.has(key)) throw new ArkmePluginError("self-feed-cursor-invalid", "发给自己分页未推进,请重试", true, 502);
|
|
45415
|
+
visited.add(key);
|
|
45416
|
+
const data = await this.runtime.authenticatedPost("/api/v1/home/feed/query", {
|
|
45417
|
+
limit,
|
|
45418
|
+
source_kinds: [1, 2],
|
|
45419
|
+
...cursor?.sendAtMillis === void 0 ? {} : { cursor_send_at: cursor.sendAtMillis },
|
|
45420
|
+
...cursor?.itemUid === void 0 ? {} : { cursor_record_uid: cursor.itemUid }
|
|
45421
|
+
}, session, options.signal);
|
|
45422
|
+
const rows = listValue$16(data.items);
|
|
45423
|
+
let filtered = false;
|
|
45424
|
+
for (const raw of rows) {
|
|
45425
|
+
const uid = this.record.recordUid(raw);
|
|
45426
|
+
if (isDshAgentInputRawRecord(raw) || arkmePrivacyLockedRecord(raw) || lockedRecordUids.has(uid) || seen.has(uid)) {
|
|
45427
|
+
filtered = true;
|
|
45428
|
+
continue;
|
|
45429
|
+
}
|
|
45430
|
+
seen.add(uid);
|
|
45431
|
+
rawRecords.push(raw);
|
|
45432
|
+
}
|
|
45433
|
+
hasMore = data.has_more === true;
|
|
45434
|
+
const nextSendAt = numberValue$19(data.next_cursor_send_at);
|
|
45435
|
+
const nextUid = stringValue$2(data.next_cursor_record_uid).trim();
|
|
45436
|
+
nextCursor = nextSendAt > 0 && nextUid !== "" ? {
|
|
45437
|
+
sendAtMillis: nextSendAt,
|
|
45438
|
+
itemUid: nextUid
|
|
45439
|
+
} : void 0;
|
|
45440
|
+
if (rawRecords.length >= limit || !hasMore || !filtered) break;
|
|
45441
|
+
if (!nextCursor) throw new ArkmePluginError("self-feed-cursor-invalid", "发给自己分页信息缺失,请重试", true, 502);
|
|
45442
|
+
cursor = nextCursor;
|
|
45443
|
+
if (pageIndex === 99) throw new ArkmePluginError("self-feed-pagination-limit", "发给自己加载未完成,请重试", true, 502);
|
|
45444
|
+
}
|
|
45445
|
+
if (rawRecords.length > limit) {
|
|
45446
|
+
rawRecords.length = limit;
|
|
45447
|
+
const last = objectValue$2(rawRecords.at(-1));
|
|
45448
|
+
nextCursor = {
|
|
45449
|
+
sendAtMillis: numberValue$19(last.send_at ?? objectValue$2(last.record_core).send_at),
|
|
45450
|
+
itemUid: this.record.recordUid(last)
|
|
45451
|
+
};
|
|
45452
|
+
hasMore = true;
|
|
45453
|
+
}
|
|
45113
45454
|
const media = await this.media.hydrateRecordMediaPage(rawRecords, session, options.signal);
|
|
45114
45455
|
const signingKey = await this.runtime.stateStore.uniqueCode();
|
|
45115
45456
|
const items = (await Promise.all(rawRecords.map(async (raw) => {
|
|
@@ -45140,16 +45481,11 @@ var ChatService = class {
|
|
|
45140
45481
|
}))).filter((item) => item.itemUid !== "");
|
|
45141
45482
|
this.hydrateTimelineExtensionParents(items);
|
|
45142
45483
|
const projectedItems = items.map((item) => this.withRecordMessageActionRef(source, item, session.userId, signingKey));
|
|
45143
|
-
const nextSendAt = numberValue$19(data.next_cursor_send_at);
|
|
45144
|
-
const nextUid = stringValue$2(data.next_cursor_record_uid).trim();
|
|
45145
45484
|
return {
|
|
45146
45485
|
source: await this.source.sourceItem(source),
|
|
45147
45486
|
items: projectedItems,
|
|
45148
|
-
hasMore
|
|
45149
|
-
...
|
|
45150
|
-
sendAtMillis: nextSendAt,
|
|
45151
|
-
itemUid: nextUid
|
|
45152
|
-
} } : {}
|
|
45487
|
+
hasMore,
|
|
45488
|
+
...nextCursor === void 0 ? {} : { nextCursor }
|
|
45153
45489
|
};
|
|
45154
45490
|
}
|
|
45155
45491
|
if (source.kind === "default_category") {
|
|
@@ -46255,7 +46591,7 @@ var ChatService = class {
|
|
|
46255
46591
|
const publishedRecordUid = stringValue$2(data.record_uid).trim() || createdRecordUid;
|
|
46256
46592
|
const senderDisplayName = profile.nickname.trim() || profile.displayName.trim() || "我";
|
|
46257
46593
|
const senderAvatarUrl = profile.avatarRef.trim();
|
|
46258
|
-
await this.realtime.invalidateRecordProjection();
|
|
46594
|
+
await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
46259
46595
|
return {
|
|
46260
46596
|
sid: detail.sid,
|
|
46261
46597
|
recordUid: publishedRecordUid,
|
|
@@ -46350,7 +46686,7 @@ var ChatService = class {
|
|
|
46350
46686
|
content_payload: contentPayload,
|
|
46351
46687
|
send_at: Date.now()
|
|
46352
46688
|
}, session, options.signal);
|
|
46353
|
-
await this.realtime.invalidateRecordProjection();
|
|
46689
|
+
await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
46354
46690
|
return await appendCommentWarning({
|
|
46355
46691
|
sourceRef: targetSourceRef,
|
|
46356
46692
|
itemUid: stringValue$2(data.record_uid).trim() || recordUid,
|
|
@@ -46366,7 +46702,7 @@ var ChatService = class {
|
|
|
46366
46702
|
content_payload: contentPayload,
|
|
46367
46703
|
send_at: Date.now()
|
|
46368
46704
|
}, session, options.signal);
|
|
46369
|
-
await this.realtime.invalidateRecordProjection();
|
|
46705
|
+
await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
46370
46706
|
return await appendCommentWarning({
|
|
46371
46707
|
sourceRef: targetSourceRef,
|
|
46372
46708
|
itemUid: stringValue$2(data.record_uid).trim() || recordUid,
|
|
@@ -46389,7 +46725,7 @@ var ChatService = class {
|
|
|
46389
46725
|
...options.recordDurationMillis === void 0 ? {} : { recordDurationMillis: options.recordDurationMillis },
|
|
46390
46726
|
...options.captureContext === void 0 ? {} : { captureContext: options.captureContext }
|
|
46391
46727
|
});
|
|
46392
|
-
if (result.localState !== "failed") await this.realtime.invalidateRecordProjection();
|
|
46728
|
+
if (result.localState !== "failed") await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
46393
46729
|
return await this.withConfirmedSendReferences({
|
|
46394
46730
|
sourceRef,
|
|
46395
46731
|
itemUid: result.recordUid,
|
|
@@ -46422,7 +46758,7 @@ var ChatService = class {
|
|
|
46422
46758
|
send_at: sendAtMillis
|
|
46423
46759
|
}, session);
|
|
46424
46760
|
await this.record.syncCreatedRecordTags?.(stringValue$2(result.record_uid).trim() || recordUid, text, session.userId);
|
|
46425
|
-
await this.realtime.invalidateRecordProjection();
|
|
46761
|
+
await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
46426
46762
|
return await this.withConfirmedSendReferences({
|
|
46427
46763
|
sourceRef,
|
|
46428
46764
|
itemUid: stringValue$2(result.record_uid).trim() || recordUid,
|
|
@@ -46793,7 +47129,7 @@ var ChatService = class {
|
|
|
46793
47129
|
if (source.kind === "send_to_self" || source.kind === "default_category") {
|
|
46794
47130
|
const result = await this.runtime.authenticatedPost("/api/v1/records/create", commonBody, session, options.signal, { trackWriteOutcome: true });
|
|
46795
47131
|
await this.record.syncCreatedRecordTags?.(stringValue$2(result.record_uid).trim() || recordUid, textContent, session.userId, options.signal, input.textFormat);
|
|
46796
|
-
await this.realtime.invalidateRecordProjection();
|
|
47132
|
+
await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
46797
47133
|
return await this.withConfirmedSendReferences({
|
|
46798
47134
|
sourceRef,
|
|
46799
47135
|
itemUid: stringValue$2(result.record_uid).trim() || recordUid,
|
|
@@ -46818,7 +47154,7 @@ var ChatService = class {
|
|
|
46818
47154
|
...commonBody
|
|
46819
47155
|
}, session, options.signal, { trackWriteOutcome: true });
|
|
46820
47156
|
await this.record.syncCreatedRecordTags?.(stringValue$2(result.record_uid).trim() || recordUid, textContent, session.userId, options.signal, input.textFormat);
|
|
46821
|
-
await this.realtime.invalidateRecordProjection();
|
|
47157
|
+
await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
46822
47158
|
return await this.withConfirmedSendReferences({
|
|
46823
47159
|
sourceRef,
|
|
46824
47160
|
itemUid: stringValue$2(result.record_uid).trim() || recordUid,
|
|
@@ -89683,6 +90019,7 @@ var ArkmeService = class {
|
|
|
89683
90019
|
return await this.backgroundSoundPreferenceOwner.update(enabled, signal, expectedUserId);
|
|
89684
90020
|
}
|
|
89685
90021
|
clearAccountState(userIds) {
|
|
90022
|
+
this.calendar.dispose();
|
|
89686
90023
|
this.directory.reset();
|
|
89687
90024
|
this.realtime.resetAttentionSummary();
|
|
89688
90025
|
for (const userId of userIds) this.privacy.clear(userId);
|
|
@@ -90911,7 +91248,7 @@ var ArkmeService = class {
|
|
|
90911
91248
|
}
|
|
90912
91249
|
async createText(recordUid, textContent) {
|
|
90913
91250
|
const result = await this.record.createText(recordUid, textContent);
|
|
90914
|
-
await this.realtime.invalidateRecordProjection();
|
|
91251
|
+
await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
90915
91252
|
return result;
|
|
90916
91253
|
}
|
|
90917
91254
|
async listRecordTags(limit = 100, signal) {
|
|
@@ -90919,7 +91256,7 @@ var ArkmeService = class {
|
|
|
90919
91256
|
}
|
|
90920
91257
|
async createTextForConversation(recordUid, textContent) {
|
|
90921
91258
|
const result = await this.record.createTextForConversation(recordUid, textContent);
|
|
90922
|
-
if (result.localState !== "failed") await this.realtime.invalidateRecordProjection();
|
|
91259
|
+
if (result.localState !== "failed") await this.realtime.invalidateRecordProjection({ contentOnly: true });
|
|
90923
91260
|
return result;
|
|
90924
91261
|
}
|
|
90925
91262
|
async createDSHAgentInputText(recordUid, textContent, sendAtMillis) {
|