@opengeni/db 0.31.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-auth.d.ts +209 -1
- package/dist/browser-downloads.d.ts +51 -0
- package/dist/browser-identities.d.ts +11 -2
- package/dist/browser-sessions.d.ts +83 -1
- package/dist/browser-state-artifacts.d.ts +75 -1
- package/dist/canonical-human-identities.d.ts +48 -0
- package/dist/canonical-human-identities.js +28 -0
- package/dist/canonical-human-identities.js.map +1 -0
- package/dist/capability-integrations.d.ts +8 -6
- package/dist/{chunk-MWDVXQOL.js → chunk-5KTIEDX7.js} +5773 -4212
- package/dist/chunk-5KTIEDX7.js.map +1 -0
- package/dist/{chunk-NBE6CHRI.js → chunk-CQZ4QSP5.js} +49 -9
- package/dist/chunk-CQZ4QSP5.js.map +1 -0
- package/dist/chunk-F32YT7MP.js +117 -0
- package/dist/chunk-F32YT7MP.js.map +1 -0
- package/dist/{chunk-ISI2TIUG.js → chunk-JC5QPLUM.js} +30 -3
- package/dist/chunk-JC5QPLUM.js.map +1 -0
- package/dist/{chunk-F5FT7BEZ.js → chunk-P3RE4D2B.js} +2 -2
- package/dist/chunk-TAUTWOS5.js +259 -0
- package/dist/chunk-TAUTWOS5.js.map +1 -0
- package/dist/{chunk-YHZXQ7HP.js → chunk-VKLB2ZGI.js} +446 -19
- package/dist/chunk-VKLB2ZGI.js.map +1 -0
- package/dist/database.d.ts +5 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +438 -29
- package/dist/index.js +35640 -28969
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +23 -7
- package/dist/integration-bindings.d.ts +24 -24
- package/dist/integration-facets.d.ts +99 -0
- package/dist/interaction-revisions.d.ts +11 -0
- package/dist/interaction-schema.d.ts +698 -34
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +8 -7
- package/dist/schema.d.ts +9464 -5412
- package/dist/schema.js +51 -9
- package/dist/session-control.d.ts +29 -3
- package/dist/session-tenancy.d.ts +44 -0
- package/dist/session-tenancy.js +16 -0
- package/dist/session-tenancy.js.map +1 -0
- package/dist/slack-task-policy-schema.d.ts +847 -0
- package/dist/slack-task-policy.d.ts +65 -0
- package/dist/task-notes-schema.d.ts +924 -0
- package/dist/task-notes.d.ts +85 -0
- package/dist/video-generation.d.ts +9 -0
- package/dist/video-generation.js +5 -3
- package/dist/xai-subscription.d.ts +326 -0
- package/drizzle/0212_browser_state_transfer_hardening.sql +560 -0
- package/drizzle/0213_browser_interaction_authority.sql +67 -0
- package/drizzle/0214_browser_download_saves.sql +34 -0
- package/drizzle/0215_browser_controller_host.sql +385 -0
- package/drizzle/0216_browser_auth_health_evidence.sql +137 -0
- package/drizzle/0217_external_browser_auth_operations.sql +22 -0
- package/drizzle/0218_organization_tenancy_foundation.sql +299 -0
- package/drizzle/0219_organization_tenancy_managed_human_provisioning.sql +317 -0
- package/drizzle/0219_site_auth_maintenance_sessions.sql +234 -0
- package/drizzle/0220_memory_slack_append_only_cascade.sql +38 -0
- package/drizzle/0220_session_channels.sql +54 -0
- package/drizzle/0221_sessions_channel_index.sql +5 -0
- package/drizzle/0222_session_visibility_authority_epochs.sql +158 -0
- package/drizzle/0222_sessions_channel_fk.sql +89 -0
- package/drizzle/0223_pending_tool_event_output.sql +55 -0
- package/drizzle/0223_sessions_channel_fk_validate.sql +118 -0
- package/drizzle/0224_slack_post_outcome_reconciliation.sql +123 -0
- package/drizzle/0225_session_visibility_fork_activation.sql +1363 -0
- package/drizzle/0226_personal_codex_authority_foundation.sql +365 -0
- package/drizzle/0227_slack_native_actions.sql +145 -0
- package/drizzle/0228_interaction_controller_data_plane.sql +14 -0
- package/drizzle/0228_slack_task_policy.sql +400 -0
- package/drizzle/0229_slack_inbox_file_fact.sql +10 -0
- package/drizzle/0230_user_scoped_variable_sets_rigs.sql +84 -0
- package/drizzle/0231_integration_definition_identity_cutover.sql +271 -0
- package/drizzle/0232_integration_facet_authority_cutover.sql +610 -0
- package/drizzle/0233_skill_and_integration_authority_cutover.sql +1162 -0
- package/drizzle/0234_xai_subscription_authority.sql +1139 -0
- package/drizzle/0235_canonical_human_login_bindings.sql +920 -0
- package/drizzle/0236_browser_identity_lifecycle.sql +39 -0
- package/drizzle/0236_session_visibility_slack_policy.sql +72 -0
- package/drizzle/0237_interaction_transition_reaper.sql +263 -0
- package/drizzle/0238_goal_persistence_policy.sql +471 -0
- package/drizzle/0238_supergrok_realtime_model.sql +29 -0
- package/drizzle/0239_supergrok_video_funding.sql +50 -0
- package/drizzle/0239_task_tree_notes.sql +990 -0
- package/package.json +13 -5
- package/src/browser-auth.ts +2600 -123
- package/src/browser-downloads.ts +517 -0
- package/src/browser-identities.ts +220 -3
- package/src/browser-sessions.ts +334 -45
- package/src/browser-state-artifacts.ts +402 -12
- package/src/canonical-human-identities.ts +317 -0
- package/src/capability-integrations.ts +121 -213
- package/src/database.ts +41 -1
- package/src/index.ts +4157 -394
- package/src/insights.ts +109 -28
- package/src/integration-bindings.ts +101 -101
- package/src/{integration-features.ts → integration-facets.ts} +187 -184
- package/src/interaction-revisions.ts +33 -3
- package/src/interaction-schema.ts +311 -8
- package/src/pack-components.ts +43 -43
- package/src/pack-installations.ts +0 -43
- package/src/plugin-packages.ts +9 -9
- package/src/provision-roles.ts +232 -0
- package/src/runtime-posture.ts +227 -14
- package/src/schema.ts +1188 -75
- package/src/session-control.ts +122 -37
- package/src/session-queue-commands.ts +78 -1
- package/src/session-tenancy.ts +188 -0
- package/src/session-tool-call-settlement.ts +9 -3
- package/src/slack-task-policy-schema.ts +130 -0
- package/src/slack-task-policy.ts +341 -0
- package/src/task-notes-schema.ts +135 -0
- package/src/task-notes.ts +178 -0
- package/src/video-generation.ts +90 -12
- package/src/workspace-artifacts.ts +1 -1
- package/src/xai-subscription.ts +1887 -0
- package/dist/chunk-ISI2TIUG.js.map +0 -1
- package/dist/chunk-MWDVXQOL.js.map +0 -1
- package/dist/chunk-NBE6CHRI.js.map +0 -1
- package/dist/chunk-YHZXQ7HP.js.map +0 -1
- package/dist/integration-features.d.ts +0 -99
- /package/dist/{chunk-F5FT7BEZ.js.map → chunk-P3RE4D2B.js.map} +0 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
BrowserSessionCapabilities,
|
|
10
10
|
InteractionError,
|
|
11
11
|
PublishBrowserRevisionResponse,
|
|
12
|
+
UpdateBrowserIdentityRequest,
|
|
12
13
|
type BrowserIdentity as BrowserIdentityValue,
|
|
13
14
|
type BrowserIdentityListResponse as BrowserIdentityListResponseValue,
|
|
14
15
|
type BrowserIdentityMutationResponse as BrowserIdentityMutationResponseValue,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
type BrowserRevisionMaterialization as BrowserRevisionMaterializationValue,
|
|
18
19
|
type InteractionError as InteractionErrorValue,
|
|
19
20
|
type PublishBrowserRevisionResponse as PublishBrowserRevisionResponseValue,
|
|
21
|
+
type UpdateBrowserIdentityRequest as UpdateBrowserIdentityRequestValue,
|
|
20
22
|
} from "@opengeni/contracts";
|
|
21
23
|
import { and, asc, desc, eq, inArray, sql } from "drizzle-orm";
|
|
22
24
|
import { type Database, withRlsContext } from "./database";
|
|
@@ -26,6 +28,9 @@ import {
|
|
|
26
28
|
} from "./interaction-revisions";
|
|
27
29
|
import { safeDatabaseErrorFacts } from "./persistence-errors";
|
|
28
30
|
import {
|
|
31
|
+
commitBrowserStateUploadInTransaction,
|
|
32
|
+
markBrowserStateUploadsDeletePendingInTransaction,
|
|
33
|
+
prepareBrowserStateUploadInTransaction,
|
|
29
34
|
validateBrowserStateArtifactCommitInput,
|
|
30
35
|
type BrowserStateArtifactCommitInput,
|
|
31
36
|
} from "./browser-state-artifacts";
|
|
@@ -37,6 +42,7 @@ type BrowserRevisionComponentRow = typeof schema.browserRevisionComponents.$infe
|
|
|
37
42
|
type BrowserStateArtifactRow = typeof schema.browserStateArtifacts.$inferSelect;
|
|
38
43
|
type BrowserSessionRow = typeof schema.browserSessions.$inferSelect;
|
|
39
44
|
type InteractionOperationRow = typeof schema.interactionOperations.$inferSelect;
|
|
45
|
+
type InteractionResourceOperationRow = typeof schema.interactionResourceOperations.$inferSelect;
|
|
40
46
|
|
|
41
47
|
const SHA256_PATTERN = /^[0-9a-f]{64}$/u;
|
|
42
48
|
const MAX_COMPONENTS = 16;
|
|
@@ -57,8 +63,6 @@ export class BrowserIdentityStateError extends Error {
|
|
|
57
63
|
readonly name = "BrowserIdentityStateError";
|
|
58
64
|
}
|
|
59
65
|
|
|
60
|
-
export type { BrowserStateArtifactCommitInput } from "./browser-state-artifacts";
|
|
61
|
-
|
|
62
66
|
export type BrowserRevisionPublicationPreparation =
|
|
63
67
|
| {
|
|
64
68
|
kind: "completed";
|
|
@@ -117,6 +121,7 @@ function identityFromRow(row: BrowserIdentityRow): BrowserIdentityValue {
|
|
|
117
121
|
workspaceId: row.workspaceId,
|
|
118
122
|
name: row.name,
|
|
119
123
|
status: row.status,
|
|
124
|
+
version: safeInteger(row.version, "BrowserIdentity version"),
|
|
120
125
|
defaultRevisionId: row.defaultRevisionId,
|
|
121
126
|
headGeneration: safeInteger(row.headGeneration, "BrowserIdentity head generation"),
|
|
122
127
|
revisionCount: safeInteger(row.revisionCount, "BrowserIdentity revision count"),
|
|
@@ -393,6 +398,160 @@ export async function createBrowserIdentity(
|
|
|
393
398
|
});
|
|
394
399
|
}
|
|
395
400
|
|
|
401
|
+
export async function updateBrowserIdentity(
|
|
402
|
+
db: Database,
|
|
403
|
+
input: {
|
|
404
|
+
accountId: string;
|
|
405
|
+
workspaceId: string;
|
|
406
|
+
identityId: string;
|
|
407
|
+
actorSubjectId: string;
|
|
408
|
+
} & UpdateBrowserIdentityRequestValue,
|
|
409
|
+
): Promise<BrowserIdentityMutationResponseValue> {
|
|
410
|
+
const request = UpdateBrowserIdentityRequest.parse({
|
|
411
|
+
operationId: input.operationId,
|
|
412
|
+
expectedVersion: input.expectedVersion,
|
|
413
|
+
...(input.name !== undefined ? { name: input.name } : {}),
|
|
414
|
+
...(input.status !== undefined ? { status: input.status } : {}),
|
|
415
|
+
...(input.defaultRevisionId !== undefined
|
|
416
|
+
? { defaultRevisionId: input.defaultRevisionId }
|
|
417
|
+
: {}),
|
|
418
|
+
});
|
|
419
|
+
const { operationId: _operationId, ...digestRequest } = request;
|
|
420
|
+
const requestDigest = createHash("sha256")
|
|
421
|
+
.update(
|
|
422
|
+
JSON.stringify({
|
|
423
|
+
version: 1,
|
|
424
|
+
identityId: input.identityId,
|
|
425
|
+
request: digestRequest,
|
|
426
|
+
actorSubjectId: input.actorSubjectId,
|
|
427
|
+
}),
|
|
428
|
+
)
|
|
429
|
+
.digest("hex");
|
|
430
|
+
|
|
431
|
+
try {
|
|
432
|
+
return await withRlsContext(
|
|
433
|
+
db,
|
|
434
|
+
input,
|
|
435
|
+
async (scopedDb) =>
|
|
436
|
+
await scopedDb.transaction(async (txRaw) => {
|
|
437
|
+
const tx = txRaw as unknown as Database;
|
|
438
|
+
await lockBrowserIdentityMutationOperation(tx, request.operationId);
|
|
439
|
+
const existing = await loadBrowserIdentityMutationOperation(
|
|
440
|
+
tx,
|
|
441
|
+
input.workspaceId,
|
|
442
|
+
request.operationId,
|
|
443
|
+
);
|
|
444
|
+
if (existing) {
|
|
445
|
+
if (
|
|
446
|
+
existing.resourceKind !== "browser_identity" ||
|
|
447
|
+
existing.resourceId !== input.identityId ||
|
|
448
|
+
existing.kind !== "update" ||
|
|
449
|
+
existing.requestDigest !== requestDigest ||
|
|
450
|
+
existing.actorSubjectId !== input.actorSubjectId
|
|
451
|
+
) {
|
|
452
|
+
throw new BrowserIdentityConflictError(
|
|
453
|
+
"Operation id is already bound to another browser identity request",
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
if (existing.state !== "completed" || !existing.result || !existing.resultVersion) {
|
|
457
|
+
throw new BrowserIdentityStateError("Browser identity operation is not complete");
|
|
458
|
+
}
|
|
459
|
+
const response = BrowserIdentityMutationResponse.parse(existing.result);
|
|
460
|
+
return { ...response, replayed: true };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
await lockBrowserIdentity(tx, input.workspaceId, input.identityId);
|
|
464
|
+
const current = await loadIdentity(tx, input.workspaceId, input.identityId);
|
|
465
|
+
if (!current) throw new BrowserIdentityNotFoundError("BrowserIdentity not found");
|
|
466
|
+
if (current.version !== request.expectedVersion) {
|
|
467
|
+
throw new BrowserIdentityConflictError("BrowserIdentity changed before this update");
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
let defaultRevisionChanged = false;
|
|
471
|
+
if (request.defaultRevisionId !== undefined) {
|
|
472
|
+
if ((request.status ?? current.status) !== "active") {
|
|
473
|
+
throw new BrowserIdentityStateError(
|
|
474
|
+
"An archived browser profile cannot select a default version",
|
|
475
|
+
);
|
|
476
|
+
}
|
|
477
|
+
const [revision] = await tx
|
|
478
|
+
.select({ id: schema.browserRevisions.id })
|
|
479
|
+
.from(schema.browserRevisions)
|
|
480
|
+
.where(
|
|
481
|
+
and(
|
|
482
|
+
eq(schema.browserRevisions.workspaceId, input.workspaceId),
|
|
483
|
+
eq(schema.browserRevisions.identityId, input.identityId),
|
|
484
|
+
eq(schema.browserRevisions.id, request.defaultRevisionId),
|
|
485
|
+
),
|
|
486
|
+
)
|
|
487
|
+
.limit(1);
|
|
488
|
+
if (!revision) {
|
|
489
|
+
throw new BrowserIdentityStateError(
|
|
490
|
+
"Default browser version does not belong to this profile",
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
defaultRevisionChanged = request.defaultRevisionId !== current.defaultRevisionId;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const now = new Date();
|
|
497
|
+
const [row] = await tx
|
|
498
|
+
.update(schema.browserIdentities)
|
|
499
|
+
.set({
|
|
500
|
+
name: request.name ?? current.name,
|
|
501
|
+
status: request.status ?? current.status,
|
|
502
|
+
...(defaultRevisionChanged
|
|
503
|
+
? {
|
|
504
|
+
defaultRevisionId: request.defaultRevisionId,
|
|
505
|
+
headGeneration: safeInteger(
|
|
506
|
+
current.headGeneration + 1,
|
|
507
|
+
"next BrowserIdentity head generation",
|
|
508
|
+
),
|
|
509
|
+
}
|
|
510
|
+
: {}),
|
|
511
|
+
version: safeInteger(current.version + 1, "next BrowserIdentity version"),
|
|
512
|
+
updatedAt: now,
|
|
513
|
+
})
|
|
514
|
+
.where(
|
|
515
|
+
and(
|
|
516
|
+
eq(schema.browserIdentities.workspaceId, input.workspaceId),
|
|
517
|
+
eq(schema.browserIdentities.id, input.identityId),
|
|
518
|
+
eq(schema.browserIdentities.version, request.expectedVersion),
|
|
519
|
+
),
|
|
520
|
+
)
|
|
521
|
+
.returning();
|
|
522
|
+
if (!row) throw new BrowserIdentityConflictError("BrowserIdentity update lost its fence");
|
|
523
|
+
|
|
524
|
+
const response = BrowserIdentityMutationResponse.parse({
|
|
525
|
+
identity: identityFromRow(row),
|
|
526
|
+
operationId: request.operationId,
|
|
527
|
+
replayed: false,
|
|
528
|
+
});
|
|
529
|
+
await tx.insert(schema.interactionResourceOperations).values({
|
|
530
|
+
operationId: request.operationId,
|
|
531
|
+
accountId: input.accountId,
|
|
532
|
+
workspaceId: input.workspaceId,
|
|
533
|
+
resourceKind: "browser_identity",
|
|
534
|
+
resourceId: input.identityId,
|
|
535
|
+
kind: "update",
|
|
536
|
+
requestDigest,
|
|
537
|
+
resultVersion: row.version,
|
|
538
|
+
result: response,
|
|
539
|
+
actorSubjectId: input.actorSubjectId,
|
|
540
|
+
state: "completed",
|
|
541
|
+
settledAt: now,
|
|
542
|
+
});
|
|
543
|
+
await advanceWorkspaceInteractionRevision(tx, input.accountId, input.workspaceId);
|
|
544
|
+
return response;
|
|
545
|
+
}),
|
|
546
|
+
);
|
|
547
|
+
} catch (error) {
|
|
548
|
+
if (postgresConstraint(error) === "browser_identities_workspace_active_name_uq") {
|
|
549
|
+
throw new BrowserIdentityConflictError("An active browser profile already uses this name");
|
|
550
|
+
}
|
|
551
|
+
throw error;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
396
555
|
export function browserRevisionPublicationRequestDigest(input: {
|
|
397
556
|
browserSessionId: string;
|
|
398
557
|
identityId: string;
|
|
@@ -572,6 +731,7 @@ export async function dispatchBrowserRevisionPublication(
|
|
|
572
731
|
expectedHeadGeneration: number;
|
|
573
732
|
advanceDefault: boolean;
|
|
574
733
|
actorSubjectId: string;
|
|
734
|
+
stateUpload?: { objectKey: string; cleanupAfter: Date };
|
|
575
735
|
},
|
|
576
736
|
): Promise<BrowserRevisionPublicationDispatch> {
|
|
577
737
|
const digest = browserRevisionPublicationRequestDigest(input);
|
|
@@ -634,6 +794,16 @@ export async function dispatchBrowserRevisionPublication(
|
|
|
634
794
|
"Publication belongs to another controller generation",
|
|
635
795
|
);
|
|
636
796
|
}
|
|
797
|
+
if (input.stateUpload) {
|
|
798
|
+
await prepareBrowserStateUploadInTransaction(tx, {
|
|
799
|
+
accountId: input.accountId,
|
|
800
|
+
workspaceId: input.workspaceId,
|
|
801
|
+
operationId: input.operationId,
|
|
802
|
+
sourceBrowserSessionId: input.browserSessionId,
|
|
803
|
+
purpose: "revision_component",
|
|
804
|
+
...input.stateUpload,
|
|
805
|
+
});
|
|
806
|
+
}
|
|
637
807
|
return {
|
|
638
808
|
kind: "dispatched",
|
|
639
809
|
browserSessionId: input.browserSessionId,
|
|
@@ -642,6 +812,16 @@ export async function dispatchBrowserRevisionPublication(
|
|
|
642
812
|
};
|
|
643
813
|
}
|
|
644
814
|
|
|
815
|
+
if (input.stateUpload) {
|
|
816
|
+
await prepareBrowserStateUploadInTransaction(tx, {
|
|
817
|
+
accountId: input.accountId,
|
|
818
|
+
workspaceId: input.workspaceId,
|
|
819
|
+
operationId: input.operationId,
|
|
820
|
+
sourceBrowserSessionId: input.browserSessionId,
|
|
821
|
+
purpose: "revision_component",
|
|
822
|
+
...input.stateUpload,
|
|
823
|
+
});
|
|
824
|
+
}
|
|
645
825
|
const now = new Date();
|
|
646
826
|
const [updated] = await tx
|
|
647
827
|
.update(schema.interactionOperations)
|
|
@@ -781,6 +961,14 @@ export async function commitBrowserRevisionPublication(
|
|
|
781
961
|
})
|
|
782
962
|
.returning();
|
|
783
963
|
if (!row) throw new Error("Browser state artifact insert was lost");
|
|
964
|
+
await commitBrowserStateUploadInTransaction(tx, {
|
|
965
|
+
workspaceId: input.workspaceId,
|
|
966
|
+
operationId: input.operationId,
|
|
967
|
+
sourceBrowserSessionId: input.browserSessionId,
|
|
968
|
+
purpose: "revision_component",
|
|
969
|
+
objectKey: artifact.objectKey,
|
|
970
|
+
artifactId: row.id,
|
|
971
|
+
});
|
|
784
972
|
artifactRows.push(row);
|
|
785
973
|
}
|
|
786
974
|
|
|
@@ -832,6 +1020,7 @@ export async function commitBrowserRevisionPublication(
|
|
|
832
1020
|
.update(schema.browserIdentities)
|
|
833
1021
|
.set({
|
|
834
1022
|
revisionCount: ordinal,
|
|
1023
|
+
version: safeInteger(identity.version + 1, "next BrowserIdentity version"),
|
|
835
1024
|
...(defaultAdvanced
|
|
836
1025
|
? { defaultRevisionId: revisionId, headGeneration: resultHeadGeneration }
|
|
837
1026
|
: {}),
|
|
@@ -980,6 +1169,7 @@ export async function failBrowserRevisionPublication(
|
|
|
980
1169
|
)
|
|
981
1170
|
.returning({ operationId: schema.interactionOperations.operationId });
|
|
982
1171
|
if (!settled) throw new Error("BrowserRevision publication failure settlement was lost");
|
|
1172
|
+
await markBrowserStateUploadsDeletePendingInTransaction(tx, input);
|
|
983
1173
|
}),
|
|
984
1174
|
);
|
|
985
1175
|
}
|
|
@@ -1041,7 +1231,7 @@ async function loadBrowserRevisionArtifactAuthority(
|
|
|
1041
1231
|
revision,
|
|
1042
1232
|
artifacts: components.map((component) => {
|
|
1043
1233
|
const artifact = byArtifact.get(component.artifactId);
|
|
1044
|
-
if (!artifact || artifact.state !== "available") {
|
|
1234
|
+
if (!artifact || artifact.state !== "available" || artifact.encryptedDataKey === null) {
|
|
1045
1235
|
throw new BrowserIdentityStateError("BrowserRevision artifact is unavailable");
|
|
1046
1236
|
}
|
|
1047
1237
|
return {
|
|
@@ -1147,6 +1337,33 @@ async function lockBrowserIdentity(db: Database, workspaceId: string, identityId
|
|
|
1147
1337
|
`);
|
|
1148
1338
|
}
|
|
1149
1339
|
|
|
1340
|
+
async function lockBrowserIdentityMutationOperation(
|
|
1341
|
+
db: Database,
|
|
1342
|
+
operationId: string,
|
|
1343
|
+
): Promise<void> {
|
|
1344
|
+
await db.execute(
|
|
1345
|
+
sql`select pg_advisory_xact_lock(hashtextextended(${`interaction-resource:${operationId}`}, 0))`,
|
|
1346
|
+
);
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
async function loadBrowserIdentityMutationOperation(
|
|
1350
|
+
db: Database,
|
|
1351
|
+
workspaceId: string,
|
|
1352
|
+
operationId: string,
|
|
1353
|
+
): Promise<InteractionResourceOperationRow | null> {
|
|
1354
|
+
const [row] = await db
|
|
1355
|
+
.select()
|
|
1356
|
+
.from(schema.interactionResourceOperations)
|
|
1357
|
+
.where(
|
|
1358
|
+
and(
|
|
1359
|
+
eq(schema.interactionResourceOperations.workspaceId, workspaceId),
|
|
1360
|
+
eq(schema.interactionResourceOperations.operationId, operationId),
|
|
1361
|
+
),
|
|
1362
|
+
)
|
|
1363
|
+
.limit(1);
|
|
1364
|
+
return row ?? null;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1150
1367
|
async function lockBrowserSession(db: Database, workspaceId: string, browserSessionId: string) {
|
|
1151
1368
|
await db.execute(sql`
|
|
1152
1369
|
select id from browser_sessions
|