@powerhousedao/reactor-attachments 6.2.3-dev.50 → 6.2.3-dev.52

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 CHANGED
@@ -1,7 +1,9 @@
1
- import { $ as AttachmentMetadataField, A as IReservationStore, B as AttachmentStatOptions, C as IAttachmentReader, D as IAttachmentTransportFactory, E as IAttachmentTransport, F as AttachmentDownloadTargetOptions, G as AttachmentUploadTarget, H as AttachmentTargetHeaders, I as AttachmentHeader, J as ReserveAttachmentOptions, K as HashFirstReserveAttachmentOptions, L as AttachmentMetadata, M as AttachmentBackendKind, N as AttachmentDownloadOptions, O as IAttachmentUpload, P as AttachmentDownloadTarget, Q as AttachmentAlreadyExists, R as AttachmentResponse, S as IAttachmentBackend, T as IAttachmentStore, U as AttachmentTransportConfig, V as AttachmentStatus, W as AttachmentUploadResult, X as TransportResponse, Y as TransportFetchResult, Z as UploadFirstReserveAttachmentOptions, _ as createRef, a as RemoteAttachmentUpload, at as InvalidAttachmentMetadata, b as parseAttachmentDownloadTarget, c as XhrUploadTransportOptions, ct as SizeMismatch, d as AttachmentUploadResponse, et as AttachmentNotFound, f as AttachmentUploadTransport, g as ParsedRef, h as SwitchboardTransportConfig, i as RemoteAttachmentUploadFactory, it as HashMismatch, j as AttachmentBackendHealth, k as IAttachmentUploadFactory, l as createXhrUploadTransport, lt as UploadTooLarge, m as SwitchboardAttachmentTransport, n as createRemoteAttachmentService, nt as AttachmentTransferError, o as RemoteReservationStore, ot as InvalidAttachmentRef, p as createFetchUploadTransport, q as Reservation, r as RemoteAttachmentStore, rt as AttachmentTransferStage, s as SwitchboardClientConfig, st as ReservationNotFound, t as NullAttachmentTransport, tt as AttachmentPending, u as AttachmentUploadRequest, v as parseRef, w as IAttachmentService, x as parseAttachmentUploadTarget, y as AttachmentService, z as AttachmentSendOptions } from "./null-attachment-transport-jZmzFncu.js";
1
+ import { A as InvalidAttachmentRef, C as AttachmentMetadataField, D as AttachmentTransferStage, E as AttachmentTransferError, M as SizeMismatch, N as UploadTooLarge, O as HashMismatch, S as AttachmentAlreadyExists, T as AttachmentPending, _ as createRef, a as RemoteAttachmentUpload, b as parseAttachmentDownloadTarget, c as XhrUploadTransportOptions, d as AttachmentUploadResponse, f as AttachmentUploadTransport, g as ParsedRef, h as SwitchboardTransportConfig, i as RemoteAttachmentUploadFactory, j as ReservationNotFound, k as InvalidAttachmentMetadata, l as createXhrUploadTransport, m as SwitchboardAttachmentTransport, n as createRemoteAttachmentService, o as RemoteReservationStore, p as createFetchUploadTransport, r as RemoteAttachmentStore, s as SwitchboardClientConfig, t as NullAttachmentTransport, u as AttachmentUploadRequest, v as parseRef, w as AttachmentNotFound, x as parseAttachmentUploadTarget, y as AttachmentService } from "./null-attachment-transport-dg7vi6F4.js";
2
+ import { A as UploadFirstReserveAttachmentOptions, C as AttachmentUploadResult, D as ReserveAttachmentOptions, E as Reservation, O as TransportFetchResult, S as AttachmentTransportConfig, T as HashFirstReserveAttachmentOptions, _ as AttachmentResponse, a as IAttachmentTransport, b as AttachmentStatus, c as IAttachmentUploadFactory, d as AttachmentBackendKind, f as AttachmentDownloadOptions, g as AttachmentMetadata, h as AttachmentHeader, i as IAttachmentStore, k as TransportResponse, l as IReservationStore, m as AttachmentDownloadTargetOptions, n as IAttachmentReader, o as IAttachmentTransportFactory, p as AttachmentDownloadTarget, r as IAttachmentService, s as IAttachmentUpload, t as IAttachmentBackend, u as AttachmentBackendHealth, v as AttachmentSendOptions, w as AttachmentUploadTarget, x as AttachmentTargetHeaders, y as AttachmentStatOptions } from "./interfaces-jHW9JXv1.js";
3
+ import { a as IAttachmentReferenceScanner, c as IAttachmentSchemaCompiler, i as IAttachmentReferenceReader, n as AttachmentReferencePageResult, o as IAttachmentReferenceWriter, s as CompiledAttachmentExtractor, t as AttachmentReferenceInput } from "./types-AagIcjTD.js";
2
4
  import { Kysely } from "kysely";
3
5
  import { AttachmentHash, AttachmentRef, BaseReadModel, DocumentViewDatabase, IConsistencyTracker, IDocumentModelRegistry, IOperationIndex, IWriteCache } from "@powerhousedao/reactor";
4
- import { Action, DocumentModelModule, OperationWithContext } from "@powerhousedao/shared/document-model";
6
+ import { DocumentModelModule, OperationWithContext } from "@powerhousedao/shared/document-model";
5
7
  //#region src/reserve-metadata.d.ts
6
8
  /** The descriptive fields of a reservation, as a caller supplies them. */
7
9
  type ReserveMetadata = {
@@ -169,40 +171,12 @@ export declare class AttachmentBuilder {
169
171
  build(): Promise<AttachmentBuildResult>;
170
172
  }
171
173
  //#endregion
172
- //#region src/reference-index/types.d.ts
173
- interface CompiledAttachmentExtractor {
174
- extract(action: Action): AttachmentRef[];
175
- }
176
- interface IAttachmentSchemaCompiler {
177
- forModuleAction(module: DocumentModelModule, actionType: string): CompiledAttachmentExtractor;
178
- }
179
- //#endregion
180
174
  //#region src/reference-index/attachment-schema-compiler.d.ts
181
175
  export declare class AttachmentSchemaCompiler implements IAttachmentSchemaCompiler {
182
176
  private readonly cache;
183
177
  forModuleAction(module: DocumentModelModule, actionType: string): CompiledAttachmentExtractor;
184
178
  }
185
179
  //#endregion
186
- //#region src/read-models/attachment-reference/types.d.ts
187
- interface AttachmentReferenceInput {
188
- documentId: string;
189
- ref: AttachmentRef;
190
- operationId: string;
191
- branch: string;
192
- scope: string;
193
- ordinal: number;
194
- }
195
- interface IAttachmentReferenceReader {
196
- hasReference(documentId: string, ref: AttachmentRef): Promise<boolean>;
197
- /** The scopes whose operations reference the attachment; empty when none. */
198
- referencingScopes(documentId: string, ref: AttachmentRef): Promise<string[]>;
199
- }
200
- interface IAttachmentReferenceWriter {
201
- addReferences(references: readonly AttachmentReferenceInput[]): Promise<void>;
202
- /** Deletes every reference of the documents; for a purged document. */
203
- removeDocuments(documentIds: readonly string[]): Promise<void>;
204
- }
205
- //#endregion
206
180
  //#region src/read-models/attachment-reference/index-builder.d.ts
207
181
  type AttachmentReferenceIndexBuildResult = {
208
182
  store: IAttachmentReferenceReader & IAttachmentReferenceWriter;
@@ -249,11 +223,18 @@ interface AttachmentReferenceDatabase {
249
223
  }
250
224
  //#endregion
251
225
  //#region src/read-models/attachment-reference/kysely-attachment-reference-store.d.ts
252
- export declare class KyselyAttachmentReferenceStore implements IAttachmentReferenceReader, IAttachmentReferenceWriter {
226
+ export declare class KyselyAttachmentReferenceStore implements IAttachmentReferenceReader, IAttachmentReferenceScanner, IAttachmentReferenceWriter {
253
227
  private readonly db;
254
228
  constructor(db: Kysely<AttachmentReferenceDatabase>);
255
229
  hasReference(documentId: string, ref: AttachmentRef): Promise<boolean>;
256
230
  referencingScopes(documentId: string, ref: AttachmentRef): Promise<string[]>;
231
+ /**
232
+ * Keyset paging over the unique `(document_id, attachment_ref)` constraint,
233
+ * rather than OFFSET: a scan that runs while the read model is still
234
+ * indexing must not skip or repeat a row because rows appeared behind the
235
+ * cursor. That is exactly the boot case the replicator's re-scan runs in.
236
+ */
237
+ listReferences(cursor: string | undefined, limit: number): Promise<AttachmentReferencePageResult>;
257
238
  addReferences(references: readonly AttachmentReferenceInput[]): Promise<void>;
258
239
  removeDocuments(documentIds: readonly string[]): Promise<void>;
259
240
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/reserve-metadata.ts","../src/storage/kysely/types.ts","../src/storage/kysely/attachment-store.ts","../src/storage/kysely/reservation-store.ts","../src/storage/migrations/migrator.ts","../src/direct/direct-attachment-upload.ts","../src/direct/direct-attachment-upload-factory.ts","../src/direct/filesystem-attachment-backend.ts","../src/attachment-builder.ts","../src/reference-index/types.ts","../src/reference-index/attachment-schema-compiler.ts","../src/read-models/attachment-reference/types.ts","../src/read-models/attachment-reference/index-builder.ts","../src/read-models/attachment-reference/attachment-reference-read-model.ts","../src/read-models/attachment-reference/storage/types.ts","../src/read-models/attachment-reference/kysely-attachment-reference-store.ts","../src/read-models/attachment-reference/storage/migrations/migrator.ts","../src/storage/s3/config.ts","../src/storage/s3/keying.ts","../src/storage/s3/primitives.ts","../src/storage/s3/backend.ts","../src/storage/s3/upload-factory.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/reserve-metadata.ts","../src/storage/kysely/types.ts","../src/storage/kysely/attachment-store.ts","../src/storage/kysely/reservation-store.ts","../src/storage/migrations/migrator.ts","../src/direct/direct-attachment-upload.ts","../src/direct/direct-attachment-upload-factory.ts","../src/direct/filesystem-attachment-backend.ts","../src/attachment-builder.ts","../src/reference-index/attachment-schema-compiler.ts","../src/read-models/attachment-reference/index-builder.ts","../src/read-models/attachment-reference/attachment-reference-read-model.ts","../src/read-models/attachment-reference/storage/types.ts","../src/read-models/attachment-reference/kysely-attachment-reference-store.ts","../src/read-models/attachment-reference/storage/migrations/migrator.ts","../src/storage/s3/config.ts","../src/storage/s3/keying.ts","../src/storage/s3/primitives.ts","../src/storage/s3/backend.ts","../src/storage/s3/upload-factory.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
- import { C as SizeMismatch, S as ReservationNotFound, _ as AttachmentPending, a as RemoteAttachmentUpload, b as InvalidAttachmentMetadata, c as createFetchUploadTransport, d as createRef, f as parseRef, g as AttachmentNotFound, h as AttachmentAlreadyExists, i as RemoteAttachmentUploadFactory, l as SwitchboardAttachmentTransport, m as parseAttachmentUploadTarget, n as createRemoteAttachmentService, o as RemoteReservationStore, p as parseAttachmentDownloadTarget, r as RemoteAttachmentStore, s as createXhrUploadTransport, t as NullAttachmentTransport, u as AttachmentService, v as AttachmentTransferError, w as UploadTooLarge, x as InvalidAttachmentRef, y as HashMismatch } from "./null-attachment-transport-CUDNBfd5.js";
1
+ import { a as parseRef, c as AttachmentPending, d as InvalidAttachmentMetadata, f as InvalidAttachmentRef, h as UploadTooLarge, i as createRef, l as AttachmentTransferError, m as SizeMismatch, o as AttachmentAlreadyExists, p as ReservationNotFound, s as AttachmentNotFound, t as SwitchboardAttachmentTransport, u as HashMismatch } from "./switchboard-attachment-transport-BH3ZAmxE.js";
2
+ import { a as RemoteAttachmentUpload, c as createFetchUploadTransport, d as parseAttachmentUploadTarget, i as RemoteAttachmentUploadFactory, l as AttachmentService, n as createRemoteAttachmentService, o as RemoteReservationStore, r as RemoteAttachmentStore, s as createXhrUploadTransport, t as NullAttachmentTransport, u as parseAttachmentDownloadTarget } from "./null-attachment-transport-BGG9cRC-.js";
3
+ import { t as AttachmentSchemaCompiler } from "./attachment-schema-compiler-rIaJpiHO.js";
2
4
  import { dirname, join } from "node:path";
3
5
  import { Migrator, sql } from "kysely";
4
6
  import { mkdir, rename, rm } from "node:fs/promises";
@@ -6,9 +8,6 @@ import { createReadStream, createWriteStream } from "node:fs";
6
8
  import { createHash, randomUUID } from "node:crypto";
7
9
  import { Readable } from "node:stream";
8
10
  import { finished } from "node:stream/promises";
9
- import { generatorTypeDefs } from "@powerhousedao/document-engineering/graphql";
10
- import { constantCase, pascalCase } from "change-case";
11
- import { Kind, buildASTSchema, getNamedType, isInputObjectType, isListType, isNonNullType, parse, print } from "graphql";
12
11
  import { BaseReadModel, defaultReadModelIndexingConfig } from "@powerhousedao/reactor";
13
12
  import { isPurgeMarker } from "@powerhousedao/shared/document-model";
14
13
  import { Buffer as Buffer$1 } from "node:buffer";
@@ -844,262 +843,23 @@ var AttachmentBuilder = class {
844
843
  }
845
844
  };
846
845
  //#endregion
847
- //#region src/reference-index/attachment-schema-compiler.ts
848
- const ATTACHMENT_REF_TYPE = "AttachmentRef";
849
- const CODEGEN_SCALAR_NAMES = /* @__PURE__ */ new Set([
850
- "Unknown",
851
- "DateTime",
852
- "Address",
853
- ATTACHMENT_REF_TYPE,
854
- ...Object.keys(generatorTypeDefs)
855
- ]);
856
- function describeContext(context) {
857
- return `document type "${context.documentType}", version ${context.version}, action "${context.actionType}"`;
858
- }
859
- function compilationError(context, reason) {
860
- return /* @__PURE__ */ new Error(`Attachment schema compilation failed for ${describeContext(context)}: ${reason}`);
861
- }
862
- function extractionError(context, path, reason) {
863
- return /* @__PURE__ */ new Error(`Attachment extraction failed for ${describeContext(context)} at ${path}: ${reason}`);
864
- }
865
- function applicableSpecification(module, context) {
866
- const matches = module.documentModel.global.specifications.filter((specification) => specification.version === context.version);
867
- if (matches.length !== 1) throw compilationError(context, matches.length === 0 ? "the module has no matching specification" : "the module has multiple matching specifications");
868
- return matches[0];
869
- }
870
- function parseOperations(specification, context) {
871
- return specification.modules.flatMap((moduleSpecification) => moduleSpecification.operations.map((operation) => {
872
- if (operation.schema === null) return {
873
- document: null,
874
- operation
875
- };
876
- try {
877
- return {
878
- document: parse(operation.schema),
879
- operation
880
- };
881
- } catch {
882
- throw compilationError(context, "an operation has invalid GraphQL SDL");
883
- }
884
- }));
885
- }
886
- function selectOperation(operations, context) {
887
- const matches = operations.filter(({ operation }) => operation.name !== null && constantCase(operation.name) === context.actionType);
888
- if (matches.length > 1) throw compilationError(context, "multiple operations map to the action");
889
- if (matches.length === 0) return null;
890
- return matches[0];
846
+ //#region src/read-models/attachment-reference/kysely-attachment-reference-store.ts
847
+ function encodeCursor(cursor) {
848
+ return JSON.stringify([cursor.documentId, cursor.ref]);
891
849
  }
892
- function buildEffectiveSchema(specification, context) {
893
- const scalarSchemas = Array.from(CODEGEN_SCALAR_NAMES, (name) => `scalar ${name}`);
894
- const stateSchemas = Object.values(specification.state).map((state) => state.schema);
895
- const operationSchemas = specification.modules.flatMap((moduleSpecification) => moduleSpecification.operations.flatMap((operation) => operation.schema === null ? [] : [operation.schema]));
850
+ function decodeCursor(cursor) {
851
+ let parsed;
896
852
  try {
897
- const document = parse([
898
- ...scalarSchemas,
899
- ...stateSchemas,
900
- ...operationSchemas
901
- ].filter(Boolean).join("\n\n"));
902
- return buildASTSchema(dedupeTypeDefinitions(document));
853
+ parsed = JSON.parse(cursor);
903
854
  } catch {
904
- throw compilationError(context, "the effective GraphQL schema is invalid");
905
- }
906
- }
907
- function dedupeTypeDefinitions(document) {
908
- const seen = /* @__PURE__ */ new Map();
909
- const definitions = document.definitions.filter((definition) => {
910
- if (!("name" in definition) || definition.name?.value === void 0 || definition.kind === Kind.SCALAR_TYPE_DEFINITION) return true;
911
- const name = definition.name.value;
912
- const printed = print(definition);
913
- const existing = seen.get(name);
914
- if (existing === void 0) {
915
- seen.set(name, printed);
916
- return true;
917
- }
918
- return existing !== printed;
919
- });
920
- return {
921
- ...document,
922
- definitions
923
- };
924
- }
925
- function attachmentReachableTypes(definitions) {
926
- const reachable = /* @__PURE__ */ new Set();
927
- let changed = true;
928
- while (changed) {
929
- changed = false;
930
- for (const [name, definition] of definitions) {
931
- if (reachable.has(name)) continue;
932
- if (Object.values(definition.getFields()).some((field) => {
933
- const typeName = getNamedType(field.type).name;
934
- return typeName === ATTACHMENT_REF_TYPE || definitions.has(typeName) && reachable.has(typeName);
935
- })) {
936
- reachable.add(name);
937
- changed = true;
938
- }
939
- }
855
+ throw new Error(`Invalid attachment reference scan cursor: ${JSON.stringify(cursor)}`);
940
856
  }
941
- return reachable;
942
- }
943
- function compileValuePlan(type, objectPlans) {
944
- if (isNonNullType(type)) return {
945
- ...compileValuePlan(type.ofType, objectPlans),
946
- required: true
947
- };
948
- if (isListType(type)) return {
949
- item: compileValuePlan(type.ofType, objectPlans),
950
- kind: "list",
951
- required: false
952
- };
953
- const typeName = type.name;
954
- if (typeName === ATTACHMENT_REF_TYPE) return {
955
- kind: "attachment",
956
- required: false
957
- };
958
- const body = objectPlans.get(typeName);
959
- if (!body) throw new Error(`Internal attachment schema plan error for ${typeName}`);
857
+ if (!Array.isArray(parsed) || parsed.length !== 2 || typeof parsed[0] !== "string" || parsed[0] === "" || typeof parsed[1] !== "string" || parsed[1] === "") throw new Error(`Invalid attachment reference scan cursor: ${JSON.stringify(cursor)}`);
960
858
  return {
961
- body,
962
- kind: "object",
963
- required: false
964
- };
965
- }
966
- function compileRootPlan(rootName, definitions) {
967
- const reachable = attachmentReachableTypes(definitions);
968
- if (!reachable.has(rootName)) return null;
969
- const objectPlans = /* @__PURE__ */ new Map();
970
- for (const name of reachable) objectPlans.set(name, { fields: [] });
971
- for (const name of reachable) {
972
- const definition = definitions.get(name);
973
- const body = objectPlans.get(name);
974
- if (!definition || !body) continue;
975
- for (const field of Object.values(definition.getFields())) {
976
- const typeName = getNamedType(field.type).name;
977
- if (typeName !== ATTACHMENT_REF_TYPE && !reachable.has(typeName)) continue;
978
- body.fields.push({
979
- hasDefault: field.defaultValue !== void 0,
980
- name: field.name,
981
- value: compileValuePlan(field.type, objectPlans)
982
- });
983
- }
984
- }
985
- return objectPlans.get(rootName) ?? null;
986
- }
987
- function readOwnField(value, fieldName, context, path) {
988
- try {
989
- if (!Object.prototype.hasOwnProperty.call(value, fieldName)) return {
990
- present: false,
991
- value: void 0
992
- };
993
- return {
994
- present: true,
995
- value: value[fieldName]
996
- };
997
- } catch {
998
- throw extractionError(context, path, "the declared field cannot be read");
999
- }
1000
- }
1001
- function extractValue(plan, value, path, context, refs, seenRefs, activeObjects) {
1002
- if (value === null || value === void 0) {
1003
- if (plan.required) throw extractionError(context, path, "a required value is missing or null");
1004
- return;
1005
- }
1006
- if (plan.kind === "attachment") {
1007
- if (typeof value !== "string") throw extractionError(context, path, "expected an AttachmentRef string");
1008
- try {
1009
- parseRef(value);
1010
- } catch {
1011
- throw extractionError(context, path, "the AttachmentRef is malformed");
1012
- }
1013
- if (!seenRefs.has(value)) {
1014
- seenRefs.add(value);
1015
- refs.push(value);
1016
- }
1017
- return;
1018
- }
1019
- if (plan.kind === "list") {
1020
- if (!Array.isArray(value)) throw extractionError(context, path, "expected a list");
1021
- for (let index = 0; index < value.length; index += 1) extractValue(plan.item, value[index], `${path}[${index}]`, context, refs, seenRefs, activeObjects);
1022
- return;
1023
- }
1024
- if (typeof value !== "object" || Array.isArray(value)) throw extractionError(context, path, "expected an input object");
1025
- if (activeObjects.has(value)) throw extractionError(context, path, "the input value contains a cycle");
1026
- activeObjects.add(value);
1027
- try {
1028
- const record = value;
1029
- for (const field of plan.body.fields) {
1030
- const fieldPath = `${path}.${field.name}`;
1031
- const result = readOwnField(record, field.name, context, fieldPath);
1032
- if ((!result.present || result.value === void 0) && field.hasDefault) continue;
1033
- extractValue(field.value, result.value, fieldPath, context, refs, seenRefs, activeObjects);
1034
- }
1035
- } finally {
1036
- activeObjects.delete(value);
1037
- }
1038
- }
1039
- var SchemaCompiledAttachmentExtractor = class {
1040
- context;
1041
- rootPlan;
1042
- constructor(context, rootPlan) {
1043
- this.context = context;
1044
- this.rootPlan = rootPlan;
1045
- }
1046
- extract(action) {
1047
- if (action.type !== this.context.actionType) throw extractionError(this.context, "input", "the action type does not match the compiled schema");
1048
- if (!this.rootPlan) return [];
1049
- if (action.input === null || typeof action.input !== "object" || Array.isArray(action.input)) throw extractionError(this.context, "input", "expected an input object");
1050
- const refs = [];
1051
- const seenRefs = /* @__PURE__ */ new Set();
1052
- const activeObjects = /* @__PURE__ */ new WeakSet();
1053
- activeObjects.add(action.input);
1054
- try {
1055
- const input = action.input;
1056
- for (const field of this.rootPlan.fields) {
1057
- const path = `input.${field.name}`;
1058
- const result = readOwnField(input, field.name, this.context, path);
1059
- if ((!result.present || result.value === void 0) && field.hasDefault) continue;
1060
- extractValue(field.value, result.value, path, this.context, refs, seenRefs, activeObjects);
1061
- }
1062
- } finally {
1063
- activeObjects.delete(action.input);
1064
- }
1065
- return refs;
1066
- }
1067
- };
1068
- function compileExtractor(module, actionType) {
1069
- const context = {
1070
- actionType,
1071
- documentType: module.documentModel.global.id,
1072
- version: module.version ?? 1
859
+ documentId: parsed[0],
860
+ ref: parsed[1]
1073
861
  };
1074
- const specification = applicableSpecification(module, context);
1075
- const selected = selectOperation(parseOperations(specification, context), context);
1076
- if (selected === null || selected.operation.schema === null) return new SchemaCompiledAttachmentExtractor(context, null);
1077
- const effectiveSchema = buildEffectiveSchema(specification, context);
1078
- const operationName = selected.operation.name;
1079
- if (operationName === null) throw compilationError(context, "the operation has no name");
1080
- const rootName = `${pascalCase(operationName)}Input`;
1081
- const definitions = /* @__PURE__ */ new Map();
1082
- for (const type of Object.values(effectiveSchema.getTypeMap())) if (isInputObjectType(type) && !type.name.startsWith("__")) definitions.set(type.name, type);
1083
- if (!(selected.document?.definitions.filter((definition) => (definition.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION || definition.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION) && definition.name.value === rootName))?.length || !definitions.has(rootName)) throw compilationError(context, `the operation does not declare its expected root input "${rootName}"`);
1084
- return new SchemaCompiledAttachmentExtractor(context, compileRootPlan(rootName, definitions));
1085
862
  }
1086
- var AttachmentSchemaCompiler = class {
1087
- cache = /* @__PURE__ */ new WeakMap();
1088
- forModuleAction(module, actionType) {
1089
- let moduleCache = this.cache.get(module);
1090
- if (!moduleCache) {
1091
- moduleCache = /* @__PURE__ */ new Map();
1092
- this.cache.set(module, moduleCache);
1093
- }
1094
- const cached = moduleCache.get(actionType);
1095
- if (cached) return cached;
1096
- const compiled = compileExtractor(module, actionType);
1097
- moduleCache.set(actionType, compiled);
1098
- return compiled;
1099
- }
1100
- };
1101
- //#endregion
1102
- //#region src/read-models/attachment-reference/kysely-attachment-reference-store.ts
1103
863
  var KyselyAttachmentReferenceStore = class {
1104
864
  db;
1105
865
  constructor(db) {
@@ -1111,6 +871,31 @@ var KyselyAttachmentReferenceStore = class {
1111
871
  async referencingScopes(documentId, ref) {
1112
872
  return (await this.db.selectFrom("attachment_reference").select("scope").distinct().where("document_id", "=", documentId).where("attachment_ref", "=", ref).execute()).map((row) => row.scope);
1113
873
  }
874
+ /**
875
+ * Keyset paging over the unique `(document_id, attachment_ref)` constraint,
876
+ * rather than OFFSET: a scan that runs while the read model is still
877
+ * indexing must not skip or repeat a row because rows appeared behind the
878
+ * cursor. That is exactly the boot case the replicator's re-scan runs in.
879
+ */
880
+ async listReferences(cursor, limit) {
881
+ let query = this.db.selectFrom("attachment_reference").select(["document_id", "attachment_ref"]).orderBy("document_id", "asc").orderBy("attachment_ref", "asc").limit(limit);
882
+ if (cursor !== void 0) {
883
+ const after = decodeCursor(cursor);
884
+ query = query.where((eb) => eb.or([eb("document_id", ">", after.documentId), eb.and([eb("document_id", "=", after.documentId), eb("attachment_ref", ">", after.ref)])]));
885
+ }
886
+ const rows = await query.execute();
887
+ const last = rows.at(-1);
888
+ return {
889
+ references: rows.map((row) => ({
890
+ documentId: row.document_id,
891
+ ref: row.attachment_ref
892
+ })),
893
+ nextCursor: rows.length === limit && last ? encodeCursor({
894
+ documentId: last.document_id,
895
+ ref: last.attachment_ref
896
+ }) : void 0
897
+ };
898
+ }
1114
899
  async addReferences(references) {
1115
900
  if (references.length === 0) return;
1116
901
  await this.db.insertInto("attachment_reference").values(references.map((reference) => ({