@opengeni/db 5.0.1-canary.0 → 5.0.1-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +6 -4
- package/dist/index.js +57 -25
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/index.ts +126 -55
package/dist/index.d.ts
CHANGED
|
@@ -5323,22 +5323,22 @@ export type SessionListSnapshotCursor = {
|
|
|
5323
5323
|
offset: number;
|
|
5324
5324
|
parentSessionFilter: string;
|
|
5325
5325
|
search: string | null;
|
|
5326
|
-
archiveMode: "active" | "archived";
|
|
5326
|
+
archiveMode: "active" | "archived" | "all";
|
|
5327
5327
|
/** Additive filter identity; absent on legacy snapshot cursors. */
|
|
5328
5328
|
filter?: string;
|
|
5329
5329
|
};
|
|
5330
5330
|
export type SessionListKeysetCursor = {
|
|
5331
5331
|
kind: "keyset";
|
|
5332
5332
|
/** Absent on v2 cursors, which always used session updatedAt. */
|
|
5333
|
-
sortBy?: "updatedAt" | "archivedAt";
|
|
5333
|
+
sortBy?: "updatedAt" | "archivedAt" | "createdAt" | "name";
|
|
5334
5334
|
/** Decimal committed workspace activity revision frozen on page one. */
|
|
5335
5335
|
snapshotRevision: string;
|
|
5336
|
-
/** Exact PostgreSQL timestamp
|
|
5336
|
+
/** Exact PostgreSQL timestamp (including microseconds), or normalized name for name order. */
|
|
5337
5337
|
sortAt: string;
|
|
5338
5338
|
id: string;
|
|
5339
5339
|
parentSessionFilter: string;
|
|
5340
5340
|
search: string | null;
|
|
5341
|
-
archiveMode: "active" | "archived";
|
|
5341
|
+
archiveMode: "active" | "archived" | "all";
|
|
5342
5342
|
/** Canonical identity for channel, creator, and time-bound filters. */
|
|
5343
5343
|
filter?: string;
|
|
5344
5344
|
};
|
|
@@ -5372,6 +5372,8 @@ export type ListSessionsForSubjectOptions = ListSessionsOptions & SessionListFil
|
|
|
5372
5372
|
pinsOnly?: boolean | undefined;
|
|
5373
5373
|
/** List personally archived chats instead of active chats. */
|
|
5374
5374
|
archivedOnly?: boolean | undefined;
|
|
5375
|
+
sortBy?: "updatedAt" | "createdAt" | "name" | undefined;
|
|
5376
|
+
archiveStatus?: "active" | "archived" | "all" | undefined;
|
|
5375
5377
|
/** Return a continuation cursor. Disable for legacy one-page array reads. */
|
|
5376
5378
|
materializeSnapshot?: boolean | undefined;
|
|
5377
5379
|
authorizationScope?: SessionAuthorizationListScope | undefined;
|
package/dist/index.js
CHANGED
|
@@ -65069,7 +65069,10 @@ function sessionFilters(options) {
|
|
|
65069
65069
|
and archive_state.session_id = ${sessions.rootSessionId}
|
|
65070
65070
|
and archive_state.archived = true
|
|
65071
65071
|
)`;
|
|
65072
|
-
|
|
65072
|
+
const archiveStatus = options.archiveStatus ?? (options.archivedOnly ? "archived" : "active");
|
|
65073
|
+
if (archiveStatus !== "all") {
|
|
65074
|
+
filters.push(archiveStatus === "archived" ? archivedRoot : sql86`not (${archivedRoot})`);
|
|
65075
|
+
}
|
|
65073
65076
|
if (options.authorizationScope) {
|
|
65074
65077
|
filters.push(sessionAuthorizationScopeFilter(options.authorizationScope));
|
|
65075
65078
|
}
|
|
@@ -65214,7 +65217,8 @@ function encodeSessionListCursor(cursor) {
|
|
|
65214
65217
|
return Buffer.from(
|
|
65215
65218
|
JSON.stringify(
|
|
65216
65219
|
cursor.kind === "keyset" ? {
|
|
65217
|
-
version:
|
|
65220
|
+
version: 4,
|
|
65221
|
+
sortBy: cursor.sortBy ?? "updatedAt",
|
|
65218
65222
|
// Preserve the old cursor envelope until every pre-v2 replica has
|
|
65219
65223
|
// rolled away. It resolves only to the typed expiry/rebase path.
|
|
65220
65224
|
snapshotId: SESSION_LIST_KEYSET_LEGACY_SNAPSHOT_ID,
|
|
@@ -65244,15 +65248,16 @@ function decodeSessionListCursor(value) {
|
|
|
65244
65248
|
const search = parsed.search;
|
|
65245
65249
|
const archiveMode = parsed.archiveMode ?? "active";
|
|
65246
65250
|
const filter = parsed.filter ?? "all";
|
|
65247
|
-
const filtersAreValid = (parentSessionFilter === "all" || parentSessionFilter === "null" || typeof parentSessionFilter === "string" && UUID_PATTERN2.test(parentSessionFilter)) && (search === null || typeof search === "string" && search.length <= 200) && (archiveMode === "active" || archiveMode === "archived") && typeof filter === "string" && filter.length <= 2048;
|
|
65251
|
+
const filtersAreValid = (parentSessionFilter === "all" || parentSessionFilter === "null" || typeof parentSessionFilter === "string" && UUID_PATTERN2.test(parentSessionFilter)) && (search === null || typeof search === "string" && search.length <= 200) && (archiveMode === "active" || archiveMode === "archived" || parsed.version === 4 && archiveMode === "all") && typeof filter === "string" && filter.length <= 2048;
|
|
65248
65252
|
if (!filtersAreValid) return null;
|
|
65249
|
-
if (parsed.version === 2 || parsed.version === 3) {
|
|
65250
|
-
|
|
65253
|
+
if (parsed.version === 2 || parsed.version === 3 || parsed.version === 4) {
|
|
65254
|
+
const sortBy = parsed.version === 4 ? parsed.sortBy : parsed.version === 3 ? "archivedAt" : "updatedAt";
|
|
65255
|
+
if (!["updatedAt", "createdAt", "name", "archivedAt"].includes(sortBy) || sortBy === "archivedAt" && archiveMode !== "archived" || typeof parsed.snapshotRevision !== "string" || typeof parsed.sortAt !== "string" || sortBy !== "name" && !isSessionListCursorTimestamp(parsed.sortAt) || sortBy === "name" && (parsed.sortAt.length > 1e4 || parsed.sortAt.includes("\0")) || typeof parsed.id !== "string" || !UUID_PATTERN2.test(parsed.id)) {
|
|
65251
65256
|
return null;
|
|
65252
65257
|
}
|
|
65253
65258
|
return {
|
|
65254
65259
|
kind: "keyset",
|
|
65255
|
-
...parsed.version
|
|
65260
|
+
...parsed.version !== 2 ? { sortBy } : {},
|
|
65256
65261
|
snapshotRevision: normalizeSessionActivityRevision(
|
|
65257
65262
|
parsed.snapshotRevision,
|
|
65258
65263
|
"cursor snapshot revision"
|
|
@@ -65265,6 +65270,7 @@ function decodeSessionListCursor(value) {
|
|
|
65265
65270
|
filter
|
|
65266
65271
|
};
|
|
65267
65272
|
}
|
|
65273
|
+
if (parsed.version !== void 0) return null;
|
|
65268
65274
|
const offset = parsed.offset;
|
|
65269
65275
|
if (typeof parsed.snapshotId !== "string" || !UUID_PATTERN2.test(parsed.snapshotId) || typeof offset !== "number" || !Number.isSafeInteger(offset) || offset < 0) {
|
|
65270
65276
|
return null;
|
|
@@ -65316,21 +65322,28 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65316
65322
|
tx,
|
|
65317
65323
|
workspaceId
|
|
65318
65324
|
);
|
|
65325
|
+
const archiveMode = options.archiveStatus ?? (options.archivedOnly ? "archived" : "active");
|
|
65326
|
+
const sortBy = options.sortBy ?? (archiveMode === "archived" ? "archivedAt" : "updatedAt");
|
|
65327
|
+
if (options.archivedOnly && archiveMode !== "archived") {
|
|
65328
|
+
throw new SessionListCursorError("archivedOnly conflicts with archiveStatus");
|
|
65329
|
+
}
|
|
65319
65330
|
const filters = [eq56(sessions.workspaceId, workspaceId), ...sessionFilters(options)];
|
|
65320
|
-
const ordinaryPinFilter =
|
|
65331
|
+
const ordinaryPinFilter = archiveMode === "archived" ? sql86`true` : or12(isNull16(sessionPins.id), eq56(sessionPins.pinned, false));
|
|
65321
65332
|
const parentFilter = sessionParentFilter(options.parentSessionId);
|
|
65322
65333
|
const searchFilter = sessionSearchFilter(options.search);
|
|
65323
|
-
const
|
|
65324
|
-
const ordinarySortAt = options.archivedOnly ? sql86`(select archive_order.archived_at
|
|
65334
|
+
const archiveSortAt = sql86`(select archive_order.archived_at
|
|
65325
65335
|
from ${sessionPins} archive_order
|
|
65326
65336
|
where archive_order.workspace_id = ${sessions.workspaceId}
|
|
65327
65337
|
and archive_order.subject_id = ${options.subjectId}
|
|
65328
65338
|
and archive_order.session_id = ${sessions.rootSessionId}
|
|
65329
|
-
and archive_order.archived = true)
|
|
65330
|
-
const
|
|
65339
|
+
and archive_order.archived = true)`;
|
|
65340
|
+
const ordinarySortAt = sortBy === "name" ? sql86`translate(btrim(coalesce(${sessions.title}, '')), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') collate "C"` : sortBy === "createdAt" ? sessions.createdAt : sortBy === "archivedAt" ? archiveSortAt : sessions.updatedAt;
|
|
65341
|
+
const exactOrdinarySortAt = sortBy === "name" ? sql86`${ordinarySortAt}` : sql86`to_char(${ordinarySortAt} at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"')`;
|
|
65342
|
+
const exactArchiveSortAt = archiveMode === "active" ? sql86`null` : sql86`to_char(${archiveSortAt} at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US"Z"')`;
|
|
65343
|
+
const ordinaryOrder = sortBy === "name" ? [asc22(ordinarySortAt), asc22(sessions.id)] : [desc22(ordinarySortAt), desc22(sessions.id)];
|
|
65331
65344
|
const listFilter = sessionListFilterIdentity(options);
|
|
65332
65345
|
const now = /* @__PURE__ */ new Date();
|
|
65333
|
-
if (options.pinsOnly &&
|
|
65346
|
+
if (options.pinsOnly && archiveMode === "archived") {
|
|
65334
65347
|
throw new SessionListCursorError(
|
|
65335
65348
|
"pins-only and archived session lists cannot be combined"
|
|
65336
65349
|
);
|
|
@@ -65338,13 +65351,14 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65338
65351
|
if (options.pinsOnly && options.cursor) {
|
|
65339
65352
|
throw new SessionListCursorError("pins-only session lists do not accept a cursor");
|
|
65340
65353
|
}
|
|
65341
|
-
if (options.cursor && options.cursor.
|
|
65354
|
+
if (options.cursor && (options.cursor.kind === "snapshot" && (sortBy !== "updatedAt" || archiveMode !== "active") || options.cursor.kind === "keyset" && (options.cursor.sortBy ?? "updatedAt") !== sortBy)) {
|
|
65342
65355
|
throw new SessionListCursorExpiredError();
|
|
65343
65356
|
}
|
|
65344
65357
|
let pageIds;
|
|
65345
65358
|
let selectedOrdinaryRows;
|
|
65346
65359
|
let nextCursor = null;
|
|
65347
65360
|
const exactArchiveTimestamps = /* @__PURE__ */ new Map();
|
|
65361
|
+
const exactOrdinaryTimestamps = /* @__PURE__ */ new Map();
|
|
65348
65362
|
if (options.pinsOnly) {
|
|
65349
65363
|
pageIds = [];
|
|
65350
65364
|
} else if (options.cursor?.kind === "snapshot") {
|
|
@@ -65420,7 +65434,8 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65420
65434
|
id: sessions.id,
|
|
65421
65435
|
session: sessions,
|
|
65422
65436
|
pin: sessionPins,
|
|
65423
|
-
sortAt: exactOrdinarySortAt
|
|
65437
|
+
sortAt: exactOrdinarySortAt,
|
|
65438
|
+
archiveAt: exactArchiveSortAt
|
|
65424
65439
|
}).from(sessions).leftJoin(
|
|
65425
65440
|
sessionPins,
|
|
65426
65441
|
and55(
|
|
@@ -65428,11 +65443,14 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65428
65443
|
eq56(sessionPins.subjectId, options.subjectId),
|
|
65429
65444
|
eq56(sessionPins.sessionId, sessions.id)
|
|
65430
65445
|
)
|
|
65431
|
-
).where(and55(...filters, ordinaryPinFilter)).orderBy(
|
|
65446
|
+
).where(and55(...filters, ordinaryPinFilter)).orderBy(...ordinaryOrder).limit(limit);
|
|
65432
65447
|
pageIds = ordinaryIdRows.map((row) => row.id);
|
|
65433
65448
|
selectedOrdinaryRows = ordinaryIdRows;
|
|
65434
|
-
if (
|
|
65435
|
-
for (const row of ordinaryIdRows)
|
|
65449
|
+
if (sortBy === "updatedAt" || sortBy === "createdAt") {
|
|
65450
|
+
for (const row of ordinaryIdRows) exactOrdinaryTimestamps.set(row.id, row.sortAt);
|
|
65451
|
+
}
|
|
65452
|
+
if (archiveMode !== "active") {
|
|
65453
|
+
for (const row of ordinaryIdRows) exactArchiveTimestamps.set(row.id, row.archiveAt);
|
|
65436
65454
|
}
|
|
65437
65455
|
} else {
|
|
65438
65456
|
const cursor = options.cursor?.kind === "keyset" ? options.cursor : void 0;
|
|
@@ -65440,7 +65458,13 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65440
65458
|
throw new SessionListCursorError("session list cursor does not match its filters");
|
|
65441
65459
|
}
|
|
65442
65460
|
const snapshotRevision = cursor ? normalizeSessionActivityRevision(cursor.snapshotRevision, "cursor snapshot revision") : await readWorkspaceSessionActivityRevision(tx, workspaceId);
|
|
65443
|
-
const cursorPredicate = cursor ? or12(
|
|
65461
|
+
const cursorPredicate = cursor ? sortBy === "name" ? or12(
|
|
65462
|
+
sql86`${ordinarySortAt} > ${cursor.sortAt}::text collate "C"`,
|
|
65463
|
+
and55(
|
|
65464
|
+
sql86`${ordinarySortAt} = ${cursor.sortAt}::text collate "C"`,
|
|
65465
|
+
gt9(sessions.id, cursor.id)
|
|
65466
|
+
)
|
|
65467
|
+
) : or12(
|
|
65444
65468
|
sql86`${ordinarySortAt} < ${cursor.sortAt}::text::timestamptz`,
|
|
65445
65469
|
and55(
|
|
65446
65470
|
sql86`${ordinarySortAt} = ${cursor.sortAt}::text::timestamptz`,
|
|
@@ -65451,7 +65475,8 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65451
65475
|
id: sessions.id,
|
|
65452
65476
|
session: sessions,
|
|
65453
65477
|
pin: sessionPins,
|
|
65454
|
-
sortAt: exactOrdinarySortAt
|
|
65478
|
+
sortAt: exactOrdinarySortAt,
|
|
65479
|
+
archiveAt: exactArchiveSortAt
|
|
65455
65480
|
}).from(sessions).leftJoin(
|
|
65456
65481
|
sessionPins,
|
|
65457
65482
|
and55(
|
|
@@ -65466,19 +65491,22 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65466
65491
|
sql86`${sessions.activityRevision} <= ${snapshotRevision}::text::bigint`,
|
|
65467
65492
|
cursorPredicate
|
|
65468
65493
|
)
|
|
65469
|
-
).orderBy(
|
|
65494
|
+
).orderBy(...ordinaryOrder).limit(limit + 1);
|
|
65470
65495
|
const hasMore = ordinaryIdRows.length > limit;
|
|
65471
65496
|
const page = ordinaryIdRows.slice(0, limit);
|
|
65472
65497
|
pageIds = page.map((row) => row.id);
|
|
65473
65498
|
selectedOrdinaryRows = page;
|
|
65474
|
-
if (
|
|
65475
|
-
for (const row of page)
|
|
65499
|
+
if (sortBy === "updatedAt" || sortBy === "createdAt") {
|
|
65500
|
+
for (const row of page) exactOrdinaryTimestamps.set(row.id, row.sortAt);
|
|
65501
|
+
}
|
|
65502
|
+
if (archiveMode !== "active") {
|
|
65503
|
+
for (const row of page) exactArchiveTimestamps.set(row.id, row.archiveAt);
|
|
65476
65504
|
}
|
|
65477
65505
|
const last = page.at(-1);
|
|
65478
65506
|
if (hasMore && last) {
|
|
65479
65507
|
nextCursor = encodeSessionListCursor({
|
|
65480
65508
|
kind: "keyset",
|
|
65481
|
-
|
|
65509
|
+
sortBy,
|
|
65482
65510
|
snapshotRevision,
|
|
65483
65511
|
sortAt: last.sortAt,
|
|
65484
65512
|
id: last.id,
|
|
@@ -65489,7 +65517,7 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65489
65517
|
});
|
|
65490
65518
|
}
|
|
65491
65519
|
}
|
|
65492
|
-
const pinnedLookaheadRows =
|
|
65520
|
+
const pinnedLookaheadRows = archiveMode === "archived" ? [] : await tx.select({ session: sessions, pin: sessionPins }).from(sessionPins).innerJoin(sessions, eq56(sessions.id, sessionPins.sessionId)).where(
|
|
65493
65521
|
and55(
|
|
65494
65522
|
eq56(sessionPins.workspaceId, workspaceId),
|
|
65495
65523
|
eq56(sessionPins.subjectId, options.subjectId),
|
|
@@ -65571,6 +65599,8 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65571
65599
|
},
|
|
65572
65600
|
{ subjectId: options.subjectId, activated: tenancyActivated }
|
|
65573
65601
|
),
|
|
65602
|
+
...sortBy === "updatedAt" && exactOrdinaryTimestamps.has(session.id) ? { updatedAt: exactOrdinaryTimestamps.get(session.id) } : {},
|
|
65603
|
+
...sortBy === "createdAt" && exactOrdinaryTimestamps.has(session.id) ? { createdAt: exactOrdinaryTimestamps.get(session.id) } : {},
|
|
65574
65604
|
treeStats: treeStats.get(session.id) ?? EMPTY_SESSION_TREE_STATS
|
|
65575
65605
|
},
|
|
65576
65606
|
requiresActionSince
|
|
@@ -65582,7 +65612,9 @@ async function listSessionsForSubject(db, workspaceId, options) {
|
|
|
65582
65612
|
pinned: pinnedRows.map(mapListSession),
|
|
65583
65613
|
pinnedTruncated,
|
|
65584
65614
|
sessions: pageRows.map(mapListSession),
|
|
65585
|
-
nextCursor
|
|
65615
|
+
nextCursor,
|
|
65616
|
+
sortBy,
|
|
65617
|
+
archiveStatus: archiveMode
|
|
65586
65618
|
};
|
|
65587
65619
|
},
|
|
65588
65620
|
{ isolationLevel: "read committed" }
|