@powerhousedao/reactor-drive 6.1.0-staging.0 → 6.2.0-dev.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/constants.ts","../src/types.ts","../src/actions.ts","../src/module.ts","../src/reducer/drive.ts","../src/schema/tables.ts","../src/schema/migrations/migrator.ts","../src/processors/utils/collisions.ts","../src/processors/node-processor.ts","../src/read-model/interfaces.ts","../src/read-model/drive-node-view.ts","../src/client/reactor-drive-client.ts","../src/subgraph/schema.ts","../src/subgraph/resolvers.ts","../src/migration/migrate-legacy-state.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/constants.ts","../src/types.ts","../src/actions.ts","../src/module.ts","../src/reducer/drive.ts","../src/schema/tables.ts","../src/schema/migrations/migrator.ts","../src/processors/utils/collisions.ts","../src/processors/node-processor.ts","../src/read-model/interfaces.ts","../src/read-model/drive-node-view.ts","../src/client/reactor-drive-client.ts","../src/subgraph/schema.ts","../src/subgraph/resolvers.ts","../src/migration/migrate-legacy-state.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -148,9 +148,7 @@ const reactorDriveCreateState = (state) => {
148
148
  };
149
149
  };
150
150
  const reactorDriveCreateDocument = (state) => {
151
- const document = baseCreateDocument(reactorDriveCreateState, state);
152
- document.header.documentType = REACTOR_DRIVE_DOCUMENT_TYPE;
153
- return document;
151
+ return baseCreateDocument(reactorDriveCreateState, state, REACTOR_DRIVE_DOCUMENT_TYPE);
154
152
  };
155
153
  const reactorDriveSaveToFileHandle = (document, input) => {
156
154
  return baseSaveToFileHandle(document, input);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["up","down","migration0001","migration0002","DEFAULT_LIMIT"],"sources":["../src/constants.ts","../src/actions.ts","../src/reducer/drive.ts","../src/module.ts","../src/schema/migrations/0001_drive_node.ts","../src/schema/migrations/0002_document_name.ts","../src/schema/migrations/migrator.ts","../src/processors/utils/collisions.ts","../src/processors/node-processor.ts","../src/read-model/drive-node-view.ts","../src/client/reactor-drive-client.ts","../src/subgraph/schema.ts","../src/subgraph/resolvers.ts","../src/migration/migrate-legacy-state.ts"],"sourcesContent":["export const REACTOR_DRIVE_DOCUMENT_TYPE = \"powerhouse/reactor-drive\";\n\nexport const DRIVE_CHILD_RELATIONSHIP_TYPE = \"drive/child\";\n\nexport const REACTOR_DRIVE_FILE_EXTENSION = \"phrd\";\n","import type { Action } from \"@powerhousedao/shared/document-model\";\nimport { generateId } from \"@powerhousedao/shared/document-model\";\nimport type {\n AddFolderActionInput,\n RemoveFolderActionInput,\n UpdateFolderActionInput,\n} from \"./types.js\";\n\nexport type SetDriveNameInput = { name: string };\nexport type SetDriveIconInput = { icon: string | null };\nexport type SetSharingTypeInput = { sharingType: string };\nexport type SetAvailableOfflineInput = { availableOffline: boolean };\n\nexport function setDriveNameAction(input: SetDriveNameInput): Action {\n return {\n id: generateId(),\n type: \"SET_DRIVE_NAME\",\n scope: \"global\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function setDriveIconAction(input: SetDriveIconInput): Action {\n return {\n id: generateId(),\n type: \"SET_DRIVE_ICON\",\n scope: \"global\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function setSharingTypeAction(input: SetSharingTypeInput): Action {\n return {\n id: generateId(),\n type: \"SET_SHARING_TYPE\",\n scope: \"local\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function setAvailableOfflineAction(\n input: SetAvailableOfflineInput,\n): Action {\n return {\n id: generateId(),\n type: \"SET_AVAILABLE_OFFLINE\",\n scope: \"local\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function addFolderAction(input: AddFolderActionInput): Action {\n return {\n id: generateId(),\n type: \"ADD_FOLDER\",\n scope: \"document\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function updateFolderAction(input: UpdateFolderActionInput): Action {\n return {\n id: generateId(),\n type: \"UPDATE_FOLDER\",\n scope: \"document\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function removeFolderAction(input: RemoveFolderActionInput): Action {\n return {\n id: generateId(),\n type: \"REMOVE_FOLDER\",\n scope: \"document\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport const reactorDriveActions = {\n setDriveName: setDriveNameAction,\n setDriveIcon: setDriveIconAction,\n setSharingType: setSharingTypeAction,\n setAvailableOffline: setAvailableOfflineAction,\n addFolder: addFolderAction,\n updateFolder: updateFolderAction,\n removeFolder: removeFolderAction,\n};\n","import type {\n Action,\n StateReducer,\n} from \"@powerhousedao/shared/document-model\";\nimport { isDocumentAction } from \"@powerhousedao/shared/document-model\";\nimport type {\n SetAvailableOfflineInput,\n SetDriveIconInput,\n SetDriveNameInput,\n SetSharingTypeInput,\n} from \"../actions.js\";\nimport type { ReactorDrivePHState } from \"../types.js\";\n\ntype TypedAction = Action & { type: string };\n\nexport const reactorDriveStateReducer: StateReducer<ReactorDrivePHState> = (\n state,\n action,\n) => {\n if (isDocumentAction(action)) {\n return state;\n }\n\n const typedAction = action as TypedAction;\n\n switch (typedAction.type) {\n case \"SET_DRIVE_NAME\": {\n const input = typedAction.input as SetDriveNameInput;\n state.global.name = input.name;\n return state;\n }\n case \"SET_DRIVE_ICON\": {\n const input = typedAction.input as SetDriveIconInput;\n state.global.icon = input.icon;\n return state;\n }\n case \"SET_SHARING_TYPE\": {\n const input = typedAction.input as SetSharingTypeInput;\n state.local.sharingType = input.sharingType;\n return state;\n }\n case \"SET_AVAILABLE_OFFLINE\": {\n const input = typedAction.input as SetAvailableOfflineInput;\n state.local.availableOffline = input.availableOffline;\n return state;\n }\n case \"ADD_FOLDER\":\n case \"UPDATE_FOLDER\":\n case \"REMOVE_FOLDER\":\n // Identity: folder ops are recorded for sync and materialized by NodeProcessor.\n return state;\n default:\n return state;\n }\n};\n","import type {\n AssertIsDocumentOfType,\n AssertIsStateOfType,\n CreateDocument,\n CreateState,\n DocumentModelGlobalState,\n IsDocumentOfType,\n IsStateOfType,\n LoadFromInput,\n PHDocument,\n SaveToFileHandle,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n baseCreateDocument,\n baseLoadFromInput,\n baseSaveToFileHandle,\n createReducer,\n createState,\n defaultBaseState,\n} from \"@powerhousedao/shared/document-model\";\nimport { reactorDriveActions } from \"./actions.js\";\nimport {\n REACTOR_DRIVE_DOCUMENT_TYPE,\n REACTOR_DRIVE_FILE_EXTENSION,\n} from \"./constants.js\";\nimport { reactorDriveStateReducer } from \"./reducer/drive.js\";\nimport type {\n ReactorDriveDocumentModelModule,\n ReactorDriveGlobalState,\n ReactorDriveLocalState,\n ReactorDrivePHState,\n} from \"./types.js\";\n\nconst initialGlobalState: ReactorDriveGlobalState = {\n name: \"\",\n icon: null,\n};\n\nconst initialLocalState: ReactorDriveLocalState = {\n sharingType: \"private\",\n availableOffline: false,\n};\n\nexport const reactorDriveCreateState: CreateState<ReactorDrivePHState> = (\n state,\n) => {\n return {\n ...defaultBaseState(),\n global: { ...initialGlobalState, ...state?.global },\n local: { ...initialLocalState, ...state?.local },\n };\n};\n\nexport const reactorDriveCreateDocument: CreateDocument<ReactorDrivePHState> = (\n state,\n) => {\n const document = baseCreateDocument(reactorDriveCreateState, state);\n document.header.documentType = REACTOR_DRIVE_DOCUMENT_TYPE;\n return document;\n};\n\nconst reactorDriveSaveToFileHandle: SaveToFileHandle = (document, input) => {\n return baseSaveToFileHandle(document, input);\n};\n\nconst reactorDriveLoadFromInput: LoadFromInput<ReactorDrivePHState> = (\n input,\n) => {\n return baseLoadFromInput(input, reactorDriveDocumentReducer);\n};\n\nconst isReactorDriveState: IsStateOfType<ReactorDrivePHState> = (\n state,\n): state is ReactorDrivePHState => {\n return (\n typeof state === \"object\" &&\n state !== null &&\n \"global\" in state &&\n \"local\" in state\n );\n};\n\nconst assertIsReactorDriveState: AssertIsStateOfType<ReactorDrivePHState> = (\n state,\n) => {\n if (!isReactorDriveState(state)) {\n throw new Error(\"Not a reactor-drive state\");\n }\n};\n\nconst isReactorDriveDocument: IsDocumentOfType<ReactorDrivePHState> = (\n document,\n): document is PHDocument<ReactorDrivePHState> => {\n return (\n typeof document === \"object\" &&\n document !== null &&\n \"header\" in document &&\n (document as { header: { documentType: string } }).header.documentType ===\n REACTOR_DRIVE_DOCUMENT_TYPE\n );\n};\n\nconst assertIsReactorDriveDocument: AssertIsDocumentOfType<\n ReactorDrivePHState\n> = (document) => {\n if (!isReactorDriveDocument(document)) {\n throw new Error(\"Not a reactor-drive document\");\n }\n};\n\nexport const reactorDriveDocumentReducer = createReducer<ReactorDrivePHState>(\n reactorDriveStateReducer,\n);\n\nconst reactorDriveDocumentGlobalState: DocumentModelGlobalState = {\n id: REACTOR_DRIVE_DOCUMENT_TYPE,\n name: \"ReactorDrive\",\n extension: REACTOR_DRIVE_FILE_EXTENSION,\n description: \"\",\n author: {\n name: \"Powerhouse Inc\",\n website: \"https://www.powerhouse.inc/\",\n },\n specifications: [\n {\n version: 1,\n changeLog: [],\n state: {\n global: {\n schema:\n \"type ReactorDriveState {\\n name: String!\\n icon: String\\n}\",\n // Double-encoded by convention: `initialValue` holds a JSON-encoded string that consumers parse with JSON.parse.\n initialValue: JSON.stringify(JSON.stringify(initialGlobalState)),\n examples: [],\n },\n local: {\n schema:\n \"type ReactorDriveLocalState {\\n sharingType: String!\\n availableOffline: Boolean!\\n}\",\n // Double-encoded by convention: `initialValue` holds a JSON-encoded string that consumers parse with JSON.parse.\n initialValue: JSON.stringify(JSON.stringify(initialLocalState)),\n examples: [],\n },\n },\n modules: [\n {\n id: \"reactor-drive/base-operations\",\n name: \"base_operations\",\n description: \"\",\n operations: [\n {\n id: \"SET_DRIVE_NAME\",\n name: \"SET_DRIVE_NAME\",\n description: \"\",\n schema: \"input SetDriveNameInput { name: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"global\",\n },\n {\n id: \"SET_DRIVE_ICON\",\n name: \"SET_DRIVE_ICON\",\n description: \"\",\n schema: \"input SetDriveIconInput { icon: String }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"global\",\n },\n {\n id: \"SET_SHARING_TYPE\",\n name: \"SET_SHARING_TYPE\",\n description: \"\",\n schema: \"input SetSharingTypeInput { sharingType: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"local\",\n },\n {\n id: \"SET_AVAILABLE_OFFLINE\",\n name: \"SET_AVAILABLE_OFFLINE\",\n description: \"\",\n schema:\n \"input SetAvailableOfflineInput { availableOffline: Boolean! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"local\",\n },\n {\n id: \"ADD_FOLDER\",\n name: \"ADD_FOLDER\",\n description: \"\",\n schema:\n \"input AddFolderInput { folderId: String! parentFolderId: String name: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"document\",\n },\n {\n id: \"UPDATE_FOLDER\",\n name: \"UPDATE_FOLDER\",\n description: \"\",\n schema:\n \"input UpdateFolderInput { folderId: String! name: String parentFolderId: String }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"document\",\n },\n {\n id: \"REMOVE_FOLDER\",\n name: \"REMOVE_FOLDER\",\n description: \"\",\n schema: \"input RemoveFolderInput { folderId: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"document\",\n },\n ],\n },\n ],\n },\n ],\n};\n\nexport const reactorDriveDocumentModelModule: ReactorDriveDocumentModelModule =\n {\n actions: reactorDriveActions,\n reducer: reactorDriveDocumentReducer,\n documentModel: createState(\n defaultBaseState(),\n reactorDriveDocumentGlobalState,\n ),\n utils: {\n fileExtension: REACTOR_DRIVE_FILE_EXTENSION,\n createState: reactorDriveCreateState,\n createDocument: reactorDriveCreateDocument,\n loadFromInput: reactorDriveLoadFromInput,\n saveToFileHandle: reactorDriveSaveToFileHandle,\n isStateOfType: isReactorDriveState,\n assertIsStateOfType: assertIsReactorDriveState,\n isDocumentOfType: isReactorDriveDocument,\n assertIsDocumentOfType: assertIsReactorDriveDocument,\n },\n };\n","import type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nexport async function up(db: Kysely<unknown>): Promise<void> {\n await db.schema\n .createTable(\"DriveNode\")\n .ifNotExists()\n .addColumn(\"driveId\", \"text\", (col) => col.notNull())\n .addColumn(\"id\", \"text\", (col) => col.notNull())\n .addColumn(\"kind\", \"text\", (col) => col.notNull())\n .addColumn(\"name\", \"text\", (col) => col.notNull())\n .addColumn(\"requestedName\", \"text\", (col) => col.notNull())\n .addColumn(\"parentFolder\", \"text\")\n .addColumn(\"documentType\", \"text\")\n .addColumn(\"createdAt\", \"timestamptz\", (col) =>\n col.notNull().defaultTo(sql`NOW()`),\n )\n .addColumn(\"updatedAt\", \"timestamptz\", (col) =>\n col.notNull().defaultTo(sql`NOW()`),\n )\n .addPrimaryKeyConstraint(\"pk_drive_node\", [\"driveId\", \"id\"])\n .addCheckConstraint(\n \"chk_drive_node_document_type\",\n sql`(kind = 'file' AND \"documentType\" IS NOT NULL) OR (kind = 'folder' AND \"documentType\" IS NULL)`,\n )\n .execute();\n\n await db.schema\n .createIndex(\"idx_drive_node_parent_name\")\n .ifNotExists()\n .on(\"DriveNode\")\n .columns([\"driveId\", \"parentFolder\", \"name\"])\n .execute();\n\n await db.schema\n .createIndex(\"idx_drive_node_parent_kind_id\")\n .ifNotExists()\n .on(\"DriveNode\")\n .columns([\"driveId\", \"parentFolder\", \"kind\", \"id\"])\n .execute();\n}\n\nexport async function down(db: Kysely<unknown>): Promise<void> {\n await db.schema.dropTable(\"DriveNode\").execute();\n}\n","import type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nexport async function up(db: Kysely<unknown>): Promise<void> {\n await db.schema\n .createTable(\"DocumentName\")\n .ifNotExists()\n .addColumn(\"docId\", \"text\", (col) => col.primaryKey())\n .addColumn(\"name\", \"text\", (col) => col.notNull())\n .addColumn(\"updatedAt\", \"timestamptz\", (col) =>\n col.notNull().defaultTo(sql`NOW()`),\n )\n .execute();\n}\n\nexport async function down(db: Kysely<unknown>): Promise<void> {\n await db.schema.dropTable(\"DocumentName\").execute();\n}\n","import type { Kysely, MigrationProvider } from \"kysely\";\nimport { Migrator, sql } from \"kysely\";\nimport * as migration0001 from \"./0001_drive_node.js\";\nimport * as migration0002 from \"./0002_document_name.js\";\n\nconst migrations = {\n \"0001_drive_node\": migration0001,\n \"0002_document_name\": migration0002,\n};\n\nconst REACTOR_DRIVE_MIGRATION_TABLE = \"kysely_migration_reactor_drive\";\nconst REACTOR_DRIVE_MIGRATION_LOCK_TABLE =\n \"kysely_migration_reactor_drive_lock\";\n\nexport interface ReactorDriveMigrationResult {\n success: boolean;\n migrationsExecuted: string[];\n error?: Error;\n}\n\nclass ProgrammaticMigrationProvider implements MigrationProvider {\n getMigrations() {\n return Promise.resolve(migrations);\n }\n}\n\nexport async function runReactorDriveMigrations(\n db: Kysely<unknown>,\n schema: string,\n): Promise<ReactorDriveMigrationResult> {\n try {\n await sql`CREATE SCHEMA IF NOT EXISTS ${sql.id(schema)}`.execute(db);\n } catch (error) {\n return {\n success: false,\n migrationsExecuted: [],\n error:\n error instanceof Error ? error : new Error(\"Failed to create schema\"),\n };\n }\n\n const migrator = new Migrator({\n db: db.withSchema(schema),\n provider: new ProgrammaticMigrationProvider(),\n migrationTableSchema: schema,\n migrationTableName: REACTOR_DRIVE_MIGRATION_TABLE,\n migrationLockTableName: REACTOR_DRIVE_MIGRATION_LOCK_TABLE,\n });\n\n let error: unknown;\n let results: Awaited<ReturnType<typeof migrator.migrateToLatest>>[\"results\"];\n try {\n const result = await migrator.migrateToLatest();\n error = result.error;\n results = result.results;\n } catch (e) {\n error = e;\n results = [];\n }\n\n const migrationsExecuted =\n results?.map((result) => result.migrationName) ?? [];\n\n if (error) {\n return {\n success: false,\n migrationsExecuted,\n error:\n error instanceof Error ? error : new Error(\"Unknown migration error\"),\n };\n }\n\n return {\n success: true,\n migrationsExecuted,\n };\n}\n\nexport async function getReactorDriveMigrationStatus(\n db: Kysely<unknown>,\n schema: string,\n) {\n const migrator = new Migrator({\n db: db.withSchema(schema),\n provider: new ProgrammaticMigrationProvider(),\n migrationTableSchema: schema,\n migrationTableName: REACTOR_DRIVE_MIGRATION_TABLE,\n migrationLockTableName: REACTOR_DRIVE_MIGRATION_LOCK_TABLE,\n });\n\n return await migrator.getMigrations();\n}\n","/**\n * Deterministic per-folder name collision rule. Given a desired name and the\n * set of names already taken by siblings, returns the next available name as\n * `requested`, `requested (2)`, `requested (3)`, etc.\n *\n * The rule matches the legacy document-drive module so that migration from\n * the legacy state produces stable suffixes.\n */\nexport function resolveCollision(\n requested: string,\n takenNames: Iterable<string>,\n): string {\n const taken = new Set<string>();\n for (const name of takenNames) {\n taken.add(name);\n }\n\n if (!taken.has(requested)) {\n return requested;\n }\n\n let suffix = 2;\n while (taken.has(`${requested} (${suffix})`)) {\n suffix += 1;\n }\n return `${requested} (${suffix})`;\n}\n","import type { IOperationIndex, IWriteCache } from \"@powerhousedao/reactor\";\nimport {\n BaseReadModel,\n type DocumentViewDatabase,\n type IConsistencyTracker,\n} from \"@powerhousedao/reactor\";\nimport type {\n AddRelationshipActionInput,\n CreateDocumentActionInput,\n DeleteDocumentActionInput,\n OperationWithContext,\n RemoveRelationshipActionInput,\n SetNameActionInput,\n UpgradeDocumentActionInput,\n} from \"@powerhousedao/shared/document-model\";\nimport type { Kysely, Transaction } from \"kysely\";\nimport {\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n REACTOR_DRIVE_DOCUMENT_TYPE,\n} from \"../constants.js\";\nimport { runReactorDriveMigrations } from \"../schema/migrations/migrator.js\";\nimport type { ReactorDriveDatabase } from \"../schema/tables.js\";\nimport type {\n AddFolderActionInput,\n DriveChildFileMetadata,\n RemoveFolderActionInput,\n UpdateFolderActionInput,\n} from \"../types.js\";\nimport { resolveCollision } from \"./utils/collisions.js\";\n\nexport type NodeProcessorDatabase = ReactorDriveDatabase & DocumentViewDatabase;\n\nconst NAME_ACTION_TYPES = new Set([\n \"CREATE_DOCUMENT\",\n \"UPGRADE_DOCUMENT\",\n \"SET_NAME\",\n]);\n\nconst STRUCTURE_ACTION_TYPES = new Set([\n \"ADD_RELATIONSHIP\",\n \"REMOVE_RELATIONSHIP\",\n \"ADD_FOLDER\",\n \"UPDATE_FOLDER\",\n \"REMOVE_FOLDER\",\n]);\n\nexport class NodeProcessor extends BaseReadModel {\n private readonly driveDb: Kysely<NodeProcessorDatabase>;\n private readonly baseDb: Kysely<unknown>;\n private readonly schema: string;\n\n constructor(\n baseDb: Kysely<unknown>,\n schema: string,\n operationIndex: IOperationIndex,\n writeCache: IWriteCache,\n consistencyTracker: IConsistencyTracker,\n ) {\n const scopedDb = baseDb.withSchema(\n schema,\n ) as unknown as Kysely<NodeProcessorDatabase>;\n super(\n scopedDb as unknown as Kysely<DocumentViewDatabase>,\n operationIndex,\n writeCache,\n consistencyTracker,\n {\n readModelId: \"reactor-drive-node-processor\",\n rebuildStateOnInit: false,\n },\n );\n this.driveDb = scopedDb;\n this.baseDb = baseDb;\n this.schema = schema;\n }\n\n override async init(): Promise<void> {\n const result = await runReactorDriveMigrations(this.baseDb, this.schema);\n if (!result.success && result.error) {\n throw new Error(\n `Reactor drive migrations failed: ${result.error.message}`,\n );\n }\n await super.init();\n }\n\n protected override async commitOperations(\n items: OperationWithContext[],\n ): Promise<void> {\n await this.driveDb.transaction().execute(async (trx) => {\n for (const item of items) {\n const actionType = item.operation.action.type;\n if (NAME_ACTION_TYPES.has(actionType)) {\n await this.applyNameOperation(trx, item);\n continue;\n }\n if (STRUCTURE_ACTION_TYPES.has(actionType)) {\n await this.applyStructureOperation(trx, item);\n continue;\n }\n if (actionType === \"DELETE_DOCUMENT\") {\n await this.applyDeleteDocument(trx, item);\n }\n }\n });\n }\n\n private async applyNameOperation(\n trx: Transaction<NodeProcessorDatabase>,\n item: OperationWithContext,\n ): Promise<void> {\n const action = item.operation.action;\n const docId = item.context.documentId;\n let name: string | undefined;\n\n if (action.type === \"CREATE_DOCUMENT\") {\n const input = action.input as CreateDocumentActionInput;\n name = input.name;\n } else if (action.type === \"UPGRADE_DOCUMENT\") {\n const input = action.input as UpgradeDocumentActionInput;\n const initial = (input.initialState ?? {}) as {\n header?: { name?: string };\n };\n name = initial.header?.name;\n } else if (action.type === \"SET_NAME\") {\n const input = action.input as SetNameActionInput;\n name = input.name;\n }\n\n if (name === undefined) {\n return;\n }\n\n await this.upsertDocumentName(trx, docId, name);\n\n const linkedRows = await trx\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"id\", \"=\", docId)\n .where(\"kind\", \"=\", \"file\")\n .execute();\n\n for (const row of linkedRows) {\n const resolved = await this.resolveSiblingName(\n trx,\n row.driveId,\n row.parentFolder,\n name,\n docId,\n );\n await trx\n .updateTable(\"DriveNode\")\n .set({\n name: resolved,\n requestedName: name,\n updatedAt: new Date(),\n })\n .where(\"driveId\", \"=\", row.driveId)\n .where(\"id\", \"=\", docId)\n .execute();\n }\n }\n\n private async applyStructureOperation(\n trx: Transaction<NodeProcessorDatabase>,\n item: OperationWithContext,\n ): Promise<void> {\n if (item.context.documentType !== REACTOR_DRIVE_DOCUMENT_TYPE) {\n return;\n }\n\n const action = item.operation.action;\n const driveId = item.context.documentId;\n\n if (action.type === \"ADD_RELATIONSHIP\") {\n const input = action.input as AddRelationshipActionInput;\n if (input.relationshipType !== DRIVE_CHILD_RELATIONSHIP_TYPE) return;\n await this.handleAddFileRelationship(trx, driveId, input);\n return;\n }\n\n if (action.type === \"REMOVE_RELATIONSHIP\") {\n const input = action.input as RemoveRelationshipActionInput;\n if (input.relationshipType !== DRIVE_CHILD_RELATIONSHIP_TYPE) return;\n await trx\n .deleteFrom(\"DriveNode\")\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.targetId)\n .execute();\n return;\n }\n\n if (action.type === \"ADD_FOLDER\") {\n await this.handleAddFolder(\n trx,\n driveId,\n action.input as AddFolderActionInput,\n );\n return;\n }\n\n if (action.type === \"UPDATE_FOLDER\") {\n await this.handleUpdateFolder(\n trx,\n driveId,\n action.input as UpdateFolderActionInput,\n );\n return;\n }\n\n if (action.type === \"REMOVE_FOLDER\") {\n const input = action.input as RemoveFolderActionInput;\n await trx\n .deleteFrom(\"DriveNode\")\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.folderId)\n .execute();\n }\n }\n\n private async applyDeleteDocument(\n trx: Transaction<NodeProcessorDatabase>,\n item: OperationWithContext,\n ): Promise<void> {\n const input = item.operation.action.input as DeleteDocumentActionInput;\n const docId = input.documentId || item.context.documentId;\n\n await trx.deleteFrom(\"DriveNode\").where(\"id\", \"=\", docId).execute();\n await trx.deleteFrom(\"DocumentName\").where(\"docId\", \"=\", docId).execute();\n }\n\n private async handleAddFileRelationship(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n input: AddRelationshipActionInput,\n ): Promise<void> {\n const metadata = this.parseFileMetadata(input);\n const parentFolder = metadata.parentFolderId ?? null;\n const documentType = metadata.documentType;\n\n const requestedName =\n (await this.lookupDocumentName(trx, input.targetId)) ?? \"\";\n\n const resolved = await this.resolveSiblingName(\n trx,\n driveId,\n parentFolder,\n requestedName,\n input.targetId,\n );\n\n await trx\n .insertInto(\"DriveNode\")\n .values({\n driveId,\n id: input.targetId,\n kind: \"file\",\n name: resolved,\n requestedName,\n parentFolder,\n documentType,\n })\n .onConflict((oc) =>\n oc.columns([\"driveId\", \"id\"]).doUpdateSet({\n parentFolder,\n name: resolved,\n requestedName,\n kind: \"file\",\n documentType,\n updatedAt: new Date(),\n }),\n )\n .execute();\n }\n\n private async handleAddFolder(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n input: AddFolderActionInput,\n ): Promise<void> {\n const parentFolder = input.parentFolderId ?? null;\n const resolved = await this.resolveSiblingName(\n trx,\n driveId,\n parentFolder,\n input.name,\n input.folderId,\n );\n\n await trx\n .insertInto(\"DriveNode\")\n .values({\n driveId,\n id: input.folderId,\n kind: \"folder\",\n name: resolved,\n requestedName: input.name,\n parentFolder,\n documentType: null,\n })\n .onConflict((oc) =>\n oc.columns([\"driveId\", \"id\"]).doUpdateSet({\n parentFolder,\n name: resolved,\n requestedName: input.name,\n kind: \"folder\",\n documentType: null,\n updatedAt: new Date(),\n }),\n )\n .execute();\n }\n\n private async handleUpdateFolder(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n input: UpdateFolderActionInput,\n ): Promise<void> {\n const row = await trx\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.folderId)\n .executeTakeFirst();\n if (!row) return;\n\n const nextParentFolder =\n input.parentFolderId === undefined\n ? row.parentFolder\n : (input.parentFolderId ?? null);\n const nextRequestedName =\n typeof input.name === \"string\" ? input.name : row.requestedName;\n\n const resolved = await this.resolveSiblingName(\n trx,\n driveId,\n nextParentFolder,\n nextRequestedName,\n input.folderId,\n );\n\n await trx\n .updateTable(\"DriveNode\")\n .set({\n parentFolder: nextParentFolder,\n name: resolved,\n requestedName: nextRequestedName,\n updatedAt: new Date(),\n })\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.folderId)\n .execute();\n }\n\n private async resolveSiblingName(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n parentFolder: string | null,\n requested: string,\n excludeId: string,\n ): Promise<string> {\n let query = trx\n .selectFrom(\"DriveNode\")\n .select(\"name\")\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"!=\", excludeId);\n query =\n parentFolder === null\n ? query.where(\"parentFolder\", \"is\", null)\n : query.where(\"parentFolder\", \"=\", parentFolder);\n\n const rows = await query.execute();\n return resolveCollision(\n requested,\n rows.map((r) => r.name),\n );\n }\n\n private async lookupDocumentName(\n trx: Transaction<NodeProcessorDatabase>,\n docId: string,\n ): Promise<string | undefined> {\n const row = await trx\n .selectFrom(\"DocumentName\")\n .select(\"name\")\n .where(\"docId\", \"=\", docId)\n .executeTakeFirst();\n return row?.name;\n }\n\n private parseFileMetadata(\n input: AddRelationshipActionInput,\n ): DriveChildFileMetadata {\n const metadata = input.metadata;\n if (\n !metadata ||\n typeof metadata !== \"object\" ||\n (metadata as { kind?: unknown }).kind !== \"file\" ||\n typeof (metadata as { documentType?: unknown }).documentType !== \"string\"\n ) {\n throw new Error(\n `ADD_RELATIONSHIP for target ${input.targetId}: missing or invalid drive/child file metadata (expected { kind: \"file\", parentFolderId, documentType })`,\n );\n }\n const typed = metadata as DriveChildFileMetadata;\n return {\n kind: \"file\",\n parentFolderId: typed.parentFolderId ?? null,\n documentType: typed.documentType,\n };\n }\n\n private async upsertDocumentName(\n trx: Transaction<NodeProcessorDatabase>,\n docId: string,\n name: string,\n ): Promise<void> {\n await trx\n .insertInto(\"DocumentName\")\n .values({ docId, name })\n .onConflict((oc) =>\n oc.column(\"docId\").doUpdateSet({ name, updatedAt: new Date() }),\n )\n .execute();\n }\n}\n","import { type PagedResults, type PagingOptions } from \"@powerhousedao/reactor\";\nimport type { Kysely } from \"kysely\";\nimport type { ReactorDriveDatabase } from \"../schema/tables.js\";\nimport type {\n ReactorDriveFileNode,\n ReactorDriveFolderNode,\n ReactorDriveNode,\n} from \"../types.js\";\nimport type { IDriveReadModel } from \"./interfaces.js\";\n\nconst DEFAULT_LIMIT = 100;\n\ntype KeysetCursor = {\n createdAt: Date;\n id: string;\n};\n\nfunction parseListChildrenPaging(paging: PagingOptions | undefined): {\n limit: number;\n cursor: KeysetCursor | null;\n} {\n if (paging === undefined) {\n return { limit: DEFAULT_LIMIT, cursor: null };\n }\n if (!Number.isInteger(paging.limit) || paging.limit < 1) {\n throw new Error(\n `Invalid paging limit: ${String(paging.limit)} (must be an integer >= 1)`,\n );\n }\n if (paging.cursor === \"\") {\n return { limit: paging.limit, cursor: null };\n }\n return { limit: paging.limit, cursor: decodeKeysetCursor(paging.cursor) };\n}\n\nfunction encodeKeysetCursor(createdAt: Date, id: string): string {\n return globalThis.btoa(\n JSON.stringify({ createdAt: createdAt.toISOString(), id }),\n );\n}\n\nfunction decodeKeysetCursor(cursor: string): KeysetCursor {\n let decoded: string;\n try {\n decoded = globalThis.atob(cursor);\n } catch {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (must be a keyset cursor returned by a prior page)`,\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(decoded);\n } catch {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (must be a keyset cursor returned by a prior page)`,\n );\n }\n if (\n parsed === null ||\n typeof parsed !== \"object\" ||\n typeof (parsed as { createdAt?: unknown }).createdAt !== \"string\" ||\n typeof (parsed as { id?: unknown }).id !== \"string\"\n ) {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (must be a keyset cursor returned by a prior page)`,\n );\n }\n const createdAt = new Date((parsed as { createdAt: string }).createdAt);\n if (Number.isNaN(createdAt.getTime())) {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (createdAt is not a valid timestamp)`,\n );\n }\n return { createdAt, id: (parsed as { id: string }).id };\n}\n\nexport class DriveNodeView implements IDriveReadModel {\n constructor(private readonly db: Kysely<ReactorDriveDatabase>) {}\n\n async getNode(\n driveId: string,\n nodeId: string,\n ): Promise<ReactorDriveNode | undefined> {\n const row = await this.db\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", nodeId)\n .executeTakeFirst();\n if (!row) return undefined;\n return rowToNode(row);\n }\n\n async listChildren(\n driveId: string,\n parentFolder: string | null | undefined,\n paging?: PagingOptions,\n ): Promise<PagedResults<ReactorDriveNode>> {\n const { limit, cursor } = parseListChildrenPaging(paging);\n\n let query = this.db\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId);\n\n if (parentFolder === null) {\n query = query.where(\"parentFolder\", \"is\", null);\n } else if (parentFolder !== undefined) {\n query = query.where(\"parentFolder\", \"=\", parentFolder);\n }\n\n if (cursor !== null) {\n query = query.where((eb) =>\n eb(\n eb.refTuple(\"createdAt\", \"id\"),\n \">\",\n eb.tuple(cursor.createdAt, cursor.id),\n ),\n );\n }\n\n const rows = await query\n .orderBy(\"createdAt\", \"asc\")\n .orderBy(\"id\", \"asc\")\n .limit(limit + 1)\n .execute();\n\n const hasMore = rows.length > limit;\n const sliced = hasMore ? rows.slice(0, limit) : rows;\n const last = sliced[sliced.length - 1];\n\n return {\n results: sliced.map(rowToNode),\n options: { cursor: paging?.cursor ?? \"\", limit },\n nextCursor: hasMore\n ? encodeKeysetCursor(last.createdAt, last.id)\n : undefined,\n };\n }\n\n async listAll(driveId: string): Promise<ReactorDriveNode[]> {\n const rows = await this.db\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId)\n .orderBy(\"createdAt\", \"asc\")\n .orderBy(\"id\", \"asc\")\n .execute();\n return rows.map(rowToNode);\n }\n\n async getDescendants(\n driveId: string,\n root: string,\n ): Promise<ReactorDriveNode[]> {\n const rows = await this.db\n .withRecursive(\"descendants\", (qb) =>\n qb\n .selectFrom(\"DriveNode\")\n .select([\n \"driveId\",\n \"id\",\n \"kind\",\n \"name\",\n \"requestedName\",\n \"parentFolder\",\n \"documentType\",\n \"createdAt\",\n ])\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", root)\n .unionAll(\n qb\n .selectFrom(\"DriveNode\")\n .innerJoin(\n \"descendants\",\n \"DriveNode.parentFolder\",\n \"descendants.id\",\n )\n .where(\"DriveNode.driveId\", \"=\", driveId)\n .select([\n \"DriveNode.driveId\",\n \"DriveNode.id\",\n \"DriveNode.kind\",\n \"DriveNode.name\",\n \"DriveNode.requestedName\",\n \"DriveNode.parentFolder\",\n \"DriveNode.documentType\",\n \"DriveNode.createdAt\",\n ]),\n ),\n )\n .selectFrom(\"descendants\")\n .select([\n \"driveId\",\n \"id\",\n \"kind\",\n \"name\",\n \"requestedName\",\n \"parentFolder\",\n \"documentType\",\n ])\n .orderBy(\"createdAt\", \"asc\")\n .orderBy(\"id\", \"asc\")\n .execute();\n return rows.map(rowToNode);\n }\n}\n\ntype DriveNodeRow = {\n driveId: string;\n id: string;\n kind: \"file\" | \"folder\";\n name: string;\n requestedName: string;\n parentFolder: string | null;\n documentType: string | null;\n};\n\nfunction rowToNode(row: DriveNodeRow): ReactorDriveNode {\n if (row.kind === \"file\") {\n if (row.documentType === null) {\n throw new Error(\n `DriveNode ${row.driveId}/${row.id}: file row has null documentType, which violates the schema CHECK constraint`,\n );\n }\n const node: ReactorDriveFileNode = {\n kind: \"file\",\n id: row.id,\n driveId: row.driveId,\n parentFolder: row.parentFolder,\n name: row.name,\n documentType: row.documentType,\n };\n return node;\n }\n const node: ReactorDriveFolderNode = {\n kind: \"folder\",\n id: row.id,\n driveId: row.driveId,\n parentFolder: row.parentFolder,\n name: row.name,\n };\n return node;\n}\n","import {\n addRelationshipAction,\n createDocumentAction,\n removeRelationshipAction,\n upgradeDocumentAction,\n type BatchExecutionRequest,\n type ExecutionJobPlan,\n type IDriveClient,\n type IReactorClient,\n type PagedResults,\n type PagingOptions,\n type PropagationMode,\n} from \"@powerhousedao/reactor\";\nimport type {\n DocumentDriveDocument,\n DriveInput,\n FileNode,\n FolderNode,\n Node,\n} from \"@powerhousedao/shared/document-drive\";\nimport {\n createPresignedHeader,\n generateId,\n replayDocument,\n type Action,\n type CreateDocumentActionInput,\n type PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n REACTOR_DRIVE_DOCUMENT_TYPE,\n} from \"../constants.js\";\nimport {\n addFolderAction,\n removeFolderAction,\n setAvailableOfflineAction,\n setDriveIconAction,\n setDriveNameAction,\n setSharingTypeAction,\n updateFolderAction,\n} from \"../actions.js\";\nimport { reactorDriveCreateDocument } from \"../module.js\";\nimport type { IDriveReadModel } from \"../read-model/interfaces.js\";\nimport type {\n DriveChildFileMetadata,\n ReactorDriveFileNode,\n ReactorDriveFolderNode,\n ReactorDriveNode,\n} from \"../types.js\";\n\nexport interface ReactorDriveClientArgs {\n reactor: IReactorClient;\n readModel: IDriveReadModel;\n}\n\n/**\n * Implementation of {@link IDriveClient} backed by the reactor's relationship\n * primitives and the drive-scoped folder actions. Folder structure lives in\n * the operation log (ADD_FOLDER/UPDATE_FOLDER/REMOVE_FOLDER + ADD_RELATIONSHIP\n * for files) and is materialised by `NodeProcessor` into the `DriveNode`\n * table consumed via {@link IDriveReadModel}.\n */\nexport class ReactorDriveClient implements IDriveClient {\n private readonly reactor: IReactorClient;\n private readonly readModel: IDriveReadModel;\n\n constructor(args: ReactorDriveClientArgs) {\n this.reactor = args.reactor;\n this.readModel = args.readModel;\n }\n\n async create(\n input: DriveInput,\n signal?: AbortSignal,\n ): Promise<DocumentDriveDocument> {\n const driveDoc = reactorDriveCreateDocument({\n global: {\n name: input.global.name,\n icon: input.global.icon ?? null,\n },\n });\n if (input.local) {\n if (typeof input.local.sharingType === \"string\") {\n driveDoc.state.local.sharingType = input.local.sharingType;\n }\n if (typeof input.local.availableOffline === \"boolean\") {\n driveDoc.state.local.availableOffline = input.local.availableOffline;\n }\n }\n if (input.preferredEditor) {\n driveDoc.header.meta = {\n ...driveDoc.header.meta,\n preferredEditor: input.preferredEditor,\n };\n }\n const created = await this.reactor.create(driveDoc, undefined, signal);\n return this.toLegacyDriveDocument(created, created.header.id);\n }\n\n async addFile<TDocument extends PHDocument = PHDocument>(\n driveIdentifier: string,\n document: PHDocument,\n parentFolder?: string,\n signal?: AbortSignal,\n ): Promise<TDocument> {\n const documentId = document.header.id;\n\n const createInput: CreateDocumentActionInput = {\n model: document.header.documentType,\n version: 0,\n documentId,\n signing: {\n signature: documentId,\n publicKey: document.header.sig.publicKey,\n nonce: document.header.sig.nonce,\n createdAtUtcIso: document.header.createdAtUtcIso,\n documentType: document.header.documentType,\n },\n slug: document.header.slug,\n name: document.header.name,\n branch: document.header.branch,\n meta: document.header.meta,\n protocolVersions: document.header.protocolVersions ?? {\n \"base-reducer\": 2,\n },\n };\n\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: parentFolder ?? null,\n documentType: document.header.documentType,\n };\n\n const request: BatchExecutionRequest = {\n jobs: [\n {\n key: \"create\",\n documentId,\n scope: \"document\",\n branch: \"main\",\n actions: [\n createDocumentAction(createInput),\n upgradeDocumentAction({\n documentId,\n model: document.header.documentType,\n fromVersion: 0,\n toVersion: document.state.document.version,\n initialState: document.state,\n }),\n ],\n dependsOn: [],\n },\n {\n key: \"link\",\n documentId: driveIdentifier,\n scope: \"document\",\n branch: \"main\",\n actions: [\n addRelationshipAction(\n driveIdentifier,\n documentId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n ),\n ],\n dependsOn: [\"create\"],\n },\n ],\n };\n\n await this.reactor.executeBatch(request, signal);\n return this.reactor.get<TDocument>(documentId, undefined, signal);\n }\n\n async addFolder(\n driveIdentifier: string,\n name: string,\n parentFolder?: string,\n signal?: AbortSignal,\n ): Promise<FolderNode> {\n const folderId = generateId();\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n addFolderAction({\n folderId,\n parentFolderId: parentFolder ?? null,\n name,\n }),\n ],\n signal,\n );\n return {\n id: folderId,\n kind: \"folder\",\n name,\n parentFolder: parentFolder ?? null,\n };\n }\n\n async removeNode(\n driveIdentifier: string,\n nodeId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n const node = await this.readModel.getNode(driveIdentifier, nodeId, signal);\n if (!node) {\n throw new Error(`Node ${nodeId} not found in drive ${driveIdentifier}`);\n }\n\n if (node.kind === \"folder\") {\n const subtree = await this.readModel.getDescendants(\n driveIdentifier,\n nodeId,\n signal,\n );\n const fileDescendants = subtree.filter(\n (n): n is ReactorDriveFileNode => n.kind === \"file\",\n );\n const subFolders = subtree\n .filter((n): n is ReactorDriveFolderNode => n.kind === \"folder\")\n .filter((f) => f.id !== nodeId);\n const deepestFirstFolders = this.orderDeepestFirst(subFolders, nodeId);\n\n const batch: Action[] = [\n ...fileDescendants.map((f) =>\n removeRelationshipAction(\n driveIdentifier,\n f.id,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n ),\n ),\n ...deepestFirstFolders.map((f) =>\n removeFolderAction({ folderId: f.id }),\n ),\n removeFolderAction({ folderId: nodeId }),\n ];\n\n await this.reactor.execute(driveIdentifier, \"main\", batch, signal);\n\n for (const file of fileDescendants) {\n await this.reactor.deleteDocument(\n file.id,\n \"cascade\" as PropagationMode,\n signal,\n );\n }\n return;\n }\n\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n removeRelationshipAction(\n driveIdentifier,\n nodeId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n ),\n ],\n signal,\n );\n await this.reactor.deleteDocument(nodeId, undefined, signal);\n }\n\n async renameNode(\n driveIdentifier: string,\n nodeId: string,\n name: string,\n signal?: AbortSignal,\n ): Promise<Node> {\n const node = await this.readModel.getNode(driveIdentifier, nodeId, signal);\n if (!node) {\n throw new Error(`Node ${nodeId} not found in drive ${driveIdentifier}`);\n }\n\n if (node.kind === \"file\") {\n await this.reactor.rename(nodeId, name, \"main\", signal);\n } else {\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [updateFolderAction({ folderId: nodeId, name })],\n signal,\n );\n }\n\n const updated = await this.readModel.getNode(\n driveIdentifier,\n nodeId,\n signal,\n );\n if (!updated) {\n throw new Error(\"Node missing from drive after rename\");\n }\n return this.toLegacyNode(updated);\n }\n\n async setPreferredEditorOnNode(\n nodeId: string,\n preferredEditor: string | null,\n signal?: AbortSignal,\n ): Promise<PHDocument> {\n return this.reactor.setPreferredEditor(\n nodeId,\n preferredEditor,\n \"main\",\n signal,\n );\n }\n\n async moveNode(\n driveIdentifier: string,\n srcNodeId: string,\n targetParentFolderId: string | undefined,\n signal?: AbortSignal,\n ): Promise<DocumentDriveDocument> {\n const node = await this.readModel.getNode(\n driveIdentifier,\n srcNodeId,\n signal,\n );\n if (!node) {\n throw new Error(\n `Node ${srcNodeId} not found in drive ${driveIdentifier}`,\n );\n }\n\n if (node.kind === \"folder\") {\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n updateFolderAction({\n folderId: srcNodeId,\n parentFolderId: targetParentFolderId ?? null,\n }),\n ],\n signal,\n );\n } else {\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: targetParentFolderId ?? null,\n documentType: node.documentType,\n };\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n removeRelationshipAction(\n driveIdentifier,\n srcNodeId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n ),\n addRelationshipAction(\n driveIdentifier,\n srcNodeId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n ),\n ],\n signal,\n );\n }\n\n const drive = await this.reactor.get<PHDocument>(\n driveIdentifier,\n undefined,\n signal,\n );\n return this.toLegacyDriveDocument(drive, driveIdentifier);\n }\n\n async copyNode(\n driveIdentifier: string,\n srcNodeId: string,\n targetParentFolderId: string | undefined,\n signal?: AbortSignal,\n ): Promise<DocumentDriveDocument> {\n const srcNode = await this.readModel.getNode(\n driveIdentifier,\n srcNodeId,\n signal,\n );\n if (!srcNode) {\n throw new Error(\n `Node ${srcNodeId} not found in drive ${driveIdentifier}`,\n );\n }\n\n const subtree = await this.readModel.getDescendants(\n driveIdentifier,\n srcNodeId,\n signal,\n );\n\n if (\n targetParentFolderId !== undefined &&\n subtree.some((n) => n.id === targetParentFolderId)\n ) {\n throw new Error(\n `Cannot copy node ${srcNodeId} into itself or one of its descendants (target: ${targetParentFolderId})`,\n );\n }\n\n const idMap = new Map<string, string>();\n for (const node of subtree) {\n idMap.set(node.id, generateId());\n }\n\n const jobs: ExecutionJobPlan[] = [];\n const driveActions: Action[] = [];\n const fileCreateKeys: string[] = [];\n\n for (const node of subtree) {\n const newId = idMap.get(node.id)!;\n let newParent: string | null;\n if (node.id === srcNodeId) {\n newParent = targetParentFolderId ?? null;\n } else {\n if (node.parentFolder == null) {\n throw new Error(\n `copyNode: descendant ${node.id} has no parentFolder`,\n );\n }\n const mapped = idMap.get(node.parentFolder);\n if (mapped === undefined) {\n throw new Error(\n `copyNode: descendant ${node.id} parent ${node.parentFolder} missing from idMap`,\n );\n }\n newParent = mapped;\n }\n\n if (node.kind === \"folder\") {\n driveActions.push(\n addFolderAction({\n folderId: newId,\n parentFolderId: newParent,\n name: node.name,\n }),\n );\n continue;\n }\n\n const srcDoc = await this.reactor.get<PHDocument>(\n node.id,\n undefined,\n signal,\n );\n const documentModelModule = await this.reactor.getDocumentModelModule(\n srcDoc.header.documentType,\n );\n const duplicated: PHDocument = replayDocument(\n srcDoc.initialState,\n srcDoc.operations,\n documentModelModule.reducer,\n createPresignedHeader(newId, srcDoc.header.documentType),\n );\n duplicated.header.name = node.name;\n\n const createInput: CreateDocumentActionInput = {\n model: duplicated.header.documentType,\n version: 0,\n documentId: newId,\n signing: {\n signature: newId,\n publicKey: duplicated.header.sig.publicKey,\n nonce: duplicated.header.sig.nonce,\n createdAtUtcIso: duplicated.header.createdAtUtcIso,\n documentType: duplicated.header.documentType,\n },\n slug: duplicated.header.slug,\n name: duplicated.header.name,\n branch: duplicated.header.branch,\n meta: duplicated.header.meta,\n protocolVersions: duplicated.header.protocolVersions ?? {\n \"base-reducer\": 2,\n },\n };\n\n const createKey = `create:${newId}`;\n jobs.push({\n key: createKey,\n documentId: newId,\n scope: \"document\",\n branch: \"main\",\n actions: [\n createDocumentAction(createInput),\n upgradeDocumentAction({\n documentId: newId,\n model: duplicated.header.documentType,\n fromVersion: 0,\n toVersion: duplicated.state.document.version,\n initialState: duplicated.state,\n }),\n ],\n dependsOn: [],\n });\n fileCreateKeys.push(createKey);\n\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: newParent,\n documentType: duplicated.header.documentType,\n };\n driveActions.push(\n addRelationshipAction(\n driveIdentifier,\n newId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n ),\n );\n }\n\n if (driveActions.length > 0) {\n jobs.push({\n key: \"drive\",\n documentId: driveIdentifier,\n scope: \"document\",\n branch: \"main\",\n actions: driveActions,\n dependsOn: fileCreateKeys,\n });\n }\n\n if (jobs.length > 0) {\n const request: BatchExecutionRequest = { jobs };\n await this.reactor.executeBatch(request, signal);\n }\n\n const drive = await this.reactor.get<PHDocument>(\n driveIdentifier,\n undefined,\n signal,\n );\n return this.toLegacyDriveDocument(drive, driveIdentifier);\n }\n\n async getNode(\n driveIdentifier: string,\n nodeId: string,\n signal?: AbortSignal,\n ): Promise<Node> {\n const node = await this.readModel.getNode(driveIdentifier, nodeId, signal);\n if (!node) {\n throw new Error(`Node ${nodeId} not found in drive ${driveIdentifier}`);\n }\n return this.toLegacyNode(node);\n }\n\n async listNodes(\n driveIdentifier: string,\n parentFolder?: string | null,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<Node>> {\n const page = await this.readModel.listChildren(\n driveIdentifier,\n parentFolder,\n paging,\n signal,\n );\n return {\n results: page.results.map((node) => this.toLegacyNode(node)),\n options: page.options,\n ...(page.nextCursor !== undefined ? { nextCursor: page.nextCursor } : {}),\n ...(page.totalCount !== undefined ? { totalCount: page.totalCount } : {}),\n };\n }\n\n private toLegacyNode(node: ReactorDriveNode): Node {\n if (node.kind === \"file\") {\n const file: ReactorDriveFileNode = node;\n const legacy: FileNode = {\n id: file.id,\n kind: \"file\",\n name: file.name,\n parentFolder: file.parentFolder,\n documentType: file.documentType,\n };\n return legacy;\n }\n const folder: ReactorDriveFolderNode = node;\n const legacy: FolderNode = {\n id: folder.id,\n kind: \"folder\",\n name: folder.name,\n parentFolder: folder.parentFolder,\n };\n return legacy;\n }\n\n private async toLegacyDriveDocument(\n doc: PHDocument,\n driveId: string,\n ): Promise<DocumentDriveDocument> {\n if (doc.header.documentType !== REACTOR_DRIVE_DOCUMENT_TYPE) {\n throw new Error(\n `Document ${doc.header.id} is not a reactor-drive document`,\n );\n }\n const allNodes = await this.readModel.listAll(driveId);\n const legacy = structuredClone(doc) as unknown as DocumentDriveDocument;\n const existingGlobal = legacy.state.global as Partial<\n DocumentDriveDocument[\"state\"][\"global\"]\n >;\n legacy.state.global = {\n name: existingGlobal.name ?? \"\",\n icon: existingGlobal.icon ?? null,\n nodes: allNodes.map((n) => this.toLegacyNode(n)),\n };\n return legacy;\n }\n\n private orderDeepestFirst(\n folders: ReactorDriveFolderNode[],\n rootId: string,\n ): ReactorDriveFolderNode[] {\n const depthById = new Map<string, number>();\n const compute = (id: string): number => {\n if (id === rootId) return 0;\n const cached = depthById.get(id);\n if (cached !== undefined) return cached;\n const folder = folders.find((f) => f.id === id);\n if (!folder) return 0;\n const parent = folder.parentFolder ?? rootId;\n const depth = compute(parent) + 1;\n depthById.set(id, depth);\n return depth;\n };\n return folders.slice().sort((a, b) => compute(b.id) - compute(a.id));\n }\n}\n\nexport {\n setAvailableOfflineAction,\n setDriveIconAction,\n setDriveNameAction,\n setSharingTypeAction,\n};\n","import { gql } from \"graphql-tag\";\n\nexport const typeDefs = gql`\n enum ReactorDriveNodeKind {\n FILE\n FOLDER\n }\n\n input ReactorDrivePagingInput {\n cursor: String\n limit: Int\n }\n\n type ReactorDriveFileNode {\n id: ID!\n driveId: ID!\n name: String!\n parentFolder: ID\n documentType: String!\n }\n\n type ReactorDriveFolderNode {\n id: ID!\n driveId: ID!\n name: String!\n parentFolder: ID\n children(\n paging: ReactorDrivePagingInput\n kind: ReactorDriveNodeKind\n ): ReactorDriveNodePage!\n }\n\n union ReactorDriveNode = ReactorDriveFileNode | ReactorDriveFolderNode\n\n type ReactorDriveNodePage {\n results: [ReactorDriveNode!]!\n nextCursor: String\n hasMore: Boolean!\n totalCount: Int\n }\n\n type ReactorDrive {\n id: ID!\n name: String!\n icon: String\n sharingType: String!\n availableOffline: Boolean!\n rootNodes(\n paging: ReactorDrivePagingInput\n kind: ReactorDriveNodeKind\n ): ReactorDriveNodePage!\n }\n\n type Query {\n reactorDrive(id: ID!): ReactorDrive\n reactorDriveNode(driveId: ID!, id: ID!): ReactorDriveNode\n reactorDriveDescendants(driveId: ID!, root: ID!): [ReactorDriveNode!]!\n }\n`;\n","import type {\n IReactorClient,\n PagedResults,\n PagingOptions,\n} from \"@powerhousedao/reactor\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { REACTOR_DRIVE_DOCUMENT_TYPE } from \"../constants.js\";\nimport type { IDriveReadModel } from \"../read-model/interfaces.js\";\nimport type { ReactorDrivePHState, ReactorDriveNode } from \"../types.js\";\n\nexport interface ReactorDriveResolverContext {\n reactorClient: IReactorClient;\n readModel: IDriveReadModel;\n}\n\ntype PagingInput = { cursor?: string; limit?: number };\ntype NodeKindFilter = \"FILE\" | \"FOLDER\" | undefined;\n\nconst DEFAULT_LIMIT = 100;\n\nfunction toPaging(input: PagingInput | undefined): PagingOptions | undefined {\n if (!input) return undefined;\n return {\n cursor: input.cursor ?? \"\",\n limit: input.limit ?? DEFAULT_LIMIT,\n };\n}\n\nfunction filterByKind(\n page: PagedResults<ReactorDriveNode>,\n kind: NodeKindFilter,\n): PagedResults<ReactorDriveNode> {\n if (!kind) return page;\n const wanted = kind === \"FILE\" ? \"file\" : \"folder\";\n return {\n ...page,\n results: page.results.filter((node) => node.kind === wanted),\n };\n}\n\nfunction shapePage(page: PagedResults<ReactorDriveNode>) {\n return {\n results: page.results,\n nextCursor: page.nextCursor,\n hasMore: page.nextCursor !== undefined,\n totalCount: page.totalCount,\n };\n}\n\n/**\n * Builds GraphQL resolvers backed by the drive read model. The resolvers are\n * pure — every external dependency is read off the GraphQL context. Wiring\n * the resolvers into a subgraph (e.g. `reactor-api`'s `ISubgraph`) is the\n * caller's responsibility.\n */\nexport function createReactorDriveResolvers() {\n return {\n Query: {\n async reactorDrive(\n _root: unknown,\n args: { id: string },\n ctx: ReactorDriveResolverContext,\n ) {\n const document = await ctx.reactorClient.get<\n PHDocument<ReactorDrivePHState>\n >(args.id);\n if (document.header.documentType !== REACTOR_DRIVE_DOCUMENT_TYPE) {\n return null;\n }\n return {\n id: document.header.id,\n name: document.state.global.name,\n icon: document.state.global.icon,\n sharingType: document.state.local.sharingType,\n availableOffline: document.state.local.availableOffline,\n };\n },\n async reactorDriveNode(\n _root: unknown,\n args: { driveId: string; id: string },\n ctx: ReactorDriveResolverContext,\n ) {\n return ctx.readModel.getNode(args.driveId, args.id);\n },\n async reactorDriveDescendants(\n _root: unknown,\n args: { driveId: string; root: string },\n ctx: ReactorDriveResolverContext,\n ) {\n return ctx.readModel.getDescendants(args.driveId, args.root);\n },\n },\n ReactorDrive: {\n async rootNodes(\n parent: { id: string },\n args: { paging?: PagingInput; kind?: NodeKindFilter },\n ctx: ReactorDriveResolverContext,\n ) {\n const page = await ctx.readModel.listChildren(\n parent.id,\n null,\n toPaging(args.paging),\n );\n return shapePage(filterByKind(page, args.kind));\n },\n },\n ReactorDriveFolderNode: {\n async children(\n parent: { id: string; driveId: string },\n args: { paging?: PagingInput; kind?: NodeKindFilter },\n ctx: ReactorDriveResolverContext,\n ) {\n const page = await ctx.readModel.listChildren(\n parent.driveId,\n parent.id,\n toPaging(args.paging),\n );\n return shapePage(filterByKind(page, args.kind));\n },\n },\n ReactorDriveNode: {\n __resolveType(node: ReactorDriveNode) {\n return node.kind === \"file\"\n ? \"ReactorDriveFileNode\"\n : \"ReactorDriveFolderNode\";\n },\n },\n };\n}\n","import {\n addRelationshipAction,\n type IReactorClient,\n} from \"@powerhousedao/reactor\";\nimport type { FileNode, Node } from \"@powerhousedao/shared/document-drive\";\nimport type { Action } from \"@powerhousedao/shared/document-model\";\nimport { addFolderAction } from \"../actions.js\";\nimport { DRIVE_CHILD_RELATIONSHIP_TYPE } from \"../constants.js\";\nimport type { IDriveReadModel } from \"../read-model/interfaces.js\";\nimport type { DriveChildFileMetadata } from \"../types.js\";\n\nexport interface MigrateLegacyDriveStateArgs {\n reactor: IReactorClient;\n readModel: IDriveReadModel;\n driveId: string;\n nodes: Node[];\n branch?: string;\n signal?: AbortSignal;\n}\n\nexport interface MigrateLegacyDriveStateResult {\n emittedActions: number;\n skippedExisting: number;\n}\n\n/**\n * Translates a legacy `document-drive` `state.global.nodes` array into the\n * action vocabulary used by the new reactor-drive module.\n *\n * Folder nodes are emitted as `ADD_FOLDER` actions targeting the drive\n * document. File nodes are emitted as `ADD_RELATIONSHIP` actions on the drive\n * with `drive/child` metadata carrying the parent folder id. File nodes\n * assume the underlying PHDocument still exists under the same id — the\n * migration only re-links it into the new drive, it does not recreate\n * documents.\n *\n * Re-running the migration is safe: existing `DriveNode` rows are skipped\n * so already-migrated nodes are left untouched.\n */\nexport async function migrateLegacyDriveState(\n args: MigrateLegacyDriveStateArgs,\n): Promise<MigrateLegacyDriveStateResult> {\n const { reactor, readModel, driveId, nodes, signal } = args;\n const branch = args.branch ?? \"main\";\n\n const ordered = orderLegacyNodes(nodes);\n const actions: Action[] = [];\n let skippedExisting = 0;\n\n for (const node of ordered) {\n const existing = await readModel.getNode(driveId, node.id, signal);\n if (existing) {\n skippedExisting += 1;\n continue;\n }\n actions.push(toAction(driveId, node));\n }\n\n if (actions.length === 0) {\n return { emittedActions: 0, skippedExisting };\n }\n\n await reactor.execute(driveId, branch, actions, signal);\n return { emittedActions: actions.length, skippedExisting };\n}\n\nfunction toAction(driveId: string, node: Node): Action {\n if (node.kind === \"folder\") {\n return addFolderAction({\n folderId: node.id,\n parentFolderId: node.parentFolder ?? null,\n name: node.name,\n });\n }\n const fileNode = node as FileNode;\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: fileNode.parentFolder ?? null,\n documentType: fileNode.documentType,\n };\n return addRelationshipAction(\n driveId,\n fileNode.id,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n );\n}\n\n/**\n * Sorts legacy nodes so that any folder appears before its children. The\n * legacy state stores nodes in insertion order, which usually already\n * satisfies that property, but defensive sorting keeps replay deterministic\n * if the input was constructed out of order.\n */\nfunction orderLegacyNodes(nodes: Node[]): Node[] {\n const byId = new Map<string, Node>();\n for (const node of nodes) {\n byId.set(node.id, node);\n }\n const visited = new Set<string>();\n const ordered: Node[] = [];\n\n for (const start of nodes) {\n if (visited.has(start.id)) continue;\n const chain: Node[] = [];\n const seenInWalk = new Set<string>();\n let current: Node | undefined = start;\n while (current && !visited.has(current.id) && !seenInWalk.has(current.id)) {\n seenInWalk.add(current.id);\n chain.push(current);\n const parentId: string | null | undefined = current.parentFolder;\n current = parentId ? byId.get(parentId) : undefined;\n }\n while (chain.length > 0) {\n const node = chain.pop()!;\n if (visited.has(node.id)) continue;\n visited.add(node.id);\n ordered.push(node);\n }\n }\n return ordered;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["up","down","migration0001","migration0002","DEFAULT_LIMIT"],"sources":["../src/constants.ts","../src/actions.ts","../src/reducer/drive.ts","../src/module.ts","../src/schema/migrations/0001_drive_node.ts","../src/schema/migrations/0002_document_name.ts","../src/schema/migrations/migrator.ts","../src/processors/utils/collisions.ts","../src/processors/node-processor.ts","../src/read-model/drive-node-view.ts","../src/client/reactor-drive-client.ts","../src/subgraph/schema.ts","../src/subgraph/resolvers.ts","../src/migration/migrate-legacy-state.ts"],"sourcesContent":["export const REACTOR_DRIVE_DOCUMENT_TYPE = \"powerhouse/reactor-drive\";\n\nexport const DRIVE_CHILD_RELATIONSHIP_TYPE = \"drive/child\";\n\nexport const REACTOR_DRIVE_FILE_EXTENSION = \"phrd\";\n","import type { Action } from \"@powerhousedao/shared/document-model\";\nimport { generateId } from \"@powerhousedao/shared/document-model\";\nimport type {\n AddFolderActionInput,\n RemoveFolderActionInput,\n UpdateFolderActionInput,\n} from \"./types.js\";\n\nexport type SetDriveNameInput = { name: string };\nexport type SetDriveIconInput = { icon: string | null };\nexport type SetSharingTypeInput = { sharingType: string };\nexport type SetAvailableOfflineInput = { availableOffline: boolean };\n\nexport function setDriveNameAction(input: SetDriveNameInput): Action {\n return {\n id: generateId(),\n type: \"SET_DRIVE_NAME\",\n scope: \"global\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function setDriveIconAction(input: SetDriveIconInput): Action {\n return {\n id: generateId(),\n type: \"SET_DRIVE_ICON\",\n scope: \"global\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function setSharingTypeAction(input: SetSharingTypeInput): Action {\n return {\n id: generateId(),\n type: \"SET_SHARING_TYPE\",\n scope: \"local\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function setAvailableOfflineAction(\n input: SetAvailableOfflineInput,\n): Action {\n return {\n id: generateId(),\n type: \"SET_AVAILABLE_OFFLINE\",\n scope: \"local\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function addFolderAction(input: AddFolderActionInput): Action {\n return {\n id: generateId(),\n type: \"ADD_FOLDER\",\n scope: \"document\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function updateFolderAction(input: UpdateFolderActionInput): Action {\n return {\n id: generateId(),\n type: \"UPDATE_FOLDER\",\n scope: \"document\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport function removeFolderAction(input: RemoveFolderActionInput): Action {\n return {\n id: generateId(),\n type: \"REMOVE_FOLDER\",\n scope: \"document\",\n timestampUtcMs: new Date().toISOString(),\n input,\n };\n}\n\nexport const reactorDriveActions = {\n setDriveName: setDriveNameAction,\n setDriveIcon: setDriveIconAction,\n setSharingType: setSharingTypeAction,\n setAvailableOffline: setAvailableOfflineAction,\n addFolder: addFolderAction,\n updateFolder: updateFolderAction,\n removeFolder: removeFolderAction,\n};\n","import type {\n Action,\n StateReducer,\n} from \"@powerhousedao/shared/document-model\";\nimport { isDocumentAction } from \"@powerhousedao/shared/document-model\";\nimport type {\n SetAvailableOfflineInput,\n SetDriveIconInput,\n SetDriveNameInput,\n SetSharingTypeInput,\n} from \"../actions.js\";\nimport type { ReactorDrivePHState } from \"../types.js\";\n\ntype TypedAction = Action & { type: string };\n\nexport const reactorDriveStateReducer: StateReducer<ReactorDrivePHState> = (\n state,\n action,\n) => {\n if (isDocumentAction(action)) {\n return state;\n }\n\n const typedAction = action as TypedAction;\n\n switch (typedAction.type) {\n case \"SET_DRIVE_NAME\": {\n const input = typedAction.input as SetDriveNameInput;\n state.global.name = input.name;\n return state;\n }\n case \"SET_DRIVE_ICON\": {\n const input = typedAction.input as SetDriveIconInput;\n state.global.icon = input.icon;\n return state;\n }\n case \"SET_SHARING_TYPE\": {\n const input = typedAction.input as SetSharingTypeInput;\n state.local.sharingType = input.sharingType;\n return state;\n }\n case \"SET_AVAILABLE_OFFLINE\": {\n const input = typedAction.input as SetAvailableOfflineInput;\n state.local.availableOffline = input.availableOffline;\n return state;\n }\n case \"ADD_FOLDER\":\n case \"UPDATE_FOLDER\":\n case \"REMOVE_FOLDER\":\n // Identity: folder ops are recorded for sync and materialized by NodeProcessor.\n return state;\n default:\n return state;\n }\n};\n","import type {\n AssertIsDocumentOfType,\n AssertIsStateOfType,\n CreateDocument,\n CreateState,\n DocumentModelGlobalState,\n IsDocumentOfType,\n IsStateOfType,\n LoadFromInput,\n PHDocument,\n SaveToFileHandle,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n baseCreateDocument,\n baseLoadFromInput,\n baseSaveToFileHandle,\n createReducer,\n createState,\n defaultBaseState,\n} from \"@powerhousedao/shared/document-model\";\nimport { reactorDriveActions } from \"./actions.js\";\nimport {\n REACTOR_DRIVE_DOCUMENT_TYPE,\n REACTOR_DRIVE_FILE_EXTENSION,\n} from \"./constants.js\";\nimport { reactorDriveStateReducer } from \"./reducer/drive.js\";\nimport type {\n ReactorDriveDocumentModelModule,\n ReactorDriveGlobalState,\n ReactorDriveLocalState,\n ReactorDrivePHState,\n} from \"./types.js\";\n\nconst initialGlobalState: ReactorDriveGlobalState = {\n name: \"\",\n icon: null,\n};\n\nconst initialLocalState: ReactorDriveLocalState = {\n sharingType: \"private\",\n availableOffline: false,\n};\n\nexport const reactorDriveCreateState: CreateState<ReactorDrivePHState> = (\n state,\n) => {\n return {\n ...defaultBaseState(),\n global: { ...initialGlobalState, ...state?.global },\n local: { ...initialLocalState, ...state?.local },\n };\n};\n\nexport const reactorDriveCreateDocument: CreateDocument<ReactorDrivePHState> = (\n state,\n) => {\n return baseCreateDocument(\n reactorDriveCreateState,\n state,\n REACTOR_DRIVE_DOCUMENT_TYPE,\n );\n};\n\nconst reactorDriveSaveToFileHandle: SaveToFileHandle = (document, input) => {\n return baseSaveToFileHandle(document, input);\n};\n\nconst reactorDriveLoadFromInput: LoadFromInput<ReactorDrivePHState> = (\n input,\n) => {\n return baseLoadFromInput(input, reactorDriveDocumentReducer);\n};\n\nconst isReactorDriveState: IsStateOfType<ReactorDrivePHState> = (\n state,\n): state is ReactorDrivePHState => {\n return (\n typeof state === \"object\" &&\n state !== null &&\n \"global\" in state &&\n \"local\" in state\n );\n};\n\nconst assertIsReactorDriveState: AssertIsStateOfType<ReactorDrivePHState> = (\n state,\n) => {\n if (!isReactorDriveState(state)) {\n throw new Error(\"Not a reactor-drive state\");\n }\n};\n\nconst isReactorDriveDocument: IsDocumentOfType<ReactorDrivePHState> = (\n document,\n): document is PHDocument<ReactorDrivePHState> => {\n return (\n typeof document === \"object\" &&\n document !== null &&\n \"header\" in document &&\n (document as { header: { documentType: string } }).header.documentType ===\n REACTOR_DRIVE_DOCUMENT_TYPE\n );\n};\n\nconst assertIsReactorDriveDocument: AssertIsDocumentOfType<\n ReactorDrivePHState\n> = (document) => {\n if (!isReactorDriveDocument(document)) {\n throw new Error(\"Not a reactor-drive document\");\n }\n};\n\nexport const reactorDriveDocumentReducer = createReducer<ReactorDrivePHState>(\n reactorDriveStateReducer,\n);\n\nconst reactorDriveDocumentGlobalState: DocumentModelGlobalState = {\n id: REACTOR_DRIVE_DOCUMENT_TYPE,\n name: \"ReactorDrive\",\n extension: REACTOR_DRIVE_FILE_EXTENSION,\n description: \"\",\n author: {\n name: \"Powerhouse Inc\",\n website: \"https://www.powerhouse.inc/\",\n },\n specifications: [\n {\n version: 1,\n changeLog: [],\n state: {\n global: {\n schema:\n \"type ReactorDriveState {\\n name: String!\\n icon: String\\n}\",\n // Double-encoded by convention: `initialValue` holds a JSON-encoded string that consumers parse with JSON.parse.\n initialValue: JSON.stringify(JSON.stringify(initialGlobalState)),\n examples: [],\n },\n local: {\n schema:\n \"type ReactorDriveLocalState {\\n sharingType: String!\\n availableOffline: Boolean!\\n}\",\n // Double-encoded by convention: `initialValue` holds a JSON-encoded string that consumers parse with JSON.parse.\n initialValue: JSON.stringify(JSON.stringify(initialLocalState)),\n examples: [],\n },\n },\n modules: [\n {\n id: \"reactor-drive/base-operations\",\n name: \"base_operations\",\n description: \"\",\n operations: [\n {\n id: \"SET_DRIVE_NAME\",\n name: \"SET_DRIVE_NAME\",\n description: \"\",\n schema: \"input SetDriveNameInput { name: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"global\",\n },\n {\n id: \"SET_DRIVE_ICON\",\n name: \"SET_DRIVE_ICON\",\n description: \"\",\n schema: \"input SetDriveIconInput { icon: String }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"global\",\n },\n {\n id: \"SET_SHARING_TYPE\",\n name: \"SET_SHARING_TYPE\",\n description: \"\",\n schema: \"input SetSharingTypeInput { sharingType: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"local\",\n },\n {\n id: \"SET_AVAILABLE_OFFLINE\",\n name: \"SET_AVAILABLE_OFFLINE\",\n description: \"\",\n schema:\n \"input SetAvailableOfflineInput { availableOffline: Boolean! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"local\",\n },\n {\n id: \"ADD_FOLDER\",\n name: \"ADD_FOLDER\",\n description: \"\",\n schema:\n \"input AddFolderInput { folderId: String! parentFolderId: String name: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"document\",\n },\n {\n id: \"UPDATE_FOLDER\",\n name: \"UPDATE_FOLDER\",\n description: \"\",\n schema:\n \"input UpdateFolderInput { folderId: String! name: String parentFolderId: String }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"document\",\n },\n {\n id: \"REMOVE_FOLDER\",\n name: \"REMOVE_FOLDER\",\n description: \"\",\n schema: \"input RemoveFolderInput { folderId: String! }\",\n template: \"\",\n reducer: \"\",\n errors: [],\n examples: [],\n scope: \"document\",\n },\n ],\n },\n ],\n },\n ],\n};\n\nexport const reactorDriveDocumentModelModule: ReactorDriveDocumentModelModule =\n {\n actions: reactorDriveActions,\n reducer: reactorDriveDocumentReducer,\n documentModel: createState(\n defaultBaseState(),\n reactorDriveDocumentGlobalState,\n ),\n utils: {\n fileExtension: REACTOR_DRIVE_FILE_EXTENSION,\n createState: reactorDriveCreateState,\n createDocument: reactorDriveCreateDocument,\n loadFromInput: reactorDriveLoadFromInput,\n saveToFileHandle: reactorDriveSaveToFileHandle,\n isStateOfType: isReactorDriveState,\n assertIsStateOfType: assertIsReactorDriveState,\n isDocumentOfType: isReactorDriveDocument,\n assertIsDocumentOfType: assertIsReactorDriveDocument,\n },\n };\n","import type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nexport async function up(db: Kysely<unknown>): Promise<void> {\n await db.schema\n .createTable(\"DriveNode\")\n .ifNotExists()\n .addColumn(\"driveId\", \"text\", (col) => col.notNull())\n .addColumn(\"id\", \"text\", (col) => col.notNull())\n .addColumn(\"kind\", \"text\", (col) => col.notNull())\n .addColumn(\"name\", \"text\", (col) => col.notNull())\n .addColumn(\"requestedName\", \"text\", (col) => col.notNull())\n .addColumn(\"parentFolder\", \"text\")\n .addColumn(\"documentType\", \"text\")\n .addColumn(\"createdAt\", \"timestamptz\", (col) =>\n col.notNull().defaultTo(sql`NOW()`),\n )\n .addColumn(\"updatedAt\", \"timestamptz\", (col) =>\n col.notNull().defaultTo(sql`NOW()`),\n )\n .addPrimaryKeyConstraint(\"pk_drive_node\", [\"driveId\", \"id\"])\n .addCheckConstraint(\n \"chk_drive_node_document_type\",\n sql`(kind = 'file' AND \"documentType\" IS NOT NULL) OR (kind = 'folder' AND \"documentType\" IS NULL)`,\n )\n .execute();\n\n await db.schema\n .createIndex(\"idx_drive_node_parent_name\")\n .ifNotExists()\n .on(\"DriveNode\")\n .columns([\"driveId\", \"parentFolder\", \"name\"])\n .execute();\n\n await db.schema\n .createIndex(\"idx_drive_node_parent_kind_id\")\n .ifNotExists()\n .on(\"DriveNode\")\n .columns([\"driveId\", \"parentFolder\", \"kind\", \"id\"])\n .execute();\n}\n\nexport async function down(db: Kysely<unknown>): Promise<void> {\n await db.schema.dropTable(\"DriveNode\").execute();\n}\n","import type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nexport async function up(db: Kysely<unknown>): Promise<void> {\n await db.schema\n .createTable(\"DocumentName\")\n .ifNotExists()\n .addColumn(\"docId\", \"text\", (col) => col.primaryKey())\n .addColumn(\"name\", \"text\", (col) => col.notNull())\n .addColumn(\"updatedAt\", \"timestamptz\", (col) =>\n col.notNull().defaultTo(sql`NOW()`),\n )\n .execute();\n}\n\nexport async function down(db: Kysely<unknown>): Promise<void> {\n await db.schema.dropTable(\"DocumentName\").execute();\n}\n","import type { Kysely, MigrationProvider } from \"kysely\";\nimport { Migrator, sql } from \"kysely\";\nimport * as migration0001 from \"./0001_drive_node.js\";\nimport * as migration0002 from \"./0002_document_name.js\";\n\nconst migrations = {\n \"0001_drive_node\": migration0001,\n \"0002_document_name\": migration0002,\n};\n\nconst REACTOR_DRIVE_MIGRATION_TABLE = \"kysely_migration_reactor_drive\";\nconst REACTOR_DRIVE_MIGRATION_LOCK_TABLE =\n \"kysely_migration_reactor_drive_lock\";\n\nexport interface ReactorDriveMigrationResult {\n success: boolean;\n migrationsExecuted: string[];\n error?: Error;\n}\n\nclass ProgrammaticMigrationProvider implements MigrationProvider {\n getMigrations() {\n return Promise.resolve(migrations);\n }\n}\n\nexport async function runReactorDriveMigrations(\n db: Kysely<unknown>,\n schema: string,\n): Promise<ReactorDriveMigrationResult> {\n try {\n await sql`CREATE SCHEMA IF NOT EXISTS ${sql.id(schema)}`.execute(db);\n } catch (error) {\n return {\n success: false,\n migrationsExecuted: [],\n error:\n error instanceof Error ? error : new Error(\"Failed to create schema\"),\n };\n }\n\n const migrator = new Migrator({\n db: db.withSchema(schema),\n provider: new ProgrammaticMigrationProvider(),\n migrationTableSchema: schema,\n migrationTableName: REACTOR_DRIVE_MIGRATION_TABLE,\n migrationLockTableName: REACTOR_DRIVE_MIGRATION_LOCK_TABLE,\n });\n\n let error: unknown;\n let results: Awaited<ReturnType<typeof migrator.migrateToLatest>>[\"results\"];\n try {\n const result = await migrator.migrateToLatest();\n error = result.error;\n results = result.results;\n } catch (e) {\n error = e;\n results = [];\n }\n\n const migrationsExecuted =\n results?.map((result) => result.migrationName) ?? [];\n\n if (error) {\n return {\n success: false,\n migrationsExecuted,\n error:\n error instanceof Error ? error : new Error(\"Unknown migration error\"),\n };\n }\n\n return {\n success: true,\n migrationsExecuted,\n };\n}\n\nexport async function getReactorDriveMigrationStatus(\n db: Kysely<unknown>,\n schema: string,\n) {\n const migrator = new Migrator({\n db: db.withSchema(schema),\n provider: new ProgrammaticMigrationProvider(),\n migrationTableSchema: schema,\n migrationTableName: REACTOR_DRIVE_MIGRATION_TABLE,\n migrationLockTableName: REACTOR_DRIVE_MIGRATION_LOCK_TABLE,\n });\n\n return await migrator.getMigrations();\n}\n","/**\n * Deterministic per-folder name collision rule. Given a desired name and the\n * set of names already taken by siblings, returns the next available name as\n * `requested`, `requested (2)`, `requested (3)`, etc.\n *\n * The rule matches the legacy document-drive module so that migration from\n * the legacy state produces stable suffixes.\n */\nexport function resolveCollision(\n requested: string,\n takenNames: Iterable<string>,\n): string {\n const taken = new Set<string>();\n for (const name of takenNames) {\n taken.add(name);\n }\n\n if (!taken.has(requested)) {\n return requested;\n }\n\n let suffix = 2;\n while (taken.has(`${requested} (${suffix})`)) {\n suffix += 1;\n }\n return `${requested} (${suffix})`;\n}\n","import type { IOperationIndex, IWriteCache } from \"@powerhousedao/reactor\";\nimport {\n BaseReadModel,\n type DocumentViewDatabase,\n type IConsistencyTracker,\n} from \"@powerhousedao/reactor\";\nimport type {\n AddRelationshipActionInput,\n CreateDocumentActionInput,\n DeleteDocumentActionInput,\n OperationWithContext,\n RemoveRelationshipActionInput,\n SetNameActionInput,\n UpgradeDocumentActionInput,\n} from \"@powerhousedao/shared/document-model\";\nimport type { Kysely, Transaction } from \"kysely\";\nimport {\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n REACTOR_DRIVE_DOCUMENT_TYPE,\n} from \"../constants.js\";\nimport { runReactorDriveMigrations } from \"../schema/migrations/migrator.js\";\nimport type { ReactorDriveDatabase } from \"../schema/tables.js\";\nimport type {\n AddFolderActionInput,\n DriveChildFileMetadata,\n RemoveFolderActionInput,\n UpdateFolderActionInput,\n} from \"../types.js\";\nimport { resolveCollision } from \"./utils/collisions.js\";\n\nexport type NodeProcessorDatabase = ReactorDriveDatabase & DocumentViewDatabase;\n\nconst NAME_ACTION_TYPES = new Set([\n \"CREATE_DOCUMENT\",\n \"UPGRADE_DOCUMENT\",\n \"SET_NAME\",\n]);\n\nconst STRUCTURE_ACTION_TYPES = new Set([\n \"ADD_RELATIONSHIP\",\n \"REMOVE_RELATIONSHIP\",\n \"ADD_FOLDER\",\n \"UPDATE_FOLDER\",\n \"REMOVE_FOLDER\",\n]);\n\nexport class NodeProcessor extends BaseReadModel {\n private readonly driveDb: Kysely<NodeProcessorDatabase>;\n private readonly baseDb: Kysely<unknown>;\n private readonly schema: string;\n\n constructor(\n baseDb: Kysely<unknown>,\n schema: string,\n operationIndex: IOperationIndex,\n writeCache: IWriteCache,\n consistencyTracker: IConsistencyTracker,\n ) {\n const scopedDb = baseDb.withSchema(\n schema,\n ) as unknown as Kysely<NodeProcessorDatabase>;\n super(\n scopedDb as unknown as Kysely<DocumentViewDatabase>,\n operationIndex,\n writeCache,\n consistencyTracker,\n {\n readModelId: \"reactor-drive-node-processor\",\n rebuildStateOnInit: false,\n },\n );\n this.driveDb = scopedDb;\n this.baseDb = baseDb;\n this.schema = schema;\n }\n\n override async init(): Promise<void> {\n const result = await runReactorDriveMigrations(this.baseDb, this.schema);\n if (!result.success && result.error) {\n throw new Error(\n `Reactor drive migrations failed: ${result.error.message}`,\n );\n }\n await super.init();\n }\n\n protected override async commitOperations(\n items: OperationWithContext[],\n ): Promise<void> {\n await this.driveDb.transaction().execute(async (trx) => {\n for (const item of items) {\n const actionType = item.operation.action.type;\n if (NAME_ACTION_TYPES.has(actionType)) {\n await this.applyNameOperation(trx, item);\n continue;\n }\n if (STRUCTURE_ACTION_TYPES.has(actionType)) {\n await this.applyStructureOperation(trx, item);\n continue;\n }\n if (actionType === \"DELETE_DOCUMENT\") {\n await this.applyDeleteDocument(trx, item);\n }\n }\n });\n }\n\n private async applyNameOperation(\n trx: Transaction<NodeProcessorDatabase>,\n item: OperationWithContext,\n ): Promise<void> {\n const action = item.operation.action;\n const docId = item.context.documentId;\n let name: string | undefined;\n\n if (action.type === \"CREATE_DOCUMENT\") {\n const input = action.input as CreateDocumentActionInput;\n name = input.name;\n } else if (action.type === \"UPGRADE_DOCUMENT\") {\n const input = action.input as UpgradeDocumentActionInput;\n const initial = (input.initialState ?? {}) as {\n header?: { name?: string };\n };\n name = initial.header?.name;\n } else if (action.type === \"SET_NAME\") {\n const input = action.input as SetNameActionInput;\n name = input.name;\n }\n\n if (name === undefined) {\n return;\n }\n\n await this.upsertDocumentName(trx, docId, name);\n\n const linkedRows = await trx\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"id\", \"=\", docId)\n .where(\"kind\", \"=\", \"file\")\n .execute();\n\n for (const row of linkedRows) {\n const resolved = await this.resolveSiblingName(\n trx,\n row.driveId,\n row.parentFolder,\n name,\n docId,\n );\n await trx\n .updateTable(\"DriveNode\")\n .set({\n name: resolved,\n requestedName: name,\n updatedAt: new Date(),\n })\n .where(\"driveId\", \"=\", row.driveId)\n .where(\"id\", \"=\", docId)\n .execute();\n }\n }\n\n private async applyStructureOperation(\n trx: Transaction<NodeProcessorDatabase>,\n item: OperationWithContext,\n ): Promise<void> {\n if (item.context.documentType !== REACTOR_DRIVE_DOCUMENT_TYPE) {\n return;\n }\n\n const action = item.operation.action;\n const driveId = item.context.documentId;\n\n if (action.type === \"ADD_RELATIONSHIP\") {\n const input = action.input as AddRelationshipActionInput;\n if (input.relationshipType !== DRIVE_CHILD_RELATIONSHIP_TYPE) return;\n await this.handleAddFileRelationship(trx, driveId, input);\n return;\n }\n\n if (action.type === \"REMOVE_RELATIONSHIP\") {\n const input = action.input as RemoveRelationshipActionInput;\n if (input.relationshipType !== DRIVE_CHILD_RELATIONSHIP_TYPE) return;\n await trx\n .deleteFrom(\"DriveNode\")\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.targetId)\n .execute();\n return;\n }\n\n if (action.type === \"ADD_FOLDER\") {\n await this.handleAddFolder(\n trx,\n driveId,\n action.input as AddFolderActionInput,\n );\n return;\n }\n\n if (action.type === \"UPDATE_FOLDER\") {\n await this.handleUpdateFolder(\n trx,\n driveId,\n action.input as UpdateFolderActionInput,\n );\n return;\n }\n\n if (action.type === \"REMOVE_FOLDER\") {\n const input = action.input as RemoveFolderActionInput;\n await trx\n .deleteFrom(\"DriveNode\")\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.folderId)\n .execute();\n }\n }\n\n private async applyDeleteDocument(\n trx: Transaction<NodeProcessorDatabase>,\n item: OperationWithContext,\n ): Promise<void> {\n const input = item.operation.action.input as DeleteDocumentActionInput;\n const docId = input.documentId || item.context.documentId;\n\n await trx.deleteFrom(\"DriveNode\").where(\"id\", \"=\", docId).execute();\n await trx.deleteFrom(\"DocumentName\").where(\"docId\", \"=\", docId).execute();\n }\n\n private async handleAddFileRelationship(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n input: AddRelationshipActionInput,\n ): Promise<void> {\n const metadata = this.parseFileMetadata(input);\n const parentFolder = metadata.parentFolderId ?? null;\n const documentType = metadata.documentType;\n\n const requestedName =\n (await this.lookupDocumentName(trx, input.targetId)) ?? \"\";\n\n const resolved = await this.resolveSiblingName(\n trx,\n driveId,\n parentFolder,\n requestedName,\n input.targetId,\n );\n\n await trx\n .insertInto(\"DriveNode\")\n .values({\n driveId,\n id: input.targetId,\n kind: \"file\",\n name: resolved,\n requestedName,\n parentFolder,\n documentType,\n })\n .onConflict((oc) =>\n oc.columns([\"driveId\", \"id\"]).doUpdateSet({\n parentFolder,\n name: resolved,\n requestedName,\n kind: \"file\",\n documentType,\n updatedAt: new Date(),\n }),\n )\n .execute();\n }\n\n private async handleAddFolder(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n input: AddFolderActionInput,\n ): Promise<void> {\n const parentFolder = input.parentFolderId ?? null;\n const resolved = await this.resolveSiblingName(\n trx,\n driveId,\n parentFolder,\n input.name,\n input.folderId,\n );\n\n await trx\n .insertInto(\"DriveNode\")\n .values({\n driveId,\n id: input.folderId,\n kind: \"folder\",\n name: resolved,\n requestedName: input.name,\n parentFolder,\n documentType: null,\n })\n .onConflict((oc) =>\n oc.columns([\"driveId\", \"id\"]).doUpdateSet({\n parentFolder,\n name: resolved,\n requestedName: input.name,\n kind: \"folder\",\n documentType: null,\n updatedAt: new Date(),\n }),\n )\n .execute();\n }\n\n private async handleUpdateFolder(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n input: UpdateFolderActionInput,\n ): Promise<void> {\n const row = await trx\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.folderId)\n .executeTakeFirst();\n if (!row) return;\n\n const nextParentFolder =\n input.parentFolderId === undefined\n ? row.parentFolder\n : (input.parentFolderId ?? null);\n const nextRequestedName =\n typeof input.name === \"string\" ? input.name : row.requestedName;\n\n const resolved = await this.resolveSiblingName(\n trx,\n driveId,\n nextParentFolder,\n nextRequestedName,\n input.folderId,\n );\n\n await trx\n .updateTable(\"DriveNode\")\n .set({\n parentFolder: nextParentFolder,\n name: resolved,\n requestedName: nextRequestedName,\n updatedAt: new Date(),\n })\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", input.folderId)\n .execute();\n }\n\n private async resolveSiblingName(\n trx: Transaction<NodeProcessorDatabase>,\n driveId: string,\n parentFolder: string | null,\n requested: string,\n excludeId: string,\n ): Promise<string> {\n let query = trx\n .selectFrom(\"DriveNode\")\n .select(\"name\")\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"!=\", excludeId);\n query =\n parentFolder === null\n ? query.where(\"parentFolder\", \"is\", null)\n : query.where(\"parentFolder\", \"=\", parentFolder);\n\n const rows = await query.execute();\n return resolveCollision(\n requested,\n rows.map((r) => r.name),\n );\n }\n\n private async lookupDocumentName(\n trx: Transaction<NodeProcessorDatabase>,\n docId: string,\n ): Promise<string | undefined> {\n const row = await trx\n .selectFrom(\"DocumentName\")\n .select(\"name\")\n .where(\"docId\", \"=\", docId)\n .executeTakeFirst();\n return row?.name;\n }\n\n private parseFileMetadata(\n input: AddRelationshipActionInput,\n ): DriveChildFileMetadata {\n const metadata = input.metadata;\n if (\n !metadata ||\n typeof metadata !== \"object\" ||\n (metadata as { kind?: unknown }).kind !== \"file\" ||\n typeof (metadata as { documentType?: unknown }).documentType !== \"string\"\n ) {\n throw new Error(\n `ADD_RELATIONSHIP for target ${input.targetId}: missing or invalid drive/child file metadata (expected { kind: \"file\", parentFolderId, documentType })`,\n );\n }\n const typed = metadata as DriveChildFileMetadata;\n return {\n kind: \"file\",\n parentFolderId: typed.parentFolderId ?? null,\n documentType: typed.documentType,\n };\n }\n\n private async upsertDocumentName(\n trx: Transaction<NodeProcessorDatabase>,\n docId: string,\n name: string,\n ): Promise<void> {\n await trx\n .insertInto(\"DocumentName\")\n .values({ docId, name })\n .onConflict((oc) =>\n oc.column(\"docId\").doUpdateSet({ name, updatedAt: new Date() }),\n )\n .execute();\n }\n}\n","import { type PagedResults, type PagingOptions } from \"@powerhousedao/reactor\";\nimport type { Kysely } from \"kysely\";\nimport type { ReactorDriveDatabase } from \"../schema/tables.js\";\nimport type {\n ReactorDriveFileNode,\n ReactorDriveFolderNode,\n ReactorDriveNode,\n} from \"../types.js\";\nimport type { IDriveReadModel } from \"./interfaces.js\";\n\nconst DEFAULT_LIMIT = 100;\n\ntype KeysetCursor = {\n createdAt: Date;\n id: string;\n};\n\nfunction parseListChildrenPaging(paging: PagingOptions | undefined): {\n limit: number;\n cursor: KeysetCursor | null;\n} {\n if (paging === undefined) {\n return { limit: DEFAULT_LIMIT, cursor: null };\n }\n if (!Number.isInteger(paging.limit) || paging.limit < 1) {\n throw new Error(\n `Invalid paging limit: ${String(paging.limit)} (must be an integer >= 1)`,\n );\n }\n if (paging.cursor === \"\") {\n return { limit: paging.limit, cursor: null };\n }\n return { limit: paging.limit, cursor: decodeKeysetCursor(paging.cursor) };\n}\n\nfunction encodeKeysetCursor(createdAt: Date, id: string): string {\n return globalThis.btoa(\n JSON.stringify({ createdAt: createdAt.toISOString(), id }),\n );\n}\n\nfunction decodeKeysetCursor(cursor: string): KeysetCursor {\n let decoded: string;\n try {\n decoded = globalThis.atob(cursor);\n } catch {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (must be a keyset cursor returned by a prior page)`,\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(decoded);\n } catch {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (must be a keyset cursor returned by a prior page)`,\n );\n }\n if (\n parsed === null ||\n typeof parsed !== \"object\" ||\n typeof (parsed as { createdAt?: unknown }).createdAt !== \"string\" ||\n typeof (parsed as { id?: unknown }).id !== \"string\"\n ) {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (must be a keyset cursor returned by a prior page)`,\n );\n }\n const createdAt = new Date((parsed as { createdAt: string }).createdAt);\n if (Number.isNaN(createdAt.getTime())) {\n throw new Error(\n `Invalid paging cursor: ${JSON.stringify(cursor)} (createdAt is not a valid timestamp)`,\n );\n }\n return { createdAt, id: (parsed as { id: string }).id };\n}\n\nexport class DriveNodeView implements IDriveReadModel {\n constructor(private readonly db: Kysely<ReactorDriveDatabase>) {}\n\n async getNode(\n driveId: string,\n nodeId: string,\n ): Promise<ReactorDriveNode | undefined> {\n const row = await this.db\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", nodeId)\n .executeTakeFirst();\n if (!row) return undefined;\n return rowToNode(row);\n }\n\n async listChildren(\n driveId: string,\n parentFolder: string | null | undefined,\n paging?: PagingOptions,\n ): Promise<PagedResults<ReactorDriveNode>> {\n const { limit, cursor } = parseListChildrenPaging(paging);\n\n let query = this.db\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId);\n\n if (parentFolder === null) {\n query = query.where(\"parentFolder\", \"is\", null);\n } else if (parentFolder !== undefined) {\n query = query.where(\"parentFolder\", \"=\", parentFolder);\n }\n\n if (cursor !== null) {\n query = query.where((eb) =>\n eb(\n eb.refTuple(\"createdAt\", \"id\"),\n \">\",\n eb.tuple(cursor.createdAt, cursor.id),\n ),\n );\n }\n\n const rows = await query\n .orderBy(\"createdAt\", \"asc\")\n .orderBy(\"id\", \"asc\")\n .limit(limit + 1)\n .execute();\n\n const hasMore = rows.length > limit;\n const sliced = hasMore ? rows.slice(0, limit) : rows;\n const last = sliced[sliced.length - 1];\n\n return {\n results: sliced.map(rowToNode),\n options: { cursor: paging?.cursor ?? \"\", limit },\n nextCursor: hasMore\n ? encodeKeysetCursor(last.createdAt, last.id)\n : undefined,\n };\n }\n\n async listAll(driveId: string): Promise<ReactorDriveNode[]> {\n const rows = await this.db\n .selectFrom(\"DriveNode\")\n .selectAll()\n .where(\"driveId\", \"=\", driveId)\n .orderBy(\"createdAt\", \"asc\")\n .orderBy(\"id\", \"asc\")\n .execute();\n return rows.map(rowToNode);\n }\n\n async getDescendants(\n driveId: string,\n root: string,\n ): Promise<ReactorDriveNode[]> {\n const rows = await this.db\n .withRecursive(\"descendants\", (qb) =>\n qb\n .selectFrom(\"DriveNode\")\n .select([\n \"driveId\",\n \"id\",\n \"kind\",\n \"name\",\n \"requestedName\",\n \"parentFolder\",\n \"documentType\",\n \"createdAt\",\n ])\n .where(\"driveId\", \"=\", driveId)\n .where(\"id\", \"=\", root)\n .unionAll(\n qb\n .selectFrom(\"DriveNode\")\n .innerJoin(\n \"descendants\",\n \"DriveNode.parentFolder\",\n \"descendants.id\",\n )\n .where(\"DriveNode.driveId\", \"=\", driveId)\n .select([\n \"DriveNode.driveId\",\n \"DriveNode.id\",\n \"DriveNode.kind\",\n \"DriveNode.name\",\n \"DriveNode.requestedName\",\n \"DriveNode.parentFolder\",\n \"DriveNode.documentType\",\n \"DriveNode.createdAt\",\n ]),\n ),\n )\n .selectFrom(\"descendants\")\n .select([\n \"driveId\",\n \"id\",\n \"kind\",\n \"name\",\n \"requestedName\",\n \"parentFolder\",\n \"documentType\",\n ])\n .orderBy(\"createdAt\", \"asc\")\n .orderBy(\"id\", \"asc\")\n .execute();\n return rows.map(rowToNode);\n }\n}\n\ntype DriveNodeRow = {\n driveId: string;\n id: string;\n kind: \"file\" | \"folder\";\n name: string;\n requestedName: string;\n parentFolder: string | null;\n documentType: string | null;\n};\n\nfunction rowToNode(row: DriveNodeRow): ReactorDriveNode {\n if (row.kind === \"file\") {\n if (row.documentType === null) {\n throw new Error(\n `DriveNode ${row.driveId}/${row.id}: file row has null documentType, which violates the schema CHECK constraint`,\n );\n }\n const node: ReactorDriveFileNode = {\n kind: \"file\",\n id: row.id,\n driveId: row.driveId,\n parentFolder: row.parentFolder,\n name: row.name,\n documentType: row.documentType,\n };\n return node;\n }\n const node: ReactorDriveFolderNode = {\n kind: \"folder\",\n id: row.id,\n driveId: row.driveId,\n parentFolder: row.parentFolder,\n name: row.name,\n };\n return node;\n}\n","import {\n addRelationshipAction,\n createDocumentAction,\n removeRelationshipAction,\n upgradeDocumentAction,\n type BatchExecutionRequest,\n type ExecutionJobPlan,\n type IDriveClient,\n type IReactorClient,\n type PagedResults,\n type PagingOptions,\n type PropagationMode,\n} from \"@powerhousedao/reactor\";\nimport type {\n DocumentDriveDocument,\n DriveInput,\n FileNode,\n FolderNode,\n Node,\n} from \"@powerhousedao/shared/document-drive\";\nimport {\n createPresignedHeader,\n generateId,\n replayDocument,\n type Action,\n type CreateDocumentActionInput,\n type PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n REACTOR_DRIVE_DOCUMENT_TYPE,\n} from \"../constants.js\";\nimport {\n addFolderAction,\n removeFolderAction,\n setAvailableOfflineAction,\n setDriveIconAction,\n setDriveNameAction,\n setSharingTypeAction,\n updateFolderAction,\n} from \"../actions.js\";\nimport { reactorDriveCreateDocument } from \"../module.js\";\nimport type { IDriveReadModel } from \"../read-model/interfaces.js\";\nimport type {\n DriveChildFileMetadata,\n ReactorDriveFileNode,\n ReactorDriveFolderNode,\n ReactorDriveNode,\n} from \"../types.js\";\n\nexport interface ReactorDriveClientArgs {\n reactor: IReactorClient;\n readModel: IDriveReadModel;\n}\n\n/**\n * Implementation of {@link IDriveClient} backed by the reactor's relationship\n * primitives and the drive-scoped folder actions. Folder structure lives in\n * the operation log (ADD_FOLDER/UPDATE_FOLDER/REMOVE_FOLDER + ADD_RELATIONSHIP\n * for files) and is materialised by `NodeProcessor` into the `DriveNode`\n * table consumed via {@link IDriveReadModel}.\n */\nexport class ReactorDriveClient implements IDriveClient {\n private readonly reactor: IReactorClient;\n private readonly readModel: IDriveReadModel;\n\n constructor(args: ReactorDriveClientArgs) {\n this.reactor = args.reactor;\n this.readModel = args.readModel;\n }\n\n async create(\n input: DriveInput,\n signal?: AbortSignal,\n ): Promise<DocumentDriveDocument> {\n const driveDoc = reactorDriveCreateDocument({\n global: {\n name: input.global.name,\n icon: input.global.icon ?? null,\n },\n });\n if (input.local) {\n if (typeof input.local.sharingType === \"string\") {\n driveDoc.state.local.sharingType = input.local.sharingType;\n }\n if (typeof input.local.availableOffline === \"boolean\") {\n driveDoc.state.local.availableOffline = input.local.availableOffline;\n }\n }\n if (input.preferredEditor) {\n driveDoc.header.meta = {\n ...driveDoc.header.meta,\n preferredEditor: input.preferredEditor,\n };\n }\n const created = await this.reactor.create(driveDoc, undefined, signal);\n return this.toLegacyDriveDocument(created, created.header.id);\n }\n\n async addFile<TDocument extends PHDocument = PHDocument>(\n driveIdentifier: string,\n document: PHDocument,\n parentFolder?: string,\n signal?: AbortSignal,\n ): Promise<TDocument> {\n const documentId = document.header.id;\n\n const createInput: CreateDocumentActionInput = {\n model: document.header.documentType,\n version: 0,\n documentId,\n signing: {\n signature: documentId,\n publicKey: document.header.sig.publicKey,\n nonce: document.header.sig.nonce,\n createdAtUtcIso: document.header.createdAtUtcIso,\n documentType: document.header.documentType,\n },\n slug: document.header.slug,\n name: document.header.name,\n branch: document.header.branch,\n meta: document.header.meta,\n protocolVersions: document.header.protocolVersions ?? {\n \"base-reducer\": 2,\n },\n };\n\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: parentFolder ?? null,\n documentType: document.header.documentType,\n };\n\n const request: BatchExecutionRequest = {\n jobs: [\n {\n key: \"create\",\n documentId,\n scope: \"document\",\n branch: \"main\",\n actions: [\n createDocumentAction(createInput),\n upgradeDocumentAction({\n documentId,\n model: document.header.documentType,\n fromVersion: 0,\n toVersion: document.state.document.version,\n initialState: document.state,\n }),\n ],\n dependsOn: [],\n },\n {\n key: \"link\",\n documentId: driveIdentifier,\n scope: \"document\",\n branch: \"main\",\n actions: [\n addRelationshipAction(\n driveIdentifier,\n documentId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n ),\n ],\n dependsOn: [\"create\"],\n },\n ],\n };\n\n await this.reactor.executeBatch(request, signal);\n return this.reactor.get<TDocument>(documentId, undefined, signal);\n }\n\n async addFolder(\n driveIdentifier: string,\n name: string,\n parentFolder?: string,\n signal?: AbortSignal,\n ): Promise<FolderNode> {\n const folderId = generateId();\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n addFolderAction({\n folderId,\n parentFolderId: parentFolder ?? null,\n name,\n }),\n ],\n signal,\n );\n return {\n id: folderId,\n kind: \"folder\",\n name,\n parentFolder: parentFolder ?? null,\n };\n }\n\n async removeNode(\n driveIdentifier: string,\n nodeId: string,\n signal?: AbortSignal,\n ): Promise<void> {\n const node = await this.readModel.getNode(driveIdentifier, nodeId, signal);\n if (!node) {\n throw new Error(`Node ${nodeId} not found in drive ${driveIdentifier}`);\n }\n\n if (node.kind === \"folder\") {\n const subtree = await this.readModel.getDescendants(\n driveIdentifier,\n nodeId,\n signal,\n );\n const fileDescendants = subtree.filter(\n (n): n is ReactorDriveFileNode => n.kind === \"file\",\n );\n const subFolders = subtree\n .filter((n): n is ReactorDriveFolderNode => n.kind === \"folder\")\n .filter((f) => f.id !== nodeId);\n const deepestFirstFolders = this.orderDeepestFirst(subFolders, nodeId);\n\n const batch: Action[] = [\n ...fileDescendants.map((f) =>\n removeRelationshipAction(\n driveIdentifier,\n f.id,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n ),\n ),\n ...deepestFirstFolders.map((f) =>\n removeFolderAction({ folderId: f.id }),\n ),\n removeFolderAction({ folderId: nodeId }),\n ];\n\n await this.reactor.execute(driveIdentifier, \"main\", batch, signal);\n\n for (const file of fileDescendants) {\n await this.reactor.deleteDocument(\n file.id,\n \"cascade\" as PropagationMode,\n signal,\n );\n }\n return;\n }\n\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n removeRelationshipAction(\n driveIdentifier,\n nodeId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n ),\n ],\n signal,\n );\n await this.reactor.deleteDocument(nodeId, undefined, signal);\n }\n\n async renameNode(\n driveIdentifier: string,\n nodeId: string,\n name: string,\n signal?: AbortSignal,\n ): Promise<Node> {\n const node = await this.readModel.getNode(driveIdentifier, nodeId, signal);\n if (!node) {\n throw new Error(`Node ${nodeId} not found in drive ${driveIdentifier}`);\n }\n\n if (node.kind === \"file\") {\n await this.reactor.rename(nodeId, name, \"main\", signal);\n } else {\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [updateFolderAction({ folderId: nodeId, name })],\n signal,\n );\n }\n\n const updated = await this.readModel.getNode(\n driveIdentifier,\n nodeId,\n signal,\n );\n if (!updated) {\n throw new Error(\"Node missing from drive after rename\");\n }\n return this.toLegacyNode(updated);\n }\n\n async setPreferredEditorOnNode(\n nodeId: string,\n preferredEditor: string | null,\n signal?: AbortSignal,\n ): Promise<PHDocument> {\n return this.reactor.setPreferredEditor(\n nodeId,\n preferredEditor,\n \"main\",\n signal,\n );\n }\n\n async moveNode(\n driveIdentifier: string,\n srcNodeId: string,\n targetParentFolderId: string | undefined,\n signal?: AbortSignal,\n ): Promise<DocumentDriveDocument> {\n const node = await this.readModel.getNode(\n driveIdentifier,\n srcNodeId,\n signal,\n );\n if (!node) {\n throw new Error(\n `Node ${srcNodeId} not found in drive ${driveIdentifier}`,\n );\n }\n\n if (node.kind === \"folder\") {\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n updateFolderAction({\n folderId: srcNodeId,\n parentFolderId: targetParentFolderId ?? null,\n }),\n ],\n signal,\n );\n } else {\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: targetParentFolderId ?? null,\n documentType: node.documentType,\n };\n await this.reactor.execute(\n driveIdentifier,\n \"main\",\n [\n removeRelationshipAction(\n driveIdentifier,\n srcNodeId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n ),\n addRelationshipAction(\n driveIdentifier,\n srcNodeId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n ),\n ],\n signal,\n );\n }\n\n const drive = await this.reactor.get<PHDocument>(\n driveIdentifier,\n undefined,\n signal,\n );\n return this.toLegacyDriveDocument(drive, driveIdentifier);\n }\n\n async copyNode(\n driveIdentifier: string,\n srcNodeId: string,\n targetParentFolderId: string | undefined,\n signal?: AbortSignal,\n ): Promise<DocumentDriveDocument> {\n const srcNode = await this.readModel.getNode(\n driveIdentifier,\n srcNodeId,\n signal,\n );\n if (!srcNode) {\n throw new Error(\n `Node ${srcNodeId} not found in drive ${driveIdentifier}`,\n );\n }\n\n const subtree = await this.readModel.getDescendants(\n driveIdentifier,\n srcNodeId,\n signal,\n );\n\n if (\n targetParentFolderId !== undefined &&\n subtree.some((n) => n.id === targetParentFolderId)\n ) {\n throw new Error(\n `Cannot copy node ${srcNodeId} into itself or one of its descendants (target: ${targetParentFolderId})`,\n );\n }\n\n const idMap = new Map<string, string>();\n for (const node of subtree) {\n idMap.set(node.id, generateId());\n }\n\n const jobs: ExecutionJobPlan[] = [];\n const driveActions: Action[] = [];\n const fileCreateKeys: string[] = [];\n\n for (const node of subtree) {\n const newId = idMap.get(node.id)!;\n let newParent: string | null;\n if (node.id === srcNodeId) {\n newParent = targetParentFolderId ?? null;\n } else {\n if (node.parentFolder == null) {\n throw new Error(\n `copyNode: descendant ${node.id} has no parentFolder`,\n );\n }\n const mapped = idMap.get(node.parentFolder);\n if (mapped === undefined) {\n throw new Error(\n `copyNode: descendant ${node.id} parent ${node.parentFolder} missing from idMap`,\n );\n }\n newParent = mapped;\n }\n\n if (node.kind === \"folder\") {\n driveActions.push(\n addFolderAction({\n folderId: newId,\n parentFolderId: newParent,\n name: node.name,\n }),\n );\n continue;\n }\n\n const srcDoc = await this.reactor.get<PHDocument>(\n node.id,\n undefined,\n signal,\n );\n const documentModelModule = await this.reactor.getDocumentModelModule(\n srcDoc.header.documentType,\n );\n const duplicated: PHDocument = replayDocument(\n srcDoc.initialState,\n srcDoc.operations,\n documentModelModule.reducer,\n createPresignedHeader(newId, srcDoc.header.documentType),\n );\n duplicated.header.name = node.name;\n\n const createInput: CreateDocumentActionInput = {\n model: duplicated.header.documentType,\n version: 0,\n documentId: newId,\n signing: {\n signature: newId,\n publicKey: duplicated.header.sig.publicKey,\n nonce: duplicated.header.sig.nonce,\n createdAtUtcIso: duplicated.header.createdAtUtcIso,\n documentType: duplicated.header.documentType,\n },\n slug: duplicated.header.slug,\n name: duplicated.header.name,\n branch: duplicated.header.branch,\n meta: duplicated.header.meta,\n protocolVersions: duplicated.header.protocolVersions ?? {\n \"base-reducer\": 2,\n },\n };\n\n const createKey = `create:${newId}`;\n jobs.push({\n key: createKey,\n documentId: newId,\n scope: \"document\",\n branch: \"main\",\n actions: [\n createDocumentAction(createInput),\n upgradeDocumentAction({\n documentId: newId,\n model: duplicated.header.documentType,\n fromVersion: 0,\n toVersion: duplicated.state.document.version,\n initialState: duplicated.state,\n }),\n ],\n dependsOn: [],\n });\n fileCreateKeys.push(createKey);\n\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: newParent,\n documentType: duplicated.header.documentType,\n };\n driveActions.push(\n addRelationshipAction(\n driveIdentifier,\n newId,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n ),\n );\n }\n\n if (driveActions.length > 0) {\n jobs.push({\n key: \"drive\",\n documentId: driveIdentifier,\n scope: \"document\",\n branch: \"main\",\n actions: driveActions,\n dependsOn: fileCreateKeys,\n });\n }\n\n if (jobs.length > 0) {\n const request: BatchExecutionRequest = { jobs };\n await this.reactor.executeBatch(request, signal);\n }\n\n const drive = await this.reactor.get<PHDocument>(\n driveIdentifier,\n undefined,\n signal,\n );\n return this.toLegacyDriveDocument(drive, driveIdentifier);\n }\n\n async getNode(\n driveIdentifier: string,\n nodeId: string,\n signal?: AbortSignal,\n ): Promise<Node> {\n const node = await this.readModel.getNode(driveIdentifier, nodeId, signal);\n if (!node) {\n throw new Error(`Node ${nodeId} not found in drive ${driveIdentifier}`);\n }\n return this.toLegacyNode(node);\n }\n\n async listNodes(\n driveIdentifier: string,\n parentFolder?: string | null,\n paging?: PagingOptions,\n signal?: AbortSignal,\n ): Promise<PagedResults<Node>> {\n const page = await this.readModel.listChildren(\n driveIdentifier,\n parentFolder,\n paging,\n signal,\n );\n return {\n results: page.results.map((node) => this.toLegacyNode(node)),\n options: page.options,\n ...(page.nextCursor !== undefined ? { nextCursor: page.nextCursor } : {}),\n ...(page.totalCount !== undefined ? { totalCount: page.totalCount } : {}),\n };\n }\n\n private toLegacyNode(node: ReactorDriveNode): Node {\n if (node.kind === \"file\") {\n const file: ReactorDriveFileNode = node;\n const legacy: FileNode = {\n id: file.id,\n kind: \"file\",\n name: file.name,\n parentFolder: file.parentFolder,\n documentType: file.documentType,\n };\n return legacy;\n }\n const folder: ReactorDriveFolderNode = node;\n const legacy: FolderNode = {\n id: folder.id,\n kind: \"folder\",\n name: folder.name,\n parentFolder: folder.parentFolder,\n };\n return legacy;\n }\n\n private async toLegacyDriveDocument(\n doc: PHDocument,\n driveId: string,\n ): Promise<DocumentDriveDocument> {\n if (doc.header.documentType !== REACTOR_DRIVE_DOCUMENT_TYPE) {\n throw new Error(\n `Document ${doc.header.id} is not a reactor-drive document`,\n );\n }\n const allNodes = await this.readModel.listAll(driveId);\n const legacy = structuredClone(doc) as unknown as DocumentDriveDocument;\n const existingGlobal = legacy.state.global as Partial<\n DocumentDriveDocument[\"state\"][\"global\"]\n >;\n legacy.state.global = {\n name: existingGlobal.name ?? \"\",\n icon: existingGlobal.icon ?? null,\n nodes: allNodes.map((n) => this.toLegacyNode(n)),\n };\n return legacy;\n }\n\n private orderDeepestFirst(\n folders: ReactorDriveFolderNode[],\n rootId: string,\n ): ReactorDriveFolderNode[] {\n const depthById = new Map<string, number>();\n const compute = (id: string): number => {\n if (id === rootId) return 0;\n const cached = depthById.get(id);\n if (cached !== undefined) return cached;\n const folder = folders.find((f) => f.id === id);\n if (!folder) return 0;\n const parent = folder.parentFolder ?? rootId;\n const depth = compute(parent) + 1;\n depthById.set(id, depth);\n return depth;\n };\n return folders.slice().sort((a, b) => compute(b.id) - compute(a.id));\n }\n}\n\nexport {\n setAvailableOfflineAction,\n setDriveIconAction,\n setDriveNameAction,\n setSharingTypeAction,\n};\n","import { gql } from \"graphql-tag\";\n\nexport const typeDefs = gql`\n enum ReactorDriveNodeKind {\n FILE\n FOLDER\n }\n\n input ReactorDrivePagingInput {\n cursor: String\n limit: Int\n }\n\n type ReactorDriveFileNode {\n id: ID!\n driveId: ID!\n name: String!\n parentFolder: ID\n documentType: String!\n }\n\n type ReactorDriveFolderNode {\n id: ID!\n driveId: ID!\n name: String!\n parentFolder: ID\n children(\n paging: ReactorDrivePagingInput\n kind: ReactorDriveNodeKind\n ): ReactorDriveNodePage!\n }\n\n union ReactorDriveNode = ReactorDriveFileNode | ReactorDriveFolderNode\n\n type ReactorDriveNodePage {\n results: [ReactorDriveNode!]!\n nextCursor: String\n hasMore: Boolean!\n totalCount: Int\n }\n\n type ReactorDrive {\n id: ID!\n name: String!\n icon: String\n sharingType: String!\n availableOffline: Boolean!\n rootNodes(\n paging: ReactorDrivePagingInput\n kind: ReactorDriveNodeKind\n ): ReactorDriveNodePage!\n }\n\n type Query {\n reactorDrive(id: ID!): ReactorDrive\n reactorDriveNode(driveId: ID!, id: ID!): ReactorDriveNode\n reactorDriveDescendants(driveId: ID!, root: ID!): [ReactorDriveNode!]!\n }\n`;\n","import type {\n IReactorClient,\n PagedResults,\n PagingOptions,\n} from \"@powerhousedao/reactor\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { REACTOR_DRIVE_DOCUMENT_TYPE } from \"../constants.js\";\nimport type { IDriveReadModel } from \"../read-model/interfaces.js\";\nimport type { ReactorDrivePHState, ReactorDriveNode } from \"../types.js\";\n\nexport interface ReactorDriveResolverContext {\n reactorClient: IReactorClient;\n readModel: IDriveReadModel;\n}\n\ntype PagingInput = { cursor?: string; limit?: number };\ntype NodeKindFilter = \"FILE\" | \"FOLDER\" | undefined;\n\nconst DEFAULT_LIMIT = 100;\n\nfunction toPaging(input: PagingInput | undefined): PagingOptions | undefined {\n if (!input) return undefined;\n return {\n cursor: input.cursor ?? \"\",\n limit: input.limit ?? DEFAULT_LIMIT,\n };\n}\n\nfunction filterByKind(\n page: PagedResults<ReactorDriveNode>,\n kind: NodeKindFilter,\n): PagedResults<ReactorDriveNode> {\n if (!kind) return page;\n const wanted = kind === \"FILE\" ? \"file\" : \"folder\";\n return {\n ...page,\n results: page.results.filter((node) => node.kind === wanted),\n };\n}\n\nfunction shapePage(page: PagedResults<ReactorDriveNode>) {\n return {\n results: page.results,\n nextCursor: page.nextCursor,\n hasMore: page.nextCursor !== undefined,\n totalCount: page.totalCount,\n };\n}\n\n/**\n * Builds GraphQL resolvers backed by the drive read model. The resolvers are\n * pure — every external dependency is read off the GraphQL context. Wiring\n * the resolvers into a subgraph (e.g. `reactor-api`'s `ISubgraph`) is the\n * caller's responsibility.\n */\nexport function createReactorDriveResolvers() {\n return {\n Query: {\n async reactorDrive(\n _root: unknown,\n args: { id: string },\n ctx: ReactorDriveResolverContext,\n ) {\n const document = await ctx.reactorClient.get<\n PHDocument<ReactorDrivePHState>\n >(args.id);\n if (document.header.documentType !== REACTOR_DRIVE_DOCUMENT_TYPE) {\n return null;\n }\n return {\n id: document.header.id,\n name: document.state.global.name,\n icon: document.state.global.icon,\n sharingType: document.state.local.sharingType,\n availableOffline: document.state.local.availableOffline,\n };\n },\n async reactorDriveNode(\n _root: unknown,\n args: { driveId: string; id: string },\n ctx: ReactorDriveResolverContext,\n ) {\n return ctx.readModel.getNode(args.driveId, args.id);\n },\n async reactorDriveDescendants(\n _root: unknown,\n args: { driveId: string; root: string },\n ctx: ReactorDriveResolverContext,\n ) {\n return ctx.readModel.getDescendants(args.driveId, args.root);\n },\n },\n ReactorDrive: {\n async rootNodes(\n parent: { id: string },\n args: { paging?: PagingInput; kind?: NodeKindFilter },\n ctx: ReactorDriveResolverContext,\n ) {\n const page = await ctx.readModel.listChildren(\n parent.id,\n null,\n toPaging(args.paging),\n );\n return shapePage(filterByKind(page, args.kind));\n },\n },\n ReactorDriveFolderNode: {\n async children(\n parent: { id: string; driveId: string },\n args: { paging?: PagingInput; kind?: NodeKindFilter },\n ctx: ReactorDriveResolverContext,\n ) {\n const page = await ctx.readModel.listChildren(\n parent.driveId,\n parent.id,\n toPaging(args.paging),\n );\n return shapePage(filterByKind(page, args.kind));\n },\n },\n ReactorDriveNode: {\n __resolveType(node: ReactorDriveNode) {\n return node.kind === \"file\"\n ? \"ReactorDriveFileNode\"\n : \"ReactorDriveFolderNode\";\n },\n },\n };\n}\n","import {\n addRelationshipAction,\n type IReactorClient,\n} from \"@powerhousedao/reactor\";\nimport type { FileNode, Node } from \"@powerhousedao/shared/document-drive\";\nimport type { Action } from \"@powerhousedao/shared/document-model\";\nimport { addFolderAction } from \"../actions.js\";\nimport { DRIVE_CHILD_RELATIONSHIP_TYPE } from \"../constants.js\";\nimport type { IDriveReadModel } from \"../read-model/interfaces.js\";\nimport type { DriveChildFileMetadata } from \"../types.js\";\n\nexport interface MigrateLegacyDriveStateArgs {\n reactor: IReactorClient;\n readModel: IDriveReadModel;\n driveId: string;\n nodes: Node[];\n branch?: string;\n signal?: AbortSignal;\n}\n\nexport interface MigrateLegacyDriveStateResult {\n emittedActions: number;\n skippedExisting: number;\n}\n\n/**\n * Translates a legacy `document-drive` `state.global.nodes` array into the\n * action vocabulary used by the new reactor-drive module.\n *\n * Folder nodes are emitted as `ADD_FOLDER` actions targeting the drive\n * document. File nodes are emitted as `ADD_RELATIONSHIP` actions on the drive\n * with `drive/child` metadata carrying the parent folder id. File nodes\n * assume the underlying PHDocument still exists under the same id — the\n * migration only re-links it into the new drive, it does not recreate\n * documents.\n *\n * Re-running the migration is safe: existing `DriveNode` rows are skipped\n * so already-migrated nodes are left untouched.\n */\nexport async function migrateLegacyDriveState(\n args: MigrateLegacyDriveStateArgs,\n): Promise<MigrateLegacyDriveStateResult> {\n const { reactor, readModel, driveId, nodes, signal } = args;\n const branch = args.branch ?? \"main\";\n\n const ordered = orderLegacyNodes(nodes);\n const actions: Action[] = [];\n let skippedExisting = 0;\n\n for (const node of ordered) {\n const existing = await readModel.getNode(driveId, node.id, signal);\n if (existing) {\n skippedExisting += 1;\n continue;\n }\n actions.push(toAction(driveId, node));\n }\n\n if (actions.length === 0) {\n return { emittedActions: 0, skippedExisting };\n }\n\n await reactor.execute(driveId, branch, actions, signal);\n return { emittedActions: actions.length, skippedExisting };\n}\n\nfunction toAction(driveId: string, node: Node): Action {\n if (node.kind === \"folder\") {\n return addFolderAction({\n folderId: node.id,\n parentFolderId: node.parentFolder ?? null,\n name: node.name,\n });\n }\n const fileNode = node as FileNode;\n const metadata: DriveChildFileMetadata = {\n kind: \"file\",\n parentFolderId: fileNode.parentFolder ?? null,\n documentType: fileNode.documentType,\n };\n return addRelationshipAction(\n driveId,\n fileNode.id,\n DRIVE_CHILD_RELATIONSHIP_TYPE,\n metadata,\n );\n}\n\n/**\n * Sorts legacy nodes so that any folder appears before its children. The\n * legacy state stores nodes in insertion order, which usually already\n * satisfies that property, but defensive sorting keeps replay deterministic\n * if the input was constructed out of order.\n */\nfunction orderLegacyNodes(nodes: Node[]): Node[] {\n const byId = new Map<string, Node>();\n for (const node of nodes) {\n byId.set(node.id, node);\n }\n const visited = new Set<string>();\n const ordered: Node[] = [];\n\n for (const start of nodes) {\n if (visited.has(start.id)) continue;\n const chain: Node[] = [];\n const seenInWalk = new Set<string>();\n let current: Node | undefined = start;\n while (current && !visited.has(current.id) && !seenInWalk.has(current.id)) {\n seenInWalk.add(current.id);\n chain.push(current);\n const parentId: string | null | undefined = current.parentFolder;\n current = parentId ? byId.get(parentId) : undefined;\n }\n while (chain.length > 0) {\n const node = chain.pop()!;\n if (visited.has(node.id)) continue;\n visited.add(node.id);\n ordered.push(node);\n }\n }\n return ordered;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powerhousedao/reactor-drive",
3
- "version": "6.1.0-staging.0",
3
+ "version": "6.2.0-dev.0",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "repository": {
@@ -25,9 +25,9 @@
25
25
  "graphql": "^16",
26
26
  "graphql-tag": "^2",
27
27
  "kysely": "0.28.16",
28
- "@powerhousedao/reactor": "6.1.0-staging.0",
29
- "@powerhousedao/shared": "6.1.0-staging.0",
30
- "document-model": "6.1.0-staging.0"
28
+ "@powerhousedao/reactor": "6.2.0-dev.0",
29
+ "@powerhousedao/shared": "6.2.0-dev.0",
30
+ "document-model": "6.2.0-dev.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@electric-sql/pglite": "0.3.15",