@powerhousedao/reactor-api 6.2.2-dev.4 → 6.2.2-dev.41

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.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e5e764e0-a390-5076-8849-48b393ff0087")}catch(e){}}();
3
- import { a as isSubgraphClass, c as loadDocumentModels, d as BaseSubgraph, f as AuthorizationPolicy, i as buildGraphqlOperations, l as loadProcessors, m as createAuthorizationService, n as buildGraphQlDriveDocument, o as debounce, p as AuthorizedDocumentHandle, r as buildGraphqlOperation, t as buildGraphQlDocument, u as loadSubgraphs } from "./utils-iibOQ50e.mjs";
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f661f924-a48f-516e-8739-859d08b54d00")}catch(e){}}();
3
+ import { a as isSubgraphClass, c as loadDocumentModels, d as BaseSubgraph, f as CanonicalDocumentIdResolutionError, g as createAuthorizationService, h as AuthorizedDocumentHandle, i as buildGraphqlOperations, l as loadProcessors, m as AuthorizationPolicy, n as buildGraphQlDriveDocument, o as debounce, p as createCanonicalDocumentIdResolver, r as buildGraphqlOperation, t as buildGraphQlDocument, u as loadSubgraphs } from "./utils-BdPg2whY.mjs";
4
4
  import { AnalyticsQueryEngine } from "@powerhousedao/analytics-engine-core";
5
5
  import { AnalyticsModel, AnalyticsResolvers, typedefs } from "@powerhousedao/analytics-engine-graphql";
6
6
  import { gql } from "graphql-tag";
7
7
  import { GraphQLError, Kind, parse, print } from "graphql";
8
- import { DEFAULT_DRIVE_CONTAINER_TYPES, DriveCollectionId, PropagationMode as PropagationMode$1, consolidateSyncOperations, driveIdFromUrl, envelopesToSyncOperations, parseDriveUrl } from "@powerhousedao/reactor";
8
+ import { DEFAULT_DRIVE_CONTAINER_TYPES, DriveCollectionId, PropagationMode as PropagationMode$1, consolidateSyncOperations, driveIdFromUrl, envelopesToSyncOperations, parseDriveUrl, syncOperationErrorType } from "@powerhousedao/reactor";
9
9
  import { ConsoleLogger, childLogger, documentModelDocumentModelModule } from "document-model";
10
10
  import path from "node:path";
11
11
  import { match } from "path-to-regexp";
@@ -26,7 +26,7 @@ import { driveDocumentModelModule } from "@powerhousedao/shared/document-drive";
26
26
  import EventEmitter from "node:events";
27
27
  import fs, { watchFile } from "node:fs";
28
28
  import { PostgresAnalyticsStore } from "@powerhousedao/analytics-engine-pg";
29
- import { AttachmentBuilder } from "@powerhousedao/reactor-attachments";
29
+ import { AttachmentBuilder, AttachmentReferenceIndexBuilder, createRef, createS3AttachmentBackend, parseAttachmentStorageConfig, parseRef } from "@powerhousedao/reactor-attachments";
30
30
  import { createAttachmentClient } from "@powerhousedao/reactor-attachments/client";
31
31
  import { setupMcpServer } from "@powerhousedao/reactor-mcp";
32
32
  import { mkdir } from "node:fs/promises";
@@ -34,7 +34,7 @@ import { tmpdir } from "node:os";
34
34
  import { WebSocketServer } from "ws";
35
35
  import { createRelationalDb } from "@powerhousedao/shared/processors";
36
36
  import { Kysely, Migrator, sql } from "kysely";
37
- import { verifyAuthBearerToken } from "@renown/sdk";
37
+ import { fetchDelegationCredential, resolveSwitchboardEndpoint, verifyAuthBearerToken } from "@renown/sdk";
38
38
  import { PGlite } from "@electric-sql/pglite";
39
39
  import { AtomicNodeFs } from "@powerhousedao/pglite-fs";
40
40
  import knex from "knex";
@@ -460,6 +460,7 @@ const getDocumentModelTypeDefs = (documentModels, typeDefs$1) => {
460
460
  });
461
461
  return dedupeTypeDefinitions(gql`
462
462
  scalar JSONObject
463
+ scalar AttachmentRef
463
464
  ${typeDefs.join("\n").replaceAll(";", "")}
464
465
 
465
466
  type PHOperationContext {
@@ -878,6 +879,7 @@ function generateNewApiSchema(documentName, specification, _stateSchemaTypes, pr
878
879
  return gql`
879
880
  scalar DateTime
880
881
  scalar JSONObject
882
+ scalar AttachmentRef
881
883
 
882
884
  ${revisionType}
883
885
 
@@ -989,6 +991,7 @@ function OperationContextInputSchema() {
989
991
  function OperationInputSchema() {
990
992
  return z$1.object({
991
993
  action: z$1.lazy(() => ActionInputSchema()),
994
+ deniedReason: z$1.string().nullish(),
992
995
  error: z$1.string().nullish(),
993
996
  hash: z$1.string(),
994
997
  id: z$1.string().nullish(),
@@ -1147,6 +1150,7 @@ const GetDocumentWithOperationsDocument = gql`
1147
1150
  hash
1148
1151
  skip
1149
1152
  error
1153
+ deniedReason
1150
1154
  id
1151
1155
  action {
1152
1156
  id
@@ -1259,6 +1263,7 @@ const GetDocumentOperationsDocument = gql`
1259
1263
  hash
1260
1264
  skip
1261
1265
  error
1266
+ deniedReason
1262
1267
  id
1263
1268
  action {
1264
1269
  id
@@ -1509,6 +1514,7 @@ const PollSyncEnvelopesDocument = gql`
1509
1514
  hash
1510
1515
  skip
1511
1516
  error
1517
+ deniedReason
1512
1518
  id
1513
1519
  action {
1514
1520
  id
@@ -1551,6 +1557,7 @@ const PollSyncEnvelopesDocument = gql`
1551
1557
  deadLetters {
1552
1558
  documentId
1553
1559
  error
1560
+ errorType
1554
1561
  }
1555
1562
  hasMore
1556
1563
  }
@@ -1904,9 +1911,10 @@ async function documentModels(reactorClient, args) {
1904
1911
  throw new GraphQLError(`Failed to convert document models to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
1905
1912
  }
1906
1913
  }
1907
- async function document(reactorClient, args) {
1908
- let view;
1914
+ async function document(reactorClient, args, subject) {
1915
+ let view = subject ? { subject } : void 0;
1909
1916
  if (args.view) view = {
1917
+ subject,
1910
1918
  branch: fromInputMaybe(args.view.branch),
1911
1919
  scopes: toMutableArray(fromInputMaybe(args.view.scopes))
1912
1920
  };
@@ -1931,9 +1939,10 @@ async function document(reactorClient, args) {
1931
1939
  throw new GraphQLError(`Failed to convert document to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
1932
1940
  }
1933
1941
  }
1934
- async function documentOutgoingRelationships(reactorClient, args) {
1935
- let view;
1942
+ async function documentOutgoingRelationships(reactorClient, args, subject) {
1943
+ let view = subject ? { subject } : void 0;
1936
1944
  if (args.view) view = {
1945
+ subject,
1937
1946
  branch: fromInputMaybe(args.view.branch),
1938
1947
  scopes: toMutableArray(fromInputMaybe(args.view.scopes))
1939
1948
  };
@@ -1958,9 +1967,10 @@ async function documentOutgoingRelationships(reactorClient, args) {
1958
1967
  throw new GraphQLError(`Failed to convert outgoing relationships to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
1959
1968
  }
1960
1969
  }
1961
- async function documentIncomingRelationships(reactorClient, args) {
1962
- let view;
1970
+ async function documentIncomingRelationships(reactorClient, args, subject) {
1971
+ let view = subject ? { subject } : void 0;
1963
1972
  if (args.view) view = {
1973
+ subject,
1964
1974
  branch: fromInputMaybe(args.view.branch),
1965
1975
  scopes: toMutableArray(fromInputMaybe(args.view.scopes))
1966
1976
  };
@@ -1985,9 +1995,10 @@ async function documentIncomingRelationships(reactorClient, args) {
1985
1995
  throw new GraphQLError(`Failed to convert incoming relationships to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
1986
1996
  }
1987
1997
  }
1988
- async function findDocuments(reactorClient, args) {
1989
- let view;
1998
+ async function findDocuments(reactorClient, args, subject) {
1999
+ let view = subject ? { subject } : void 0;
1990
2000
  if (args.view) view = {
2001
+ subject,
1991
2002
  branch: fromInputMaybe(args.view.branch),
1992
2003
  scopes: toMutableArray(fromInputMaybe(args.view.scopes))
1993
2004
  };
@@ -2029,11 +2040,12 @@ async function jobStatus(reactorClient, args) {
2029
2040
  throw new GraphQLError(`Failed to convert job status to GraphQL: ${error instanceof Error ? error.message : "Unknown error"}`);
2030
2041
  }
2031
2042
  }
2032
- async function documentOperations(reactorClient, args) {
2033
- let view;
2043
+ async function documentOperations(reactorClient, args, subject) {
2044
+ let view = subject ? { subject } : void 0;
2034
2045
  const branch = fromInputMaybe(args.filter.branch);
2035
2046
  const scopes = toMutableArray(fromInputMaybe(args.filter.scopes));
2036
2047
  if (branch || scopes) view = {
2048
+ subject,
2037
2049
  branch,
2038
2050
  scopes
2039
2051
  };
@@ -2347,6 +2359,7 @@ function pollSyncEnvelopes(syncManager, args, forbiddenIds = /* @__PURE__ */ new
2347
2359
  const deadLetters = remote.channel.deadLetter.items.filter((syncOp) => !forbiddenIds.has(syncOp.documentId)).map((syncOp) => ({
2348
2360
  documentId: syncOp.documentId,
2349
2361
  error: syncOp.error?.message ?? "Unknown error",
2362
+ errorType: syncOperationErrorType(syncOp.error),
2350
2363
  jobId: syncOp.jobId,
2351
2364
  branch: syncOp.branch,
2352
2365
  scopes: syncOp.scopes,
@@ -3631,7 +3644,7 @@ function createReactorGraphQLClient(url, fetchImpl = fetch, headers) {
3631
3644
  }
3632
3645
  //#endregion
3633
3646
  //#region src/graphql/reactor/schema.graphql
3634
- var schema_default = "# Scalar types (for codegen - also defined in create-schema.ts)\nscalar JSONObject\nscalar DateTime\n\n# Input types\ninput PagingInput {\n limit: Int\n offset: Int\n cursor: String\n}\n\ninput ViewFilterInput {\n branch: String\n scopes: [String!]\n}\n\ninput SearchFilterInput {\n type: String\n parentId: String\n identifiers: [String!]\n}\n\ninput OperationsFilterInput {\n documentId: String!\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\ninput DocumentOperationsFilterInput {\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\n# Enums\nenum PropagationMode {\n CASCADE\n ORPHAN\n}\n\nenum DocumentChangeType {\n CREATED\n DELETED\n UPDATED\n PARENT_ADDED\n PARENT_REMOVED\n CHILD_ADDED\n CHILD_REMOVED\n}\n\n# Object types\ntype DocumentModelGlobalState {\n id: String!\n name: String!\n namespace: String\n version: String\n specification: JSONObject!\n}\n\ntype DocumentModelResultPage {\n items: [DocumentModelGlobalState!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype Revision {\n scope: String!\n revision: Int!\n}\n\ntype PHDocument {\n id: String!\n slug: String\n preferredEditor: String\n name: String!\n documentType: String!\n state: JSONObject!\n revisionsList: [Revision!]!\n createdAtUtcIso: DateTime!\n lastModifiedAtUtcIso: DateTime!\n operations(\n filter: DocumentOperationsFilterInput\n paging: PagingInput\n ): ReactorOperationResultPage\n}\n\ntype PHDocumentResultPage {\n items: [PHDocument!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype ReactorOperationResultPage {\n items: [ReactorOperation!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype DeadLetterInfo {\n documentId: String!\n error: String!\n jobId: String!\n branch: String!\n scopes: [String!]!\n operationCount: Int!\n}\n\ntype PollSyncEnvelopesResult {\n envelopes: [SyncEnvelope!]!\n ackOrdinal: Int!\n deadLetters: [DeadLetterInfo!]!\n hasMore: Boolean!\n}\n\ntype DocumentWithChildren {\n document: PHDocument!\n childIds: [String!]!\n}\n\ntype MoveRelationshipResult {\n source: PHDocument!\n target: PHDocument!\n}\n\ntype JobInfo {\n id: String!\n status: String!\n result: JSONObject!\n error: String\n createdAt: DateTime!\n completedAt: DateTime\n}\n\ntype DocumentChangeEvent {\n type: DocumentChangeType!\n documents: [PHDocument!]!\n context: DocumentChangeContext\n}\n\ntype DocumentChangeContext {\n parentId: String\n childId: String\n}\n\ntype JobChangeEvent {\n jobId: String!\n status: String!\n result: JSONObject!\n error: String\n}\n\ntype ReactorSignerUser {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ntype ReactorSignerApp {\n name: String!\n key: String!\n}\n\ntype ReactorSigner {\n user: ReactorSignerUser\n app: ReactorSignerApp\n signatures: [String!]!\n}\n\ntype ActionContext {\n signer: ReactorSigner\n}\n\ntype Action {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContext\n}\n\n# Input types for sync operations\ninput ActionContextInput {\n signer: ReactorSignerInput\n}\n\ninput ReactorSignerInput {\n user: ReactorSignerUserInput\n app: ReactorSignerAppInput\n signatures: [String!]!\n}\n\ninput ReactorSignerUserInput {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ninput ReactorSignerAppInput {\n name: String!\n key: String!\n}\n\ninput ActionInput {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContextInput\n}\n\n# Synchronization types\ntype ReactorOperation {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n id: String\n action: Action!\n}\n\ninput OperationInput {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n id: String\n action: ActionInput!\n}\n\ntype OperationContext {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ninput OperationContextInput {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ntype OperationWithContext {\n operation: ReactorOperation!\n context: OperationContext!\n}\n\ninput OperationWithContextInput {\n operation: OperationInput!\n context: OperationContextInput!\n}\n\ntype ChannelMeta {\n id: String!\n}\n\ninput ChannelMetaInput {\n id: String!\n}\n\ntype RemoteCursor {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\ninput RemoteCursorInput {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\nenum SyncEnvelopeType {\n OPERATIONS\n ACK\n}\n\ntype SyncEnvelope {\n type: SyncEnvelopeType!\n channelMeta: ChannelMeta!\n operations: [OperationWithContext!]\n cursor: RemoteCursor\n key: String\n dependsOn: [String!]\n}\n\ninput SyncEnvelopeInput {\n type: SyncEnvelopeType!\n channelMeta: ChannelMetaInput!\n operations: [OperationWithContextInput!]\n cursor: RemoteCursorInput\n key: String\n dependsOn: [String!]\n}\n\ninput RemoteFilterInput {\n documentId: [String!]!\n scope: [String!]!\n branch: String!\n}\n\ninput TouchChannelInput {\n id: String!\n name: String!\n collectionId: String!\n filter: RemoteFilterInput!\n sinceTimestampUtcMs: String!\n}\n\ntype TouchChannelResult {\n success: Boolean!\n ackOrdinal: Int!\n}\n\ntype Query {\n # Get document models for a namespace\n documentModels(\n namespace: String\n paging: PagingInput\n ): DocumentModelResultPage!\n\n # Get a specific document by ID or slug\n document(identifier: String!, view: ViewFilterInput): DocumentWithChildren\n\n # Get outgoing relationships of a given type from a source document\n documentOutgoingRelationships(\n sourceIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get incoming relationships of a given type to a target document\n documentIncomingRelationships(\n targetIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Find documents by search criteria\n findDocuments(\n search: SearchFilterInput\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get job status\n jobStatus(jobId: String!): JobInfo\n\n # Get operations for a document with filtering and pagination\n documentOperations(\n filter: OperationsFilterInput!\n paging: PagingInput\n ): ReactorOperationResultPage!\n\n # Poll for sync envelopes from a channel\n pollSyncEnvelopes(\n channelId: String!\n outboxAck: Int!\n outboxLatest: Int!\n ): PollSyncEnvelopesResult!\n}\n\ntype Mutation {\n # Create a new document\n createDocument(document: JSONObject!, parentIdentifier: String): PHDocument!\n\n # Create an empty document of specified type\n createEmptyDocument(\n documentType: String!\n parentIdentifier: String\n ): PHDocument!\n\n # Apply actions to a document (synchronous)\n mutateDocument(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): PHDocument!\n\n # Submit actions to a document (asynchronous)\n mutateDocumentAsync(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): String!\n\n # Rename a document\n renameDocument(\n documentIdentifier: String!\n name: String!\n branch: String\n ): PHDocument!\n\n # Update the preferred editor recorded in the document header meta.\n # Pass null/omit to clear it.\n setPreferredEditor(\n documentIdentifier: String!\n preferredEditor: String\n branch: String\n ): PHDocument!\n\n # Add a relationship between two documents\n addRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Remove a relationship between two documents\n removeRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Move a relationship from one source to another\n moveRelationship(\n sourceParentIdentifier: String!\n targetParentIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): MoveRelationshipResult!\n\n # Delete a single document\n deleteDocument(identifier: String!, propagate: PropagationMode): Boolean!\n\n # Delete multiple documents\n deleteDocuments(identifiers: [String!]!, propagate: PropagationMode): Boolean!\n\n # Touch (create or update) a channel for sync\n touchChannel(input: TouchChannelInput!): TouchChannelResult!\n\n # Push sync envelopes to a channel\n pushSyncEnvelopes(envelopes: [SyncEnvelopeInput!]!): Boolean!\n}\n\ntype Subscription {\n # Subscribe to document changes\n documentChanges(\n search: SearchFilterInput\n view: ViewFilterInput\n ): DocumentChangeEvent!\n\n # Subscribe to job changes\n jobChanges(jobId: String!): JobChangeEvent!\n}\n";
3647
+ var schema_default = "# Scalar types (for codegen - also defined in create-schema.ts)\nscalar JSONObject\nscalar DateTime\n\n# Input types\ninput PagingInput {\n limit: Int\n offset: Int\n cursor: String\n}\n\ninput ViewFilterInput {\n branch: String\n scopes: [String!]\n}\n\ninput SearchFilterInput {\n type: String\n parentId: String\n identifiers: [String!]\n}\n\ninput OperationsFilterInput {\n documentId: String!\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\ninput DocumentOperationsFilterInput {\n branch: String\n scopes: [String!]\n actionTypes: [String!]\n sinceRevision: Int\n timestampFrom: String\n timestampTo: String\n}\n\n# Enums\nenum PropagationMode {\n CASCADE\n ORPHAN\n}\n\nenum DocumentChangeType {\n CREATED\n DELETED\n UPDATED\n PARENT_ADDED\n PARENT_REMOVED\n CHILD_ADDED\n CHILD_REMOVED\n}\n\n# Object types\ntype DocumentModelGlobalState {\n id: String!\n name: String!\n namespace: String\n version: String\n specification: JSONObject!\n}\n\ntype DocumentModelResultPage {\n items: [DocumentModelGlobalState!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype Revision {\n scope: String!\n revision: Int!\n}\n\ntype PHDocument {\n id: String!\n slug: String\n preferredEditor: String\n name: String!\n documentType: String!\n state: JSONObject!\n revisionsList: [Revision!]!\n createdAtUtcIso: DateTime!\n lastModifiedAtUtcIso: DateTime!\n operations(\n filter: DocumentOperationsFilterInput\n paging: PagingInput\n ): ReactorOperationResultPage\n}\n\ntype PHDocumentResultPage {\n items: [PHDocument!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype ReactorOperationResultPage {\n items: [ReactorOperation!]!\n totalCount: Int!\n hasNextPage: Boolean!\n hasPreviousPage: Boolean!\n cursor: String\n}\n\ntype DeadLetterInfo {\n documentId: String!\n error: String!\n \"\"\"\n How the origin classified the failure. A peer needs this to mirror the origin's\n quarantine decision; without it a held auth operation would freeze the document\n on the peer side while the origin kept syncing.\n \"\"\"\n errorType: String\n jobId: String!\n branch: String!\n scopes: [String!]!\n operationCount: Int!\n}\n\ntype PollSyncEnvelopesResult {\n envelopes: [SyncEnvelope!]!\n ackOrdinal: Int!\n deadLetters: [DeadLetterInfo!]!\n hasMore: Boolean!\n}\n\ntype DocumentWithChildren {\n document: PHDocument!\n childIds: [String!]!\n}\n\ntype MoveRelationshipResult {\n source: PHDocument!\n target: PHDocument!\n}\n\ntype JobInfo {\n id: String!\n status: String!\n result: JSONObject!\n error: String\n createdAt: DateTime!\n completedAt: DateTime\n}\n\ntype DocumentChangeEvent {\n type: DocumentChangeType!\n documents: [PHDocument!]!\n context: DocumentChangeContext\n}\n\ntype DocumentChangeContext {\n parentId: String\n childId: String\n}\n\ntype JobChangeEvent {\n jobId: String!\n status: String!\n result: JSONObject!\n error: String\n}\n\ntype ReactorSignerUser {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ntype ReactorSignerApp {\n name: String!\n key: String!\n}\n\ntype ReactorSigner {\n user: ReactorSignerUser\n app: ReactorSignerApp\n signatures: [String!]!\n}\n\ntype ActionContext {\n signer: ReactorSigner\n}\n\ntype Action {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContext\n}\n\n# Input types for sync operations\ninput ActionContextInput {\n signer: ReactorSignerInput\n}\n\ninput ReactorSignerInput {\n user: ReactorSignerUserInput\n app: ReactorSignerAppInput\n signatures: [String!]!\n}\n\ninput ReactorSignerUserInput {\n address: String!\n networkId: String!\n chainId: Int!\n}\n\ninput ReactorSignerAppInput {\n name: String!\n key: String!\n}\n\ninput ActionInput {\n id: String!\n type: String!\n timestampUtcMs: String!\n input: JSONObject!\n scope: String!\n context: ActionContextInput\n}\n\n# Synchronization types\ntype ReactorOperation {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n deniedReason: String\n id: String\n action: Action!\n}\n\ninput OperationInput {\n index: Int!\n timestampUtcMs: String!\n hash: String!\n skip: Int!\n error: String\n deniedReason: String\n id: String\n action: ActionInput!\n}\n\ntype OperationContext {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ninput OperationContextInput {\n documentId: String!\n documentType: String!\n scope: String!\n branch: String!\n ordinal: Int!\n}\n\ntype OperationWithContext {\n operation: ReactorOperation!\n context: OperationContext!\n}\n\ninput OperationWithContextInput {\n operation: OperationInput!\n context: OperationContextInput!\n}\n\ntype ChannelMeta {\n id: String!\n}\n\ninput ChannelMetaInput {\n id: String!\n}\n\ntype RemoteCursor {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\ninput RemoteCursorInput {\n remoteName: String!\n cursorOrdinal: Int!\n lastSyncedAtUtcMs: String\n}\n\nenum SyncEnvelopeType {\n OPERATIONS\n ACK\n}\n\ntype SyncEnvelope {\n type: SyncEnvelopeType!\n channelMeta: ChannelMeta!\n operations: [OperationWithContext!]\n cursor: RemoteCursor\n key: String\n dependsOn: [String!]\n}\n\ninput SyncEnvelopeInput {\n type: SyncEnvelopeType!\n channelMeta: ChannelMetaInput!\n operations: [OperationWithContextInput!]\n cursor: RemoteCursorInput\n key: String\n dependsOn: [String!]\n}\n\ninput RemoteFilterInput {\n documentId: [String!]!\n scope: [String!]!\n branch: String!\n}\n\ninput TouchChannelInput {\n id: String!\n name: String!\n collectionId: String!\n filter: RemoteFilterInput!\n sinceTimestampUtcMs: String!\n}\n\ntype TouchChannelResult {\n success: Boolean!\n ackOrdinal: Int!\n}\n\ntype Query {\n # Get document models for a namespace\n documentModels(\n namespace: String\n paging: PagingInput\n ): DocumentModelResultPage!\n\n # Get a specific document by ID or slug\n document(identifier: String!, view: ViewFilterInput): DocumentWithChildren\n\n # Get outgoing relationships of a given type from a source document\n documentOutgoingRelationships(\n sourceIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get incoming relationships of a given type to a target document\n documentIncomingRelationships(\n targetIdentifier: String!\n relationshipType: String!\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Find documents by search criteria\n findDocuments(\n search: SearchFilterInput\n view: ViewFilterInput\n paging: PagingInput\n ): PHDocumentResultPage!\n\n # Get job status\n jobStatus(jobId: String!): JobInfo\n\n # Get operations for a document with filtering and pagination\n documentOperations(\n filter: OperationsFilterInput!\n paging: PagingInput\n ): ReactorOperationResultPage!\n\n # Poll for sync envelopes from a channel\n pollSyncEnvelopes(\n channelId: String!\n outboxAck: Int!\n outboxLatest: Int!\n ): PollSyncEnvelopesResult!\n}\n\ntype Mutation {\n # Create a new document\n createDocument(document: JSONObject!, parentIdentifier: String): PHDocument!\n\n # Create an empty document of specified type\n createEmptyDocument(\n documentType: String!\n parentIdentifier: String\n ): PHDocument!\n\n # Apply actions to a document (synchronous)\n mutateDocument(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): PHDocument!\n\n # Submit actions to a document (asynchronous)\n mutateDocumentAsync(\n documentIdentifier: String!\n actions: [JSONObject!]!\n view: ViewFilterInput\n ): String!\n\n # Rename a document\n renameDocument(\n documentIdentifier: String!\n name: String!\n branch: String\n ): PHDocument!\n\n # Update the preferred editor recorded in the document header meta.\n # Pass null/omit to clear it.\n setPreferredEditor(\n documentIdentifier: String!\n preferredEditor: String\n branch: String\n ): PHDocument!\n\n # Add a relationship between two documents\n addRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Remove a relationship between two documents\n removeRelationship(\n sourceIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): PHDocument!\n\n # Move a relationship from one source to another\n moveRelationship(\n sourceParentIdentifier: String!\n targetParentIdentifier: String!\n targetIdentifier: String!\n relationshipType: String!\n branch: String\n ): MoveRelationshipResult!\n\n # Delete a single document\n deleteDocument(identifier: String!, propagate: PropagationMode): Boolean!\n\n # Delete multiple documents\n deleteDocuments(identifiers: [String!]!, propagate: PropagationMode): Boolean!\n\n # Touch (create or update) a channel for sync\n touchChannel(input: TouchChannelInput!): TouchChannelResult!\n\n # Push sync envelopes to a channel\n pushSyncEnvelopes(envelopes: [SyncEnvelopeInput!]!): Boolean!\n}\n\ntype Subscription {\n # Subscribe to document changes\n documentChanges(\n search: SearchFilterInput\n view: ViewFilterInput\n ): DocumentChangeEvent!\n\n # Subscribe to job changes\n jobChanges(jobId: String!): JobChangeEvent!\n}\n";
3635
3648
  //#endregion
3636
3649
  //#region src/graphql/reactor/pubsub.ts
3637
3650
  const pubSub = new PubSub();
@@ -3787,7 +3800,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
3787
3800
  return await documentOperations(this.reactorClient, {
3788
3801
  filter,
3789
3802
  paging: args.paging
3790
- });
3803
+ }, this.viewSubject(ctx));
3791
3804
  } catch (error) {
3792
3805
  this.logger.error("Error in PHDocument.operations: @Error", error);
3793
3806
  throw error;
@@ -3810,7 +3823,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
3810
3823
  return await document(this.reactorClient, {
3811
3824
  ...args,
3812
3825
  identifier: handle.fetchIdentifier
3813
- });
3826
+ }, this.viewSubject(ctx));
3814
3827
  } catch (error) {
3815
3828
  this.logger.error("Error in document: @Error", error);
3816
3829
  throw error;
@@ -3823,7 +3836,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
3823
3836
  return await documentOutgoingRelationships(this.reactorClient, {
3824
3837
  ...args,
3825
3838
  sourceIdentifier: handle.fetchIdentifier
3826
- });
3839
+ }, this.viewSubject(ctx));
3827
3840
  } catch (error) {
3828
3841
  this.logger.error("Error in documentOutgoingRelationships: @Error", error);
3829
3842
  throw error;
@@ -3836,7 +3849,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
3836
3849
  const result = await documentIncomingRelationships(this.reactorClient, {
3837
3850
  ...args,
3838
3851
  targetIdentifier: handle.fetchIdentifier
3839
- });
3852
+ }, this.viewSubject(ctx));
3840
3853
  if (!this.authorizationService.isSupremeAdmin(ctx.user?.address)) {
3841
3854
  const filteredItems = [];
3842
3855
  for (const item of result.items) if (await this.canReadDocument(item.id, ctx)) filteredItems.push(item);
@@ -3857,7 +3870,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
3857
3870
  const result = await findDocuments(this.reactorClient, {
3858
3871
  ...args,
3859
3872
  search: args.search ?? {}
3860
- });
3873
+ }, this.viewSubject(ctx));
3861
3874
  if (!this.authorizationService.isSupremeAdmin(ctx.user?.address)) {
3862
3875
  const filteredItems = [];
3863
3876
  for (const item of result.items) if (await this.canReadDocument(item.id, ctx)) filteredItems.push(item);
@@ -3891,7 +3904,7 @@ var ReactorSubgraph = class extends BaseSubgraph {
3891
3904
  ...args.filter,
3892
3905
  documentId: handle.fetchIdentifier
3893
3906
  }
3894
- });
3907
+ }, this.viewSubject(ctx));
3895
3908
  } catch (error) {
3896
3909
  this.logger.error("Error in documentOperations: @Error", error);
3897
3910
  throw error;
@@ -4205,10 +4218,10 @@ const ADMIN_USERS = getAdminUsers();
4205
4218
  //#endregion
4206
4219
  //#region src/graphql/system/version.ts
4207
4220
  function getVersion() {
4208
- return "6.2.2-dev.4";
4221
+ return "6.2.2-dev.41";
4209
4222
  }
4210
4223
  function getGitHash() {
4211
- return "fd567d52afa0020df2c925ee70059c492e817bd8";
4224
+ return "f7653013d39a04838756c31d52eb2b160d66afd0";
4212
4225
  }
4213
4226
  function getGitUrl() {
4214
4227
  return buildTreeUrl(getGitHash());
@@ -4695,6 +4708,70 @@ var PackageManager = class {
4695
4708
  const config = { basePath: process.env.BASE_PATH || "/" };
4696
4709
  const DefaultCoreSubgraphs = [AnalyticsSubgraph, SystemSubgraph];
4697
4710
  //#endregion
4711
+ //#region src/attachment-backend.ts
4712
+ /** Filesystem is the default; explicit S3 is readiness-gated without fallback. */
4713
+ async function createStartupAttachmentBackend({ db, env = process.env, s3Dependencies }) {
4714
+ const storage = parseAttachmentStorageConfig(env);
4715
+ if (storage.kind === "filesystem") return void 0;
4716
+ const backend = createS3AttachmentBackend(db.withSchema("attachments"), storage.s3, s3Dependencies);
4717
+ if (!(await backend.health()).ready) throw new Error("S3 attachment backend readiness check failed");
4718
+ return backend;
4719
+ }
4720
+ //#endregion
4721
+ //#region src/services/attachment-access.service.ts
4722
+ const HASH_PATTERN = /^[a-f0-9]{64}$/;
4723
+ /**
4724
+ * Composes document authorization with the projected document/ref
4725
+ * relationship. Order is fixed: validate ref, resolve the canonical document
4726
+ * id, check `canRead`, then check the reference index. A denied document
4727
+ * never reaches the reference reader, and the facade never touches
4728
+ * attachment metadata, storage backends, or presigners.
4729
+ */
4730
+ var AttachmentAccessService = class {
4731
+ constructor(resolveCanonicalId, authorization, references, projection) {
4732
+ this.resolveCanonicalId = resolveCanonicalId;
4733
+ this.authorization = authorization;
4734
+ this.references = references;
4735
+ this.projection = projection;
4736
+ }
4737
+ async canReadAttachment(request) {
4738
+ if (this.projection.status !== "available") return { kind: "projection-unavailable" };
4739
+ const ref = normalizeAttachmentRef(request.attachmentRef);
4740
+ if (ref === null) return { kind: "denied" };
4741
+ let documentId;
4742
+ try {
4743
+ documentId = await this.resolveCanonicalId(request.documentId);
4744
+ } catch {
4745
+ return { kind: "denied" };
4746
+ }
4747
+ if (!await this.authorization.canRead(documentId, request.userAddress)) return { kind: "denied" };
4748
+ if (!await this.references.hasReference(documentId, ref)) return { kind: "denied" };
4749
+ return {
4750
+ kind: "allowed",
4751
+ documentId,
4752
+ ref
4753
+ };
4754
+ }
4755
+ };
4756
+ /**
4757
+ * Parses and canonicalizes a caller-supplied ref through the shared parser.
4758
+ * Returns null for anything that is not a v1 ref over a 64-char SHA-256 hex
4759
+ * hash; hex case is normalized so index lookups use the canonical form.
4760
+ */
4761
+ function normalizeAttachmentRef(value) {
4762
+ let hash;
4763
+ let version;
4764
+ try {
4765
+ const parsed = parseRef(value);
4766
+ hash = parsed.hash.toLowerCase();
4767
+ version = parsed.version;
4768
+ } catch {
4769
+ return null;
4770
+ }
4771
+ if (version !== 1 || !HASH_PATTERN.test(hash)) return null;
4772
+ return createRef(hash, version);
4773
+ }
4774
+ //#endregion
4698
4775
  //#region src/migrations/001_create_document_permissions.ts
4699
4776
  var _001_create_document_permissions_exports = /* @__PURE__ */ __exportAll({
4700
4777
  down: () => down$2,
@@ -5041,27 +5118,34 @@ var AuthService = class {
5041
5118
  this.credentialCache.delete(oldestKey);
5042
5119
  }
5043
5120
  }
5044
- /**
5045
- * Fetch the credential from the Renown API and validate it against the
5046
- * expected address, chainId and issuer. Never throws; returns false on any
5047
- * network or validation failure.
5048
- */
5049
5121
  async fetchCredentialExists(address, chainId, appId) {
5050
- const url = `https://www.renown.id/api/auth/credential?address=${address}&chainId=${chainId}&connectId=${appId}&appId=${appId}`;
5051
- try {
5052
- const response = await fetch(url, { method: "GET" });
5053
- if (response.status !== 200) return false;
5054
- const credential = (await response.json()).credential;
5055
- const appIdVerfied = credential.credentialSubject.id;
5056
- const addressVerfied = credential.issuer.id.split(":")[4];
5057
- const chainIdVerfied = credential.issuer.id.split(":")[3];
5058
- return appIdVerfied === appId && addressVerfied.toLocaleLowerCase() === address.toLocaleLowerCase() && chainIdVerfied === chainId.toString();
5059
- } catch {
5060
- return false;
5061
- }
5122
+ if (!this.config.verifyCredential) throw new Error("AuthService: credential verification is enabled but no verifyCredential was provided");
5123
+ return this.config.verifyCredential({
5124
+ address,
5125
+ chainId,
5126
+ appId
5127
+ });
5062
5128
  }
5063
5129
  };
5064
5130
  //#endregion
5131
+ //#region src/services/renown-credential-verifier.ts
5132
+ async function createRenownCredentialVerifier(config = {}) {
5133
+ const switchboardUrl = await resolveSwitchboardEndpoint({
5134
+ switchboardUrl: config.switchboardUrl,
5135
+ baseUrl: config.renownUrl
5136
+ });
5137
+ return async ({ address, chainId, appId }) => {
5138
+ return await fetchDelegationCredential({
5139
+ address,
5140
+ chainId,
5141
+ appDid: appId,
5142
+ switchboardUrl,
5143
+ baseUrl: switchboardUrl ? void 0 : config.renownUrl,
5144
+ discover: false
5145
+ }) !== void 0;
5146
+ };
5147
+ }
5148
+ //#endregion
5065
5149
  //#region src/services/document-permission.service.ts
5066
5150
  /**
5067
5151
  * Service for managing document-level permissions.
@@ -5653,7 +5737,7 @@ async function _setupCommonInfrastructure(options) {
5653
5737
  admins = options.auth.admins.map((a) => a.toLowerCase());
5654
5738
  authEnabled = options.auth.enabled;
5655
5739
  }
5656
- const { AUTH_ENABLED, ADMINS, DEFAULT_PROTECTION, DOCUMENT_PERMISSIONS_ENABLED, SKIP_CREDENTIAL_VERIFICATION, CREDENTIAL_VERIFICATION_CACHE_TTL_MS } = process.env;
5740
+ const { AUTH_ENABLED, ADMINS, DEFAULT_PROTECTION, DOCUMENT_PERMISSIONS_ENABLED, SKIP_CREDENTIAL_VERIFICATION, CREDENTIAL_VERIFICATION_CACHE_TTL_MS, RENOWN_URL, SWITCHBOARD_URL } = process.env;
5657
5741
  if (AUTH_ENABLED !== void 0) authEnabled = AUTH_ENABLED === "true";
5658
5742
  if (ADMINS !== void 0) admins = ADMINS.split(",").map((a) => a.toLowerCase());
5659
5743
  let defaultProtection = false;
@@ -5689,7 +5773,11 @@ async function _setupCommonInfrastructure(options) {
5689
5773
  enabled: authEnabled,
5690
5774
  admins,
5691
5775
  skipCredentialVerification,
5692
- credentialVerificationCacheTtlMs
5776
+ credentialVerificationCacheTtlMs,
5777
+ verifyCredential: await createRenownCredentialVerifier({
5778
+ renownUrl: RENOWN_URL,
5779
+ switchboardUrl: SWITCHBOARD_URL
5780
+ })
5693
5781
  });
5694
5782
  authFetchMiddleware = createAuthFetchMiddleware(authService);
5695
5783
  }
@@ -5715,7 +5803,12 @@ async function _setupCommonInfrastructure(options) {
5715
5803
  await mkdir(attachmentStoragePath, { recursive: true });
5716
5804
  const { db: attachmentDb, knex: attachmentKnex, pglite: attachmentPglite } = getDbClient(options.dbPath, options.pgliteFactory);
5717
5805
  dbClosers.push(...makeDbClosers(attachmentKnex, attachmentPglite));
5718
- const attachments = await new AttachmentBuilder(attachmentDb, attachmentStoragePath).withReservationSweepMs(3600 * 1e3).build();
5806
+ const ATTACHMENT_SWEEP_INTERVAL_MS = 3600 * 1e3;
5807
+ const attachmentBackend = await createStartupAttachmentBackend({ db: attachmentDb });
5808
+ const attachmentBuilder = new AttachmentBuilder(attachmentDb, attachmentStoragePath).withReservationSweepMs(ATTACHMENT_SWEEP_INTERVAL_MS);
5809
+ if (attachmentBackend) attachmentBuilder.withBackend(attachmentBackend);
5810
+ const attachments = await attachmentBuilder.build();
5811
+ const attachmentReferenceIndex = await new AttachmentReferenceIndexBuilder(attachmentDb).build();
5719
5812
  dbClosers.push(() => {
5720
5813
  attachments.destroy();
5721
5814
  return Promise.resolve();
@@ -5735,6 +5828,7 @@ async function _setupCommonInfrastructure(options) {
5735
5828
  documentPermissionService,
5736
5829
  authorizationConfig,
5737
5830
  attachments,
5831
+ attachmentReferenceIndex,
5738
5832
  packages,
5739
5833
  dbClosers,
5740
5834
  readiness
@@ -5743,7 +5837,7 @@ async function _setupCommonInfrastructure(options) {
5743
5837
  /**
5744
5838
  * Private helper function containing common setup logic for API initialization
5745
5839
  */
5746
- async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, readModels, attachments, authorizationConfig, documentModelRegistry, dbClosers = [], reactorDriveClient) {
5840
+ async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, readModels, attachments, attachmentReferenceIndex, attachmentReferenceProjection, authorizationConfig, documentModelRegistry, dbClosers = [], reactorDriveClient) {
5747
5841
  const hostModule = {
5748
5842
  relationalDb,
5749
5843
  analyticsStore,
@@ -5790,6 +5884,7 @@ async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, ht
5790
5884
  const { httpServer, wsServer } = await startServer(httpAdapter, port, options.https, logger);
5791
5885
  const authorizationService = createAuthorizationService(authorizationConfig, documentPermissionService, createGetParentIdsFn(reactorClient));
5792
5886
  logger.info(`Authorization service initialized (policy: ${authorizationConfig.policy})`);
5887
+ const attachmentAccess = new AttachmentAccessService(createCanonicalDocumentIdResolver(reactorClient), authorizationService, attachmentReferenceIndex.store, attachmentReferenceProjection);
5793
5888
  const coreSubgraphs = DefaultCoreSubgraphs.slice();
5794
5889
  coreSubgraphs.push(ReactorSubgraph);
5795
5890
  if (documentPermissionService) {
@@ -5814,6 +5909,8 @@ async function _setupAPI(reactorClient, syncManager, reactorProcessorManager, ht
5814
5909
  graphqlManager,
5815
5910
  packages,
5816
5911
  attachments,
5912
+ attachmentReferenceIndex,
5913
+ attachmentAccess,
5817
5914
  authService,
5818
5915
  dispose: buildApiDispose({
5819
5916
  graphqlManager,
@@ -5862,9 +5959,12 @@ function buildApiDispose(args) {
5862
5959
  };
5863
5960
  }
5864
5961
  async function initializeAndStartAPI(clientInitializer, options, processorApp) {
5865
- const { port, httpAdapter, authFetchMiddleware, authService, relationalDb, analyticsStore, documentPermissionService, authorizationConfig, attachments, packages, dbClosers, readiness } = await _setupCommonInfrastructure(options);
5962
+ const { port, httpAdapter, authFetchMiddleware, authService, relationalDb, analyticsStore, documentPermissionService, authorizationConfig, attachments, attachmentReferenceIndex, packages, dbClosers, readiness } = await _setupCommonInfrastructure(options);
5866
5963
  const { documentModels, processors, subgraphs } = await packages.init();
5867
- const { module: reactorClientModule, reactorDriveClient } = await clientInitializer(documentModels);
5964
+ const { module: reactorClientModule, reactorDriveClient, attachmentReferenceProjection = {
5965
+ status: "unavailable",
5966
+ reason: "initializer-did-not-report"
5967
+ } } = await clientInitializer(documentModels, { attachmentReferenceWriter: attachmentReferenceIndex.store });
5868
5968
  const reactorClient = reactorClientModule.client;
5869
5969
  const syncManager = reactorClientModule.reactorModule?.syncModule?.syncManager;
5870
5970
  if (!syncManager) throw new Error("SyncManager not available from InProcessReactorClientModule");
@@ -5873,11 +5973,12 @@ async function initializeAndStartAPI(clientInitializer, options, processorApp) {
5873
5973
  const documentModelRegistry = reactorClientModule.reactorModule?.documentModelRegistry;
5874
5974
  if (!documentModelRegistry) throw new Error("DocumentModelRegistry not available from InProcessReactorClientModule");
5875
5975
  return {
5876
- ...await _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, (reactorClientModule.reactorModule?.readModelCoordinator)?.readModels ?? [], attachments, authorizationConfig, documentModelRegistry, dbClosers, reactorDriveClient),
5976
+ ...await _setupAPI(reactorClient, syncManager, reactorProcessorManager, httpAdapter, authFetchMiddleware, authService, port, packages, relationalDb, analyticsStore, documentPermissionService, processors, subgraphs, options, processorApp, (reactorClientModule.reactorModule?.readModelCoordinator)?.readModels ?? [], attachments, attachmentReferenceIndex, attachmentReferenceProjection, authorizationConfig, documentModelRegistry, dbClosers, reactorDriveClient),
5877
5977
  client: reactorClient,
5878
5978
  syncManager,
5879
5979
  documentModelRegistry,
5880
- readiness
5980
+ readiness,
5981
+ attachmentReferenceProjection
5881
5982
  };
5882
5983
  }
5883
5984
  //#endregion
@@ -5981,7 +6082,7 @@ var PackageManagementService = class {
5981
6082
  }
5982
6083
  };
5983
6084
  //#endregion
5984
- export { ADMIN_USERS, ActionContextInputSchema, ActionInputSchema, AddRelationshipDocument, AnalyticsSubgraph, AuthService, AuthSubgraph, AuthorizationPolicy, AuthorizedDocumentHandle, BaseSubgraph, ChannelMetaInputSchema, CreateDocumentDocument, CreateEmptyDocumentDocument, DeleteDocumentDocument, DeleteDocumentsDocument, DocumentChangeType, DocumentChangeTypeSchema, DocumentChangesDocument, DocumentOperationsFilterInputSchema, DocumentPermissionService, FindDocumentsDocument, GetDocumentDocument, GetDocumentIncomingRelationshipsDocument, GetDocumentModelsDocument, GetDocumentOperationsDocument, GetDocumentOutgoingRelationshipsDocument, GetDocumentWithOperationsDocument, GetJobStatusDocument, GraphQLManager, HttpDocumentModelLoader, HttpPackageLoader, ImportPackageLoader, InMemoryPackageStorage, JobChangesDocument, MoveRelationshipDocument, MutateDocumentAsyncDocument, MutateDocumentDocument, OperationContextInputSchema, OperationInputSchema, OperationWithContextInputSchema, OperationsFilterInputSchema, PackageManagementService, PackageManager, PackagesSubgraph, PagingInputSchema, PhDocumentFieldsFragmentDoc, PollSyncEnvelopesDocument, PropagationMode, PropagationModeSchema, PushSyncEnvelopesDocument, ReactorSignerAppInputSchema, ReactorSignerInputSchema, ReactorSignerUserInputSchema, ReactorSubgraph, RemoteCursorInputSchema, RemoteFilterInputSchema, RemoveRelationshipDocument, RenameDocumentDocument, SearchFilterInputSchema, SetPreferredEditorDocument, SyncEnvelopeInputSchema, SyncEnvelopeType, SyncEnvelopeTypeSchema, SystemSubgraph, TouchChannelDocument, TouchChannelInputSchema, ViewFilterInputSchema, assertAuthRequiredForDocumentPermissions, assertSkipCredentialVerificationAllowed, buildGraphQlDocument, buildGraphQlDriveDocument, buildGraphqlOperation, buildGraphqlOperations, buildSubgraphSchemaModule, createAuthFetchMiddleware, createGatewayAdapter, createHttpAdapter, createMergedSchema, createReactorGraphQLClient, createSchema, definedNonNullAnySchema, driveIdFromUrl, extractSubgraphsFromModule, generateDocumentModelSchema, getAuthContext, getDbClient, getDocumentModelSchemaName, getDocumentModelTypeDefs, getGitHash, getGitUrl, getSdk, getUniqueDocumentModels, getVersion, initAnalyticsStoreSql, initializeAndStartAPI, isDefinedNonNullAny, isExpectedLoaderMiss, isSubgraphClass, parseDriveUrl, renderGraphqlPlayground };
6085
+ export { ADMIN_USERS, ActionContextInputSchema, ActionInputSchema, AddRelationshipDocument, AnalyticsSubgraph, AttachmentAccessService, AuthService, AuthSubgraph, AuthorizationPolicy, AuthorizedDocumentHandle, BaseSubgraph, CanonicalDocumentIdResolutionError, ChannelMetaInputSchema, CreateDocumentDocument, CreateEmptyDocumentDocument, DeleteDocumentDocument, DeleteDocumentsDocument, DocumentChangeType, DocumentChangeTypeSchema, DocumentChangesDocument, DocumentOperationsFilterInputSchema, DocumentPermissionService, FindDocumentsDocument, GetDocumentDocument, GetDocumentIncomingRelationshipsDocument, GetDocumentModelsDocument, GetDocumentOperationsDocument, GetDocumentOutgoingRelationshipsDocument, GetDocumentWithOperationsDocument, GetJobStatusDocument, GraphQLManager, HttpDocumentModelLoader, HttpPackageLoader, ImportPackageLoader, InMemoryPackageStorage, JobChangesDocument, MoveRelationshipDocument, MutateDocumentAsyncDocument, MutateDocumentDocument, OperationContextInputSchema, OperationInputSchema, OperationWithContextInputSchema, OperationsFilterInputSchema, PackageManagementService, PackageManager, PackagesSubgraph, PagingInputSchema, PhDocumentFieldsFragmentDoc, PollSyncEnvelopesDocument, PropagationMode, PropagationModeSchema, PushSyncEnvelopesDocument, ReactorSignerAppInputSchema, ReactorSignerInputSchema, ReactorSignerUserInputSchema, ReactorSubgraph, RemoteCursorInputSchema, RemoteFilterInputSchema, RemoveRelationshipDocument, RenameDocumentDocument, SearchFilterInputSchema, SetPreferredEditorDocument, SyncEnvelopeInputSchema, SyncEnvelopeType, SyncEnvelopeTypeSchema, SystemSubgraph, TouchChannelDocument, TouchChannelInputSchema, ViewFilterInputSchema, assertAuthRequiredForDocumentPermissions, assertSkipCredentialVerificationAllowed, buildGraphQlDocument, buildGraphQlDriveDocument, buildGraphqlOperation, buildGraphqlOperations, buildSubgraphSchemaModule, createAuthFetchMiddleware, createCanonicalDocumentIdResolver, createGatewayAdapter, createHttpAdapter, createMergedSchema, createReactorGraphQLClient, createRenownCredentialVerifier, createSchema, definedNonNullAnySchema, driveIdFromUrl, extractSubgraphsFromModule, generateDocumentModelSchema, getAuthContext, getDbClient, getDocumentModelSchemaName, getDocumentModelTypeDefs, getGitHash, getGitUrl, getSdk, getUniqueDocumentModels, getVersion, initAnalyticsStoreSql, initializeAndStartAPI, isDefinedNonNullAny, isExpectedLoaderMiss, isSubgraphClass, parseDriveUrl, renderGraphqlPlayground };
5985
6086
 
5986
6087
  //# sourceMappingURL=index.mjs.map
5987
- //# debugId=e5e764e0-a390-5076-8849-48b393ff0087
6088
+ //# debugId=f661f924-a48f-516e-8739-859d08b54d00