@arke-institute/sdk 0.1.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -184
- package/dist/generated/index.cjs +19 -0
- package/dist/generated/index.cjs.map +1 -0
- package/dist/generated/index.d.cts +6192 -0
- package/dist/generated/index.d.ts +6192 -0
- package/dist/generated/index.js +1 -0
- package/dist/generated/index.js.map +1 -0
- package/dist/index-BrXke2kI.d.ts +302 -0
- package/dist/index-FHcLPBSV.d.cts +302 -0
- package/dist/index.cjs +188 -3654
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -7
- package/dist/index.d.ts +62 -7
- package/dist/index.js +168 -3626
- package/dist/index.js.map +1 -1
- package/dist/operations/index.cjs +113 -0
- package/dist/operations/index.cjs.map +1 -0
- package/dist/operations/index.d.cts +3 -0
- package/dist/operations/index.d.ts +3 -0
- package/dist/operations/index.js +84 -0
- package/dist/operations/index.js.map +1 -0
- package/package.json +44 -53
- package/dist/client-dAk3E64p.d.cts +0 -183
- package/dist/client-dAk3E64p.d.ts +0 -183
- package/dist/collections/index.cjs +0 -233
- package/dist/collections/index.cjs.map +0 -1
- package/dist/collections/index.d.cts +0 -9
- package/dist/collections/index.d.ts +0 -9
- package/dist/collections/index.js +0 -205
- package/dist/collections/index.js.map +0 -1
- package/dist/content/index.cjs +0 -506
- package/dist/content/index.cjs.map +0 -1
- package/dist/content/index.d.cts +0 -403
- package/dist/content/index.d.ts +0 -403
- package/dist/content/index.js +0 -473
- package/dist/content/index.js.map +0 -1
- package/dist/edit/index.cjs +0 -1029
- package/dist/edit/index.cjs.map +0 -1
- package/dist/edit/index.d.cts +0 -78
- package/dist/edit/index.d.ts +0 -78
- package/dist/edit/index.js +0 -983
- package/dist/edit/index.js.map +0 -1
- package/dist/errors-3L7IiHcr.d.cts +0 -480
- package/dist/errors-B82BMmRP.d.cts +0 -343
- package/dist/errors-B82BMmRP.d.ts +0 -343
- package/dist/errors-BTe8GKRQ.d.ts +0 -480
- package/dist/graph/index.cjs +0 -433
- package/dist/graph/index.cjs.map +0 -1
- package/dist/graph/index.d.cts +0 -456
- package/dist/graph/index.d.ts +0 -456
- package/dist/graph/index.js +0 -402
- package/dist/graph/index.js.map +0 -1
- package/dist/query/index.cjs +0 -289
- package/dist/query/index.cjs.map +0 -1
- package/dist/query/index.d.cts +0 -541
- package/dist/query/index.d.ts +0 -541
- package/dist/query/index.js +0 -261
- package/dist/query/index.js.map +0 -1
- package/dist/upload/index.cjs +0 -1634
- package/dist/upload/index.cjs.map +0 -1
- package/dist/upload/index.d.cts +0 -150
- package/dist/upload/index.d.ts +0 -150
- package/dist/upload/index.js +0 -1597
- package/dist/upload/index.js.map +0 -1
package/dist/edit/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/edit/errors.ts","../../src/edit/client.ts","../../src/edit/diff.ts","../../src/edit/prompts.ts","../../src/edit/session.ts"],"sourcesContent":["/**\n * Error classes for edit operations\n */\n\nexport class EditError extends Error {\n constructor(\n message: string,\n public code: string = 'UNKNOWN_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'EditError';\n }\n}\n\nexport class EntityNotFoundError extends EditError {\n constructor(pi: string) {\n super(`Entity not found: ${pi}`, 'ENTITY_NOT_FOUND', { pi });\n this.name = 'EntityNotFoundError';\n }\n}\n\nexport class CASConflictError extends EditError {\n constructor(pi: string, expectedTip: string, actualTip: string) {\n super(\n `CAS conflict: entity ${pi} was modified (expected ${expectedTip}, got ${actualTip})`,\n 'CAS_CONFLICT',\n { pi, expectedTip, actualTip }\n );\n this.name = 'CASConflictError';\n }\n}\n\nexport class ReprocessError extends EditError {\n constructor(message: string, batchId?: string) {\n super(message, 'REPROCESS_ERROR', { batchId });\n this.name = 'ReprocessError';\n }\n}\n\nexport class ValidationError extends EditError {\n constructor(message: string, field?: string) {\n super(message, 'VALIDATION_ERROR', { field });\n this.name = 'ValidationError';\n }\n}\n\nexport class PermissionError extends EditError {\n constructor(message: string, pi?: string) {\n super(message, 'PERMISSION_DENIED', { pi });\n this.name = 'PermissionError';\n }\n}\n","/**\n * EditClient - Low-level API client for Arke edit operations\n *\n * Routes through the gateway:\n * - /api/* -> IPFS Wrapper (entities, content, uploads)\n * - /reprocess/* -> Reprocess API\n */\n\nimport type {\n Entity,\n EntityUpdate,\n EntityVersion,\n ReprocessRequest,\n ReprocessResult,\n ReprocessStatus,\n} from './types';\nimport {\n EditError,\n EntityNotFoundError,\n CASConflictError,\n ReprocessError,\n PermissionError,\n} from './errors';\n\n/** Configuration for EditClient */\nexport interface EditClientConfig {\n /** Gateway URL (e.g., https://gateway.arke.io) */\n gatewayUrl: string;\n /** JWT auth token */\n authToken?: string;\n /** Optional transform for status URLs (e.g., for CORS proxy) */\n statusUrlTransform?: (url: string) => string;\n}\n\n/** Default retry options for status polling */\nconst DEFAULT_RETRY_OPTIONS = {\n maxRetries: 5,\n initialDelayMs: 2000, // Start with 2s delay (orchestrator needs time to initialize)\n maxDelayMs: 30000, // Cap at 30s\n backoffMultiplier: 2, // Double each retry\n};\n\nexport class EditClient {\n private gatewayUrl: string;\n private authToken?: string;\n private statusUrlTransform?: (url: string) => string;\n\n constructor(config: EditClientConfig) {\n this.gatewayUrl = config.gatewayUrl.replace(/\\/$/, '');\n this.authToken = config.authToken;\n this.statusUrlTransform = config.statusUrlTransform;\n }\n\n /**\n * Update the auth token (useful for token refresh)\n */\n setAuthToken(token: string): void {\n this.authToken = token;\n }\n\n /**\n * Sleep for a given number of milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Execute a fetch with exponential backoff retry on transient errors\n */\n private async fetchWithRetry(\n url: string,\n options: RequestInit,\n retryOptions = DEFAULT_RETRY_OPTIONS\n ): Promise<Response> {\n let lastError: Error | null = null;\n let delay = retryOptions.initialDelayMs;\n\n for (let attempt = 0; attempt <= retryOptions.maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n\n // Retry on 5xx errors (server errors)\n if (response.status >= 500 && attempt < retryOptions.maxRetries) {\n lastError = new Error(`Server error: ${response.status} ${response.statusText}`);\n await this.sleep(delay);\n delay = Math.min(delay * retryOptions.backoffMultiplier, retryOptions.maxDelayMs);\n continue;\n }\n\n return response;\n } catch (error) {\n // Network errors - retry\n lastError = error as Error;\n if (attempt < retryOptions.maxRetries) {\n await this.sleep(delay);\n delay = Math.min(delay * retryOptions.backoffMultiplier, retryOptions.maxDelayMs);\n }\n }\n }\n\n throw lastError || new Error('Request failed after retries');\n }\n\n private getHeaders(): HeadersInit {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n };\n if (this.authToken) {\n headers['Authorization'] = `Bearer ${this.authToken}`;\n }\n return headers;\n }\n\n /**\n * Handle common error responses\n */\n private handleErrorResponse(response: Response, context: string): never {\n if (response.status === 403) {\n throw new PermissionError(`Permission denied: ${context}`);\n }\n throw new EditError(\n `${context}: ${response.statusText}`,\n 'API_ERROR',\n { status: response.status }\n );\n }\n\n // ===========================================================================\n // IPFS Wrapper Operations (via /api/*)\n // ===========================================================================\n\n /**\n * Fetch an entity by PI\n */\n async getEntity(pi: string): Promise<Entity> {\n const response = await fetch(`${this.gatewayUrl}/api/entities/${pi}`, {\n headers: this.getHeaders(),\n });\n\n if (response.status === 404) {\n throw new EntityNotFoundError(pi);\n }\n\n if (!response.ok) {\n this.handleErrorResponse(response, `Failed to fetch entity ${pi}`);\n }\n\n return response.json();\n }\n\n /**\n * Fetch content by CID\n */\n async getContent(cid: string): Promise<string> {\n const response = await fetch(`${this.gatewayUrl}/api/cat/${cid}`, {\n headers: this.getHeaders(),\n });\n\n if (!response.ok) {\n this.handleErrorResponse(response, `Failed to fetch content ${cid}`);\n }\n\n return response.text();\n }\n\n /**\n * Upload content and get CID\n */\n async uploadContent(content: string, filename: string): Promise<string> {\n const formData = new FormData();\n const blob = new Blob([content], { type: 'text/plain' });\n formData.append('file', blob, filename);\n\n const headers: HeadersInit = {};\n if (this.authToken) {\n headers['Authorization'] = `Bearer ${this.authToken}`;\n }\n\n const response = await fetch(`${this.gatewayUrl}/api/upload`, {\n method: 'POST',\n headers,\n body: formData,\n });\n\n if (!response.ok) {\n this.handleErrorResponse(response, 'Failed to upload content');\n }\n\n const result = await response.json();\n // Response format: [{ cid, name, size }]\n return result[0].cid;\n }\n\n /**\n * Update an entity with new components\n */\n async updateEntity(pi: string, update: EntityUpdate): Promise<EntityVersion> {\n const response = await fetch(`${this.gatewayUrl}/api/entities/${pi}/versions`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n expect_tip: update.expect_tip,\n components: update.components,\n components_remove: update.components_remove,\n note: update.note,\n }),\n });\n\n if (response.status === 409) {\n // CAS conflict - entity was modified\n const entity = await this.getEntity(pi);\n throw new CASConflictError(\n pi,\n update.expect_tip,\n entity.manifest_cid\n );\n }\n\n if (!response.ok) {\n this.handleErrorResponse(response, `Failed to update entity ${pi}`);\n }\n\n return response.json();\n }\n\n // ===========================================================================\n // Reprocess API Operations (via /reprocess/*)\n // ===========================================================================\n\n /**\n * Trigger reprocessing for an entity\n */\n async reprocess(request: ReprocessRequest): Promise<ReprocessResult> {\n const response = await fetch(`${this.gatewayUrl}/reprocess/reprocess`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({\n pi: request.pi,\n phases: request.phases,\n cascade: request.cascade,\n options: request.options,\n }),\n });\n\n if (response.status === 403) {\n const error = await response.json().catch(() => ({}));\n throw new PermissionError(\n error.message || `Permission denied to reprocess ${request.pi}`,\n request.pi\n );\n }\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({}));\n throw new ReprocessError(\n error.message || `Reprocess failed: ${response.statusText}`,\n undefined\n );\n }\n\n return response.json();\n }\n\n /**\n * Get reprocessing status by batch ID\n *\n * Uses exponential backoff retry to handle transient 500 errors\n * that occur when the orchestrator is initializing.\n *\n * @param statusUrl - The status URL returned from reprocess()\n * @param isFirstPoll - If true, uses a longer initial delay (orchestrator warmup)\n */\n async getReprocessStatus(statusUrl: string, isFirstPoll = false): Promise<ReprocessStatus> {\n // Use longer initial delay for first poll after triggering reprocess\n const retryOptions = isFirstPoll\n ? { ...DEFAULT_RETRY_OPTIONS, initialDelayMs: 3000 }\n : DEFAULT_RETRY_OPTIONS;\n\n // Apply URL transform if configured (for CORS proxy)\n const fetchUrl = this.statusUrlTransform ? this.statusUrlTransform(statusUrl) : statusUrl;\n\n const response = await this.fetchWithRetry(\n fetchUrl,\n { headers: this.getHeaders() },\n retryOptions\n );\n\n if (!response.ok) {\n throw new EditError(\n `Failed to fetch reprocess status: ${response.statusText}`,\n 'STATUS_ERROR',\n { status: response.status }\n );\n }\n\n return response.json();\n }\n}\n","/**\n * DiffEngine - Text comparison and diff formatting\n */\n\nimport * as Diff from 'diff';\nimport type { TextDiff, ComponentDiff, Correction } from './types';\n\nexport class DiffEngine {\n /**\n * Compute diff between two strings\n */\n static diff(original: string, modified: string): TextDiff[] {\n const changes = Diff.diffLines(original, modified);\n const diffs: TextDiff[] = [];\n let lineNumber = 1;\n\n for (const change of changes) {\n if (change.added) {\n diffs.push({\n type: 'addition',\n modified: change.value.trimEnd(),\n lineNumber,\n });\n } else if (change.removed) {\n diffs.push({\n type: 'deletion',\n original: change.value.trimEnd(),\n lineNumber,\n });\n } else {\n // Track line numbers for unchanged content\n const lines = change.value.split('\\n').length - 1;\n lineNumber += lines;\n }\n\n // Update line number for added content\n if (change.added) {\n lineNumber += change.value.split('\\n').length - 1;\n }\n }\n\n return diffs;\n }\n\n /**\n * Compute word-level diff for more granular changes\n */\n static diffWords(original: string, modified: string): TextDiff[] {\n const changes = Diff.diffWords(original, modified);\n const diffs: TextDiff[] = [];\n\n for (const change of changes) {\n if (change.added) {\n diffs.push({\n type: 'addition',\n modified: change.value,\n });\n } else if (change.removed) {\n diffs.push({\n type: 'deletion',\n original: change.value,\n });\n }\n }\n\n return diffs;\n }\n\n /**\n * Create a ComponentDiff from original and modified content\n */\n static createComponentDiff(\n componentName: string,\n original: string,\n modified: string\n ): ComponentDiff {\n const diffs = this.diff(original, modified);\n const hasChanges = diffs.length > 0;\n\n let summary: string;\n if (!hasChanges) {\n summary = 'No changes';\n } else {\n const additions = diffs.filter((d) => d.type === 'addition').length;\n const deletions = diffs.filter((d) => d.type === 'deletion').length;\n const parts: string[] = [];\n if (additions > 0) parts.push(`${additions} addition${additions > 1 ? 's' : ''}`);\n if (deletions > 0) parts.push(`${deletions} deletion${deletions > 1 ? 's' : ''}`);\n summary = parts.join(', ');\n }\n\n return {\n componentName,\n diffs,\n summary,\n hasChanges,\n };\n }\n\n /**\n * Format diffs for AI prompt consumption\n */\n static formatForPrompt(diffs: TextDiff[]): string {\n if (diffs.length === 0) {\n return 'No changes detected.';\n }\n\n const lines: string[] = [];\n\n for (const diff of diffs) {\n const linePrefix = diff.lineNumber ? `Line ${diff.lineNumber}: ` : '';\n\n if (diff.type === 'addition') {\n lines.push(`${linePrefix}+ ${diff.modified}`);\n } else if (diff.type === 'deletion') {\n lines.push(`${linePrefix}- ${diff.original}`);\n } else if (diff.type === 'change') {\n lines.push(`${linePrefix}\"${diff.original}\" → \"${diff.modified}\"`);\n }\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Format component diffs for AI prompt\n */\n static formatComponentDiffsForPrompt(componentDiffs: ComponentDiff[]): string {\n const sections: string[] = [];\n\n for (const cd of componentDiffs) {\n if (!cd.hasChanges) continue;\n\n sections.push(`## Changes to ${cd.componentName}:`);\n sections.push(this.formatForPrompt(cd.diffs));\n sections.push('');\n }\n\n return sections.join('\\n');\n }\n\n /**\n * Create a unified diff view\n */\n static unifiedDiff(\n original: string,\n modified: string,\n options?: { filename?: string; context?: number }\n ): string {\n const filename = options?.filename || 'content';\n const patch = Diff.createPatch(filename, original, modified, '', '', {\n context: options?.context ?? 3,\n });\n return patch;\n }\n\n /**\n * Extract corrections from diffs (specific text replacements)\n */\n static extractCorrections(\n original: string,\n modified: string,\n sourceFile?: string\n ): Correction[] {\n const wordDiffs = Diff.diffWords(original, modified);\n const corrections: Correction[] = [];\n\n let i = 0;\n while (i < wordDiffs.length) {\n const current = wordDiffs[i];\n\n // Look for removal followed by addition (a replacement)\n if (current.removed && i + 1 < wordDiffs.length && wordDiffs[i + 1].added) {\n const removed = current.value.trim();\n const added = wordDiffs[i + 1].value.trim();\n\n if (removed && added && removed !== added) {\n corrections.push({\n original: removed,\n corrected: added,\n sourceFile,\n });\n }\n i += 2;\n } else {\n i++;\n }\n }\n\n return corrections;\n }\n\n /**\n * Check if two strings are meaningfully different\n * (ignoring whitespace differences)\n */\n static hasSignificantChanges(original: string, modified: string): boolean {\n const normalizedOriginal = original.replace(/\\s+/g, ' ').trim();\n const normalizedModified = modified.replace(/\\s+/g, ' ').trim();\n return normalizedOriginal !== normalizedModified;\n }\n}\n","/**\n * PromptBuilder - Context-aware AI prompt construction\n */\n\nimport { DiffEngine } from './diff';\nimport type {\n RegeneratableComponent,\n EntityContext,\n CascadeContext,\n ComponentDiff,\n Correction,\n} from './types';\n\nexport class PromptBuilder {\n /**\n * Build prompt for AI-first mode (user provides instructions)\n */\n static buildAIPrompt(\n userPrompt: string,\n component: RegeneratableComponent,\n entityContext: EntityContext,\n currentContent?: string\n ): string {\n const sections: string[] = [];\n\n // User instruction\n sections.push(`## Instructions for ${component}`);\n sections.push(userPrompt);\n sections.push('');\n\n // Entity context\n sections.push('## Entity Context');\n sections.push(`- PI: ${entityContext.pi}`);\n sections.push(`- Current version: ${entityContext.ver}`);\n if (entityContext.parentPi) {\n sections.push(`- Parent: ${entityContext.parentPi}`);\n }\n if (entityContext.childrenCount > 0) {\n sections.push(`- Children: ${entityContext.childrenCount}`);\n }\n sections.push('');\n\n // Current content reference\n if (currentContent) {\n sections.push(`## Current ${component} content for reference:`);\n sections.push('```');\n sections.push(currentContent.slice(0, 2000)); // Truncate if very long\n if (currentContent.length > 2000) {\n sections.push('... [truncated]');\n }\n sections.push('```');\n }\n\n return sections.join('\\n');\n }\n\n /**\n * Build prompt incorporating manual edits and diffs\n */\n static buildEditReviewPrompt(\n componentDiffs: ComponentDiff[],\n corrections: Correction[],\n component: RegeneratableComponent,\n userInstructions?: string\n ): string {\n const sections: string[] = [];\n\n sections.push('## Manual Edits Made');\n sections.push('');\n sections.push('The following manual edits were made to this entity:');\n sections.push('');\n\n // Show diffs\n const diffContent = DiffEngine.formatComponentDiffsForPrompt(componentDiffs);\n if (diffContent) {\n sections.push(diffContent);\n }\n\n // Show corrections\n if (corrections.length > 0) {\n sections.push('## Corrections Identified');\n sections.push('');\n for (const correction of corrections) {\n const source = correction.sourceFile ? ` (in ${correction.sourceFile})` : '';\n sections.push(`- \"${correction.original}\" → \"${correction.corrected}\"${source}`);\n }\n sections.push('');\n }\n\n // User instructions\n sections.push('## Instructions');\n if (userInstructions) {\n sections.push(userInstructions);\n } else {\n sections.push(\n `Update the ${component} to accurately reflect these changes. ` +\n 'Ensure any corrections are incorporated and the content is consistent.'\n );\n }\n sections.push('');\n\n // Specific guidance per component\n sections.push('## Guidance');\n switch (component) {\n case 'pinax':\n sections.push(\n 'Update metadata fields to reflect any corrections. Pay special attention to dates, ' +\n 'names, and other factual information that may have been corrected.'\n );\n break;\n case 'description':\n sections.push(\n 'Regenerate the description incorporating the changes. Maintain the overall tone ' +\n 'and structure while ensuring accuracy based on the corrections.'\n );\n break;\n case 'cheimarros':\n sections.push(\n 'Update the knowledge graph to reflect any new or corrected entities, relationships, ' +\n 'and facts identified in the changes.'\n );\n break;\n }\n\n return sections.join('\\n');\n }\n\n /**\n * Build cascade-aware prompt additions\n */\n static buildCascadePrompt(basePrompt: string, cascadeContext: CascadeContext): string {\n const sections: string[] = [basePrompt];\n\n sections.push('');\n sections.push('## Cascade Context');\n sections.push('');\n sections.push(\n 'This edit is part of a cascading update. After updating this entity, ' +\n 'parent entities will also be updated to reflect these changes.'\n );\n sections.push('');\n\n if (cascadeContext.path.length > 1) {\n sections.push(`Cascade path: ${cascadeContext.path.join(' → ')}`);\n sections.push(`Depth: ${cascadeContext.depth}`);\n }\n\n if (cascadeContext.stopAtPi) {\n sections.push(`Cascade will stop at: ${cascadeContext.stopAtPi}`);\n }\n\n sections.push('');\n sections.push(\n 'Ensure the content accurately represents the source material so parent ' +\n 'aggregations will be correct.'\n );\n\n return sections.join('\\n');\n }\n\n /**\n * Build a general prompt combining multiple instructions\n */\n static buildCombinedPrompt(\n generalPrompt: string | undefined,\n componentPrompt: string | undefined,\n component: RegeneratableComponent\n ): string {\n const sections: string[] = [];\n\n if (generalPrompt) {\n sections.push('## General Instructions');\n sections.push(generalPrompt);\n sections.push('');\n }\n\n if (componentPrompt) {\n sections.push(`## Specific Instructions for ${component}`);\n sections.push(componentPrompt);\n sections.push('');\n }\n\n if (sections.length === 0) {\n return `Regenerate the ${component} based on the current entity content.`;\n }\n\n return sections.join('\\n');\n }\n\n /**\n * Build prompt for correction-based updates\n */\n static buildCorrectionPrompt(corrections: Correction[]): string {\n if (corrections.length === 0) {\n return '';\n }\n\n const sections: string[] = [];\n\n sections.push('## Corrections Applied');\n sections.push('');\n sections.push('The following corrections were made to the source content:');\n sections.push('');\n\n for (const correction of corrections) {\n const source = correction.sourceFile ? ` in ${correction.sourceFile}` : '';\n sections.push(`- \"${correction.original}\" was corrected to \"${correction.corrected}\"${source}`);\n if (correction.context) {\n sections.push(` Context: ${correction.context}`);\n }\n }\n\n sections.push('');\n sections.push(\n 'Update the metadata and description to reflect these corrections. ' +\n 'Previous content may have contained errors based on the incorrect text.'\n );\n\n return sections.join('\\n');\n }\n\n /**\n * Get component-specific regeneration guidance\n */\n static getComponentGuidance(component: RegeneratableComponent): string {\n switch (component) {\n case 'pinax':\n return (\n 'Extract and structure metadata including: institution, creator, title, ' +\n 'date range, subjects, type, and other relevant fields. Ensure accuracy ' +\n 'based on the source content.'\n );\n case 'description':\n return (\n 'Generate a clear, informative description that summarizes the entity content. ' +\n 'Focus on what the material contains, its historical significance, and context. ' +\n 'Write for a general audience unless otherwise specified.'\n );\n case 'cheimarros':\n return (\n 'Extract entities (people, places, organizations, events) and their relationships. ' +\n 'Build a knowledge graph that captures the key facts and connections in the content.'\n );\n default:\n return '';\n }\n }\n}\n","/**\n * EditSession - Stateful session managing an edit workflow\n */\n\nimport { EditClient } from './client';\nimport { DiffEngine } from './diff';\nimport { PromptBuilder } from './prompts';\nimport type {\n Entity,\n EditMode,\n EditSessionConfig,\n EditScope,\n Correction,\n ComponentDiff,\n RegeneratableComponent,\n PromptTarget,\n ChangeSummary,\n EditResult,\n EditStatus,\n PollOptions,\n CustomPrompts,\n} from './types';\nimport { ValidationError } from './errors';\n\nconst DEFAULT_SCOPE: EditScope = {\n components: [],\n cascade: false,\n};\n\nconst DEFAULT_POLL_OPTIONS: Required<Omit<PollOptions, 'onProgress'>> = {\n intervalMs: 2000,\n timeoutMs: 300000, // 5 minutes\n};\n\nexport class EditSession {\n readonly pi: string;\n readonly mode: EditMode;\n readonly aiReviewEnabled: boolean;\n\n private client: EditClient;\n private entity: Entity | null = null;\n private loadedComponents: Record<string, string> = {};\n\n // AI mode state\n private prompts: Record<string, string> = {};\n\n // Manual mode state\n private editedContent: Record<string, string> = {};\n private corrections: Correction[] = [];\n\n // Scope\n private scope: EditScope = { ...DEFAULT_SCOPE };\n\n // Execution state\n private submitting = false;\n private result: EditResult | null = null;\n private statusUrl: string | null = null;\n\n constructor(client: EditClient, pi: string, config?: EditSessionConfig) {\n this.client = client;\n this.pi = pi;\n this.mode = config?.mode ?? 'ai-prompt';\n this.aiReviewEnabled = config?.aiReviewEnabled ?? true;\n }\n\n // ===========================================================================\n // Loading\n // ===========================================================================\n\n /**\n * Load the entity and its key components\n */\n async load(): Promise<void> {\n this.entity = await this.client.getEntity(this.pi);\n\n // Load key components that are commonly edited\n const priorityComponents = ['description.md', 'pinax.json', 'cheimarros.json'];\n\n await Promise.all(\n priorityComponents.map(async (name) => {\n const cid = this.entity!.components[name];\n if (cid) {\n try {\n this.loadedComponents[name] = await this.client.getContent(cid);\n } catch {\n // Component may not exist, that's ok\n }\n }\n })\n );\n }\n\n /**\n * Load a specific component on demand\n */\n async loadComponent(name: string): Promise<string | undefined> {\n if (this.loadedComponents[name]) {\n return this.loadedComponents[name];\n }\n\n if (!this.entity) {\n throw new ValidationError('Session not loaded');\n }\n\n const cid = this.entity.components[name];\n if (!cid) {\n return undefined;\n }\n\n const content = await this.client.getContent(cid);\n this.loadedComponents[name] = content;\n return content;\n }\n\n /**\n * Get the loaded entity\n */\n getEntity(): Entity {\n if (!this.entity) {\n throw new ValidationError('Session not loaded. Call load() first.');\n }\n return this.entity;\n }\n\n /**\n * Get loaded component content\n */\n getComponents(): Record<string, string> {\n return { ...this.loadedComponents };\n }\n\n // ===========================================================================\n // AI Prompt Mode\n // ===========================================================================\n\n /**\n * Set a prompt for AI regeneration\n */\n setPrompt(target: PromptTarget, prompt: string): void {\n if (this.mode === 'manual-only') {\n throw new ValidationError('Cannot set prompts in manual-only mode');\n }\n this.prompts[target] = prompt;\n }\n\n /**\n * Get all prompts\n */\n getPrompts(): Record<string, string> {\n return { ...this.prompts };\n }\n\n /**\n * Clear a prompt\n */\n clearPrompt(target: PromptTarget): void {\n delete this.prompts[target];\n }\n\n // ===========================================================================\n // Manual Edit Mode\n // ===========================================================================\n\n /**\n * Set edited content for a component\n */\n setContent(componentName: string, content: string): void {\n if (this.mode === 'ai-prompt') {\n throw new ValidationError('Cannot set content in ai-prompt mode');\n }\n this.editedContent[componentName] = content;\n }\n\n /**\n * Get all edited content\n */\n getEditedContent(): Record<string, string> {\n return { ...this.editedContent };\n }\n\n /**\n * Clear edited content for a component\n */\n clearContent(componentName: string): void {\n delete this.editedContent[componentName];\n }\n\n /**\n * Add a correction (for OCR fixes, etc.)\n */\n addCorrection(original: string, corrected: string, sourceFile?: string): void {\n this.corrections.push({ original, corrected, sourceFile });\n }\n\n /**\n * Get all corrections\n */\n getCorrections(): Correction[] {\n return [...this.corrections];\n }\n\n /**\n * Clear corrections\n */\n clearCorrections(): void {\n this.corrections = [];\n }\n\n // ===========================================================================\n // Scope Configuration\n // ===========================================================================\n\n /**\n * Set the edit scope\n */\n setScope(scope: Partial<EditScope>): void {\n this.scope = { ...this.scope, ...scope };\n }\n\n /**\n * Get the current scope\n */\n getScope(): EditScope {\n return { ...this.scope };\n }\n\n // ===========================================================================\n // Preview & Summary\n // ===========================================================================\n\n /**\n * Get diffs for manual changes\n */\n getDiff(): ComponentDiff[] {\n const diffs: ComponentDiff[] = [];\n\n for (const [name, edited] of Object.entries(this.editedContent)) {\n const original = this.loadedComponents[name] || '';\n if (DiffEngine.hasSignificantChanges(original, edited)) {\n diffs.push(DiffEngine.createComponentDiff(name, original, edited));\n }\n }\n\n return diffs;\n }\n\n /**\n * Preview what prompts will be sent to AI\n */\n previewPrompt(): Record<RegeneratableComponent, string> {\n const result: Record<string, string> = {};\n\n if (!this.entity) return result as Record<RegeneratableComponent, string>;\n\n const entityContext = {\n pi: this.entity.pi,\n ver: this.entity.ver,\n parentPi: this.entity.parent_pi,\n childrenCount: this.entity.children_pi.length,\n currentContent: this.loadedComponents,\n };\n\n for (const component of this.scope.components) {\n let prompt: string;\n\n if (this.mode === 'ai-prompt') {\n // AI prompt mode: use user's prompt\n const componentPrompt = this.prompts[component];\n const generalPrompt = this.prompts['general'];\n const combined = PromptBuilder.buildCombinedPrompt(generalPrompt, componentPrompt, component);\n prompt = PromptBuilder.buildAIPrompt(\n combined,\n component,\n entityContext,\n this.loadedComponents[`${component}.json`] || this.loadedComponents[`${component}.md`]\n );\n } else {\n // Manual mode: build from diffs and corrections\n const diffs = this.getDiff();\n const userInstructions = this.prompts['general'] || this.prompts[component];\n prompt = PromptBuilder.buildEditReviewPrompt(diffs, this.corrections, component, userInstructions);\n }\n\n // Add cascade context if applicable\n if (this.scope.cascade) {\n prompt = PromptBuilder.buildCascadePrompt(prompt, {\n path: [this.entity.pi, this.entity.parent_pi || 'root'].filter(Boolean) as string[],\n depth: 0,\n stopAtPi: this.scope.stopAtPi,\n });\n }\n\n result[component] = prompt;\n }\n\n return result as Record<RegeneratableComponent, string>;\n }\n\n /**\n * Get a summary of pending changes\n */\n getChangeSummary(): ChangeSummary {\n const diffs = this.getDiff();\n const hasManualEdits = diffs.some((d) => d.hasChanges);\n\n return {\n mode: this.mode,\n hasManualEdits,\n editedComponents: Object.keys(this.editedContent),\n corrections: [...this.corrections],\n prompts: { ...this.prompts },\n scope: { ...this.scope },\n willRegenerate: [...this.scope.components],\n willCascade: this.scope.cascade,\n willSave: hasManualEdits,\n willReprocess: this.scope.components.length > 0,\n };\n }\n\n // ===========================================================================\n // Execution\n // ===========================================================================\n\n /**\n * Submit changes (saves first if manual edits, then reprocesses)\n */\n async submit(note: string): Promise<EditResult> {\n if (this.submitting) {\n throw new ValidationError('Submit already in progress');\n }\n if (!this.entity) {\n throw new ValidationError('Session not loaded. Call load() first.');\n }\n\n this.submitting = true;\n this.result = {};\n\n try {\n // Phase 1: Save manual edits if any\n const diffs = this.getDiff();\n const hasManualEdits = diffs.some((d) => d.hasChanges);\n\n if (hasManualEdits) {\n // Upload edited components and collect CIDs\n const componentUpdates: Record<string, string> = {};\n\n for (const [name, content] of Object.entries(this.editedContent)) {\n const original = this.loadedComponents[name] || '';\n if (DiffEngine.hasSignificantChanges(original, content)) {\n const cid = await this.client.uploadContent(content, name);\n componentUpdates[name] = cid;\n }\n }\n\n // Update entity\n const version = await this.client.updateEntity(this.pi, {\n expect_tip: this.entity.manifest_cid,\n components: componentUpdates,\n note,\n });\n\n this.result.saved = {\n pi: version.pi,\n newVersion: version.ver,\n newTip: version.tip,\n };\n\n // Update our entity reference\n this.entity.manifest_cid = version.tip;\n this.entity.ver = version.ver;\n }\n\n // Phase 2: Trigger reprocessing if components selected\n if (this.scope.components.length > 0) {\n const customPrompts = this.buildCustomPrompts();\n\n const reprocessResult = await this.client.reprocess({\n pi: this.pi,\n phases: this.scope.components,\n cascade: this.scope.cascade,\n options: {\n stop_at_pi: this.scope.stopAtPi,\n custom_prompts: customPrompts,\n custom_note: note,\n },\n });\n\n this.result.reprocess = reprocessResult;\n this.statusUrl = reprocessResult.status_url;\n }\n\n return this.result;\n } finally {\n this.submitting = false;\n }\n }\n\n /**\n * Wait for reprocessing to complete\n */\n async waitForCompletion(options?: PollOptions): Promise<EditStatus> {\n const opts = { ...DEFAULT_POLL_OPTIONS, ...options };\n\n if (!this.statusUrl) {\n return {\n phase: 'complete',\n saveComplete: true,\n };\n }\n\n const startTime = Date.now();\n let isFirstPoll = true;\n\n while (true) {\n // Pass isFirstPoll flag - the client will use longer retry delays on first poll\n // since the orchestrator often needs time to initialize after reprocess is triggered\n const status = await this.client.getReprocessStatus(this.statusUrl, isFirstPoll);\n isFirstPoll = false;\n\n const editStatus: EditStatus = {\n phase: status.status === 'DONE' ? 'complete' : status.status === 'ERROR' ? 'error' : 'reprocessing',\n saveComplete: true,\n reprocessStatus: status,\n error: status.error,\n };\n\n if (opts.onProgress) {\n opts.onProgress(editStatus);\n }\n\n if (status.status === 'DONE' || status.status === 'ERROR') {\n return editStatus;\n }\n\n if (Date.now() - startTime > opts.timeoutMs) {\n return {\n phase: 'error',\n saveComplete: true,\n reprocessStatus: status,\n error: 'Timeout waiting for reprocessing to complete',\n };\n }\n\n await new Promise((resolve) => setTimeout(resolve, opts.intervalMs));\n }\n }\n\n /**\n * Get current status without waiting\n */\n async getStatus(): Promise<EditStatus> {\n if (!this.statusUrl) {\n return {\n phase: this.result?.saved ? 'complete' : 'idle',\n saveComplete: !!this.result?.saved,\n };\n }\n\n const status = await this.client.getReprocessStatus(this.statusUrl);\n\n return {\n phase: status.status === 'DONE' ? 'complete' : status.status === 'ERROR' ? 'error' : 'reprocessing',\n saveComplete: true,\n reprocessStatus: status,\n error: status.error,\n };\n }\n\n // ===========================================================================\n // Private Helpers\n // ===========================================================================\n\n private buildCustomPrompts(): CustomPrompts {\n const custom: CustomPrompts = {};\n\n // In AI prompt mode, prompts go directly to reprocess API\n if (this.mode === 'ai-prompt') {\n if (this.prompts['general']) custom.general = this.prompts['general'];\n if (this.prompts['pinax']) custom.pinax = this.prompts['pinax'];\n if (this.prompts['description']) custom.description = this.prompts['description'];\n if (this.prompts['cheimarros']) custom.cheimarros = this.prompts['cheimarros'];\n } else {\n // Manual mode: build prompts from diffs, corrections, and user instructions\n const diffs = this.getDiff();\n const diffContext = DiffEngine.formatComponentDiffsForPrompt(diffs);\n const correctionContext = PromptBuilder.buildCorrectionPrompt(this.corrections);\n\n // Combine all context: diffs + corrections + user instructions\n const basePrompt = [diffContext, correctionContext, this.prompts['general']]\n .filter(Boolean)\n .join('\\n\\n');\n\n if (basePrompt) {\n custom.general = basePrompt;\n }\n\n // Component-specific prompts\n if (this.prompts['pinax']) custom.pinax = this.prompts['pinax'];\n if (this.prompts['description']) custom.description = this.prompts['description'];\n if (this.prompts['cheimarros']) custom.cheimarros = this.prompts['cheimarros'];\n }\n\n return custom;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
import { f as CreateCollectionPayload, b as Collection, o as PiPermissions, C as CollectionsClient } from './client-dAk3E64p.cjs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Processing configuration types for per-directory control
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Configuration for processing stages applied to files
|
|
8
|
-
*/
|
|
9
|
-
interface ProcessingConfig {
|
|
10
|
-
/** Enable OCR on eligible files */
|
|
11
|
-
ocr: boolean;
|
|
12
|
-
/** Enable description/summary generation */
|
|
13
|
-
describe: boolean;
|
|
14
|
-
/** Enable pinax metadata generation */
|
|
15
|
-
pinax: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* SDK Configuration Types
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Custom prompts for AI services in the ingest pipeline
|
|
24
|
-
* All fields are optional. Prompts are appended to base system prompts.
|
|
25
|
-
*/
|
|
26
|
-
interface CustomPrompts {
|
|
27
|
-
/**
|
|
28
|
-
* Applied to all AI service calls across all phases
|
|
29
|
-
* @example "All content is from 18th century manuscripts. Use period-appropriate terminology."
|
|
30
|
-
*/
|
|
31
|
-
general?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Phase-specific: file reorganization
|
|
34
|
-
* @example "Group documents by subject matter (astronomy, biology, chemistry, physics)."
|
|
35
|
-
*/
|
|
36
|
-
reorganization?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Phase-specific: PINAX metadata extraction
|
|
39
|
-
* @example "Focus on extracting dates, locations, and institutional affiliations. Use Library of Congress Subject Headings."
|
|
40
|
-
*/
|
|
41
|
-
pinax?: string;
|
|
42
|
-
/**
|
|
43
|
-
* Phase-specific: description generation
|
|
44
|
-
* @example "Write descriptions in scholarly, academic tone with focus on historical context."
|
|
45
|
-
*/
|
|
46
|
-
description?: string;
|
|
47
|
-
/**
|
|
48
|
-
* Phase-specific: knowledge graph extraction
|
|
49
|
-
* @example "Focus on extracting people, institutions, and their relationships."
|
|
50
|
-
*/
|
|
51
|
-
cheimarros?: string;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Configuration for the ArkeUploader SDK
|
|
55
|
-
*/
|
|
56
|
-
interface UploaderConfig {
|
|
57
|
-
/**
|
|
58
|
-
* Gateway base URL (e.g., https://api.arke.institute)
|
|
59
|
-
* All requests route through /ingest/* endpoints
|
|
60
|
-
* @example 'https://api.arke.institute'
|
|
61
|
-
*/
|
|
62
|
-
gatewayUrl: string;
|
|
63
|
-
/**
|
|
64
|
-
* Bearer token for authentication (required for all upload operations)
|
|
65
|
-
*/
|
|
66
|
-
authToken: string;
|
|
67
|
-
/**
|
|
68
|
-
* Name of person/service uploading files
|
|
69
|
-
*/
|
|
70
|
-
uploader: string;
|
|
71
|
-
/**
|
|
72
|
-
* Root path in the archive hierarchy
|
|
73
|
-
* @default '/'
|
|
74
|
-
*/
|
|
75
|
-
rootPath?: string;
|
|
76
|
-
/**
|
|
77
|
-
* Parent persistent identifier (for hierarchical archives)
|
|
78
|
-
*/
|
|
79
|
-
parentPi?: string;
|
|
80
|
-
/**
|
|
81
|
-
* Custom metadata to attach to batch
|
|
82
|
-
*/
|
|
83
|
-
metadata?: Record<string, unknown>;
|
|
84
|
-
/**
|
|
85
|
-
* Custom prompts for AI services in the ingest pipeline
|
|
86
|
-
*/
|
|
87
|
-
customPrompts?: CustomPrompts;
|
|
88
|
-
/**
|
|
89
|
-
* Processing options (OCR, IIIF, etc.)
|
|
90
|
-
*/
|
|
91
|
-
processing?: ProcessingConfig;
|
|
92
|
-
/**
|
|
93
|
-
* Number of files to upload in parallel
|
|
94
|
-
* @default 5
|
|
95
|
-
*/
|
|
96
|
-
parallelUploads?: number;
|
|
97
|
-
/**
|
|
98
|
-
* Number of parts to upload in parallel for multipart uploads
|
|
99
|
-
* @default 3
|
|
100
|
-
*/
|
|
101
|
-
parallelParts?: number;
|
|
102
|
-
/**
|
|
103
|
-
* Maximum number of retry attempts for failed requests
|
|
104
|
-
* @default 3
|
|
105
|
-
*/
|
|
106
|
-
maxRetries?: number;
|
|
107
|
-
/**
|
|
108
|
-
* Initial delay between retries in milliseconds
|
|
109
|
-
* @default 1000
|
|
110
|
-
*/
|
|
111
|
-
retryInitialDelay?: number;
|
|
112
|
-
/**
|
|
113
|
-
* Maximum delay between retries in milliseconds
|
|
114
|
-
* @default 30000
|
|
115
|
-
*/
|
|
116
|
-
retryMaxDelay?: number;
|
|
117
|
-
/**
|
|
118
|
-
* Add random jitter to retry delays to prevent thundering herd
|
|
119
|
-
* @default true
|
|
120
|
-
*/
|
|
121
|
-
retryJitter?: boolean;
|
|
122
|
-
/**
|
|
123
|
-
* Timeout for API requests in milliseconds
|
|
124
|
-
* @default 30000
|
|
125
|
-
*/
|
|
126
|
-
timeout?: number;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Options for batch upload operation
|
|
130
|
-
*/
|
|
131
|
-
interface UploadOptions {
|
|
132
|
-
/**
|
|
133
|
-
* Progress callback for upload tracking
|
|
134
|
-
*/
|
|
135
|
-
onProgress?: (progress: UploadProgress) => void;
|
|
136
|
-
/**
|
|
137
|
-
* Dry run mode - validate without uploading
|
|
138
|
-
* @default false
|
|
139
|
-
*/
|
|
140
|
-
dryRun?: boolean;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Progress information during upload
|
|
144
|
-
*/
|
|
145
|
-
interface UploadProgress {
|
|
146
|
-
/**
|
|
147
|
-
* Current phase of upload
|
|
148
|
-
*/
|
|
149
|
-
phase: 'scanning' | 'uploading' | 'finalizing' | 'discovery' | 'complete';
|
|
150
|
-
/**
|
|
151
|
-
* Total number of files to upload
|
|
152
|
-
*/
|
|
153
|
-
filesTotal: number;
|
|
154
|
-
/**
|
|
155
|
-
* Number of files uploaded so far
|
|
156
|
-
*/
|
|
157
|
-
filesUploaded: number;
|
|
158
|
-
/**
|
|
159
|
-
* Total bytes to upload
|
|
160
|
-
*/
|
|
161
|
-
bytesTotal: number;
|
|
162
|
-
/**
|
|
163
|
-
* Bytes uploaded so far
|
|
164
|
-
*/
|
|
165
|
-
bytesUploaded: number;
|
|
166
|
-
/**
|
|
167
|
-
* Current file being processed
|
|
168
|
-
*/
|
|
169
|
-
currentFile?: string;
|
|
170
|
-
/**
|
|
171
|
-
* Percentage complete (0-100)
|
|
172
|
-
*/
|
|
173
|
-
percentComplete: number;
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Result of batch upload
|
|
177
|
-
*/
|
|
178
|
-
interface BatchResult {
|
|
179
|
-
/**
|
|
180
|
-
* Batch ID assigned by worker
|
|
181
|
-
*/
|
|
182
|
-
batchId: string;
|
|
183
|
-
/**
|
|
184
|
-
* Root PI of the uploaded content (entity identifier)
|
|
185
|
-
* This is the canonical identifier for the uploaded collection.
|
|
186
|
-
*/
|
|
187
|
-
rootPi: string;
|
|
188
|
-
/**
|
|
189
|
-
* Number of files uploaded
|
|
190
|
-
*/
|
|
191
|
-
filesUploaded: number;
|
|
192
|
-
/**
|
|
193
|
-
* Total bytes uploaded
|
|
194
|
-
*/
|
|
195
|
-
bytesUploaded: number;
|
|
196
|
-
/**
|
|
197
|
-
* Upload duration in milliseconds
|
|
198
|
-
*/
|
|
199
|
-
durationMs: number;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Upload Client with Collections Integration
|
|
204
|
-
* Provides high-level upload operations with permission checks
|
|
205
|
-
*/
|
|
206
|
-
|
|
207
|
-
interface UploadClientConfig {
|
|
208
|
-
/**
|
|
209
|
-
* Gateway base URL (e.g., https://api.arke.institute)
|
|
210
|
-
*/
|
|
211
|
-
gatewayUrl: string;
|
|
212
|
-
/**
|
|
213
|
-
* Bearer token for authentication
|
|
214
|
-
*/
|
|
215
|
-
authToken: string;
|
|
216
|
-
/**
|
|
217
|
-
* Name of person/service uploading files (defaults to user ID from JWT)
|
|
218
|
-
*/
|
|
219
|
-
uploader?: string;
|
|
220
|
-
/**
|
|
221
|
-
* Custom fetch implementation (optional, for testing)
|
|
222
|
-
*/
|
|
223
|
-
fetchImpl?: typeof fetch;
|
|
224
|
-
}
|
|
225
|
-
interface CreateCollectionUploadOptions {
|
|
226
|
-
/**
|
|
227
|
-
* Files to upload - directory path (Node.js) or File[]/FileList (browser)
|
|
228
|
-
*/
|
|
229
|
-
files: string | File[] | FileList;
|
|
230
|
-
/**
|
|
231
|
-
* Collection metadata
|
|
232
|
-
*/
|
|
233
|
-
collectionMetadata: CreateCollectionPayload;
|
|
234
|
-
/**
|
|
235
|
-
* Custom prompts for AI processing
|
|
236
|
-
*/
|
|
237
|
-
customPrompts?: CustomPrompts;
|
|
238
|
-
/**
|
|
239
|
-
* Processing options (OCR, IIIF, etc.)
|
|
240
|
-
*/
|
|
241
|
-
processing?: ProcessingConfig;
|
|
242
|
-
/**
|
|
243
|
-
* Progress callback
|
|
244
|
-
*/
|
|
245
|
-
onProgress?: (progress: UploadProgress) => void;
|
|
246
|
-
/**
|
|
247
|
-
* Dry run mode
|
|
248
|
-
*/
|
|
249
|
-
dryRun?: boolean;
|
|
250
|
-
}
|
|
251
|
-
interface AddToCollectionOptions {
|
|
252
|
-
/**
|
|
253
|
-
* Files to upload - directory path (Node.js) or File[]/FileList (browser)
|
|
254
|
-
*/
|
|
255
|
-
files: string | File[] | FileList;
|
|
256
|
-
/**
|
|
257
|
-
* Parent PI to add files under (must be within a collection you can edit)
|
|
258
|
-
*/
|
|
259
|
-
parentPi: string;
|
|
260
|
-
/**
|
|
261
|
-
* Custom prompts for AI processing
|
|
262
|
-
*/
|
|
263
|
-
customPrompts?: CustomPrompts;
|
|
264
|
-
/**
|
|
265
|
-
* Processing options (OCR, IIIF, etc.)
|
|
266
|
-
*/
|
|
267
|
-
processing?: ProcessingConfig;
|
|
268
|
-
/**
|
|
269
|
-
* Progress callback
|
|
270
|
-
*/
|
|
271
|
-
onProgress?: (progress: UploadProgress) => void;
|
|
272
|
-
/**
|
|
273
|
-
* Dry run mode
|
|
274
|
-
*/
|
|
275
|
-
dryRun?: boolean;
|
|
276
|
-
}
|
|
277
|
-
interface CreateCollectionUploadResult extends BatchResult {
|
|
278
|
-
/**
|
|
279
|
-
* The created collection
|
|
280
|
-
*/
|
|
281
|
-
collection: Collection & {
|
|
282
|
-
rootPi: string;
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* High-level upload client with collections integration
|
|
287
|
-
*
|
|
288
|
-
* @example
|
|
289
|
-
* ```typescript
|
|
290
|
-
* import { UploadClient } from '@arke-institute/sdk';
|
|
291
|
-
*
|
|
292
|
-
* const client = new UploadClient({
|
|
293
|
-
* gatewayUrl: 'https://api.arke.institute',
|
|
294
|
-
* authToken: 'your-jwt-token',
|
|
295
|
-
* uploader: 'my-app',
|
|
296
|
-
* });
|
|
297
|
-
*
|
|
298
|
-
* // Create a new collection from files
|
|
299
|
-
* const result = await client.createCollection({
|
|
300
|
-
* files: './photos',
|
|
301
|
-
* collectionMetadata: { title: 'My Archive', slug: 'my-archive' },
|
|
302
|
-
* });
|
|
303
|
-
*
|
|
304
|
-
* // Add files to an existing collection
|
|
305
|
-
* await client.addToCollection({
|
|
306
|
-
* files: './more-photos',
|
|
307
|
-
* parentPi: result.collection.rootPi,
|
|
308
|
-
* });
|
|
309
|
-
* ```
|
|
310
|
-
*/
|
|
311
|
-
declare class UploadClient {
|
|
312
|
-
private config;
|
|
313
|
-
private collectionsClient;
|
|
314
|
-
constructor(config: UploadClientConfig);
|
|
315
|
-
/**
|
|
316
|
-
* Update the auth token (e.g., after token refresh)
|
|
317
|
-
*/
|
|
318
|
-
setAuthToken(token: string): void;
|
|
319
|
-
/**
|
|
320
|
-
* Create a new collection and upload files to it
|
|
321
|
-
*
|
|
322
|
-
* Anyone authenticated can create a new collection.
|
|
323
|
-
* The root PI of the uploaded files becomes the collection's root.
|
|
324
|
-
*/
|
|
325
|
-
createCollection(options: CreateCollectionUploadOptions): Promise<CreateCollectionUploadResult>;
|
|
326
|
-
/**
|
|
327
|
-
* Add files to an existing collection
|
|
328
|
-
*
|
|
329
|
-
* Requires owner or editor role on the collection containing the parent PI.
|
|
330
|
-
* Use this to add a folder or files to an existing collection hierarchy.
|
|
331
|
-
*
|
|
332
|
-
* Note: Permission checks are enforced server-side by the ingest worker.
|
|
333
|
-
* The server will return 403 if the user lacks edit access to the parent PI.
|
|
334
|
-
*/
|
|
335
|
-
addToCollection(options: AddToCollectionOptions): Promise<BatchResult>;
|
|
336
|
-
/**
|
|
337
|
-
* Check if you can edit a specific PI (i.e., add files to its collection)
|
|
338
|
-
*/
|
|
339
|
-
canEdit(pi: string): Promise<PiPermissions>;
|
|
340
|
-
/**
|
|
341
|
-
* Get access to the underlying collections client for other operations
|
|
342
|
-
*/
|
|
343
|
-
get collections(): CollectionsClient;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* File metadata and upload tracking types
|
|
348
|
-
*/
|
|
349
|
-
|
|
350
|
-
interface FileInfo {
|
|
351
|
-
/** Absolute path on local filesystem */
|
|
352
|
-
localPath: string;
|
|
353
|
-
/** Logical path within the batch (e.g., /series_1/box_7/page_001.tiff) */
|
|
354
|
-
logicalPath: string;
|
|
355
|
-
/** File name only */
|
|
356
|
-
fileName: string;
|
|
357
|
-
/** File size in bytes */
|
|
358
|
-
size: number;
|
|
359
|
-
/** MIME type */
|
|
360
|
-
contentType: string;
|
|
361
|
-
/** IPFS CID v1 (base32) - optional, may be undefined if computation failed */
|
|
362
|
-
cid?: string;
|
|
363
|
-
/** Processing configuration for this file */
|
|
364
|
-
processingConfig: ProcessingConfig;
|
|
365
|
-
}
|
|
366
|
-
interface UploadTask extends FileInfo {
|
|
367
|
-
/** Current status of the upload */
|
|
368
|
-
status: 'pending' | 'uploading' | 'completed' | 'failed';
|
|
369
|
-
/** R2 key assigned by worker */
|
|
370
|
-
r2Key?: string;
|
|
371
|
-
/** Upload type determined by worker */
|
|
372
|
-
uploadType?: 'simple' | 'multipart';
|
|
373
|
-
/** Multipart upload ID (if applicable) */
|
|
374
|
-
uploadId?: string;
|
|
375
|
-
/** Completed parts for multipart uploads */
|
|
376
|
-
completedParts?: Array<{
|
|
377
|
-
part_number: number;
|
|
378
|
-
etag: string;
|
|
379
|
-
}>;
|
|
380
|
-
/** Error message if failed */
|
|
381
|
-
error?: string;
|
|
382
|
-
/** Bytes uploaded so far */
|
|
383
|
-
bytesUploaded?: number;
|
|
384
|
-
/** Timestamp when upload started */
|
|
385
|
-
startedAt?: Date;
|
|
386
|
-
/** Timestamp when upload completed */
|
|
387
|
-
completedAt?: Date;
|
|
388
|
-
}
|
|
389
|
-
interface ScanResult {
|
|
390
|
-
files: FileInfo[];
|
|
391
|
-
totalSize: number;
|
|
392
|
-
totalFiles: number;
|
|
393
|
-
largestFile: number;
|
|
394
|
-
smallestFile: number;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Common platform types and utilities
|
|
399
|
-
*/
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Platform-specific file source
|
|
403
|
-
* Can be a path string (Node.js) or File object (Browser)
|
|
404
|
-
*/
|
|
405
|
-
type FileSource = string | File;
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* Main ArkeUploader SDK class
|
|
409
|
-
*/
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Upload client for Arke Institute's ingest service
|
|
413
|
-
* Works in Node.js, browsers, and other JavaScript runtimes
|
|
414
|
-
*/
|
|
415
|
-
declare class ArkeUploader {
|
|
416
|
-
private config;
|
|
417
|
-
private workerClient;
|
|
418
|
-
private scanner;
|
|
419
|
-
private platform;
|
|
420
|
-
constructor(config: UploaderConfig);
|
|
421
|
-
/**
|
|
422
|
-
* Get platform-specific scanner
|
|
423
|
-
*/
|
|
424
|
-
private getScanner;
|
|
425
|
-
/**
|
|
426
|
-
* Upload a batch of files
|
|
427
|
-
* @param source - Directory path (Node.js) or File[]/FileList (browser)
|
|
428
|
-
* @param options - Upload options
|
|
429
|
-
*/
|
|
430
|
-
uploadBatch(source: FileSource | FileSource[], options?: UploadOptions): Promise<BatchResult>;
|
|
431
|
-
/**
|
|
432
|
-
* Poll for root_pi during async discovery
|
|
433
|
-
*/
|
|
434
|
-
private pollForRootPi;
|
|
435
|
-
/**
|
|
436
|
-
* Upload files with controlled concurrency
|
|
437
|
-
*/
|
|
438
|
-
private uploadFilesWithConcurrency;
|
|
439
|
-
/**
|
|
440
|
-
* Upload a single file
|
|
441
|
-
*/
|
|
442
|
-
private uploadSingleFile;
|
|
443
|
-
/**
|
|
444
|
-
* Get file data based on platform
|
|
445
|
-
*/
|
|
446
|
-
private getFileData;
|
|
447
|
-
/**
|
|
448
|
-
* Report progress to callback
|
|
449
|
-
*/
|
|
450
|
-
private reportProgress;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
* Custom error classes for better error handling
|
|
455
|
-
*/
|
|
456
|
-
declare class WorkerAPIError extends Error {
|
|
457
|
-
statusCode?: number | undefined;
|
|
458
|
-
details?: any | undefined;
|
|
459
|
-
constructor(message: string, statusCode?: number | undefined, details?: any | undefined);
|
|
460
|
-
}
|
|
461
|
-
declare class UploadError extends Error {
|
|
462
|
-
fileName?: string | undefined;
|
|
463
|
-
statusCode?: number | undefined;
|
|
464
|
-
cause?: Error | undefined;
|
|
465
|
-
constructor(message: string, fileName?: string | undefined, statusCode?: number | undefined, cause?: Error | undefined);
|
|
466
|
-
}
|
|
467
|
-
declare class ValidationError extends Error {
|
|
468
|
-
field?: string | undefined;
|
|
469
|
-
constructor(message: string, field?: string | undefined);
|
|
470
|
-
}
|
|
471
|
-
declare class NetworkError extends Error {
|
|
472
|
-
cause?: Error | undefined;
|
|
473
|
-
constructor(message: string, cause?: Error | undefined);
|
|
474
|
-
}
|
|
475
|
-
declare class ScanError extends Error {
|
|
476
|
-
path?: string | undefined;
|
|
477
|
-
constructor(message: string, path?: string | undefined);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
export { type AddToCollectionOptions as A, type BatchResult as B, type CreateCollectionUploadOptions as C, type FileInfo as F, NetworkError as N, type ProcessingConfig as P, ScanError as S, UploadClient as U, ValidationError as V, WorkerAPIError as W, type UploadClientConfig as a, type CreateCollectionUploadResult as b, ArkeUploader as c, type UploaderConfig as d, type UploadOptions as e, type UploadProgress as f, type CustomPrompts as g, UploadError as h, type UploadTask as i, type ScanResult as j };
|