@elqnt/kg 3.0.1 → 3.0.2

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.
Files changed (55) hide show
  1. package/dist/api/index.d.mts +92 -3
  2. package/dist/api/index.d.ts +92 -3
  3. package/dist/api/index.js +16 -2
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/index.mjs +15 -1
  6. package/dist/api/server.d.mts +1 -0
  7. package/dist/api/server.d.ts +1 -0
  8. package/dist/{chunk-HCDFJCQL.mjs → chunk-5D7RJC7D.mjs} +105 -5
  9. package/dist/chunk-5D7RJC7D.mjs.map +1 -0
  10. package/dist/chunk-B33SF6DB.js +2 -0
  11. package/dist/{chunk-W4XVBGE7.js.map → chunk-B33SF6DB.js.map} +1 -1
  12. package/dist/chunk-BP2I7KWY.js +1031 -0
  13. package/dist/chunk-BP2I7KWY.js.map +1 -0
  14. package/dist/{chunk-2TJCYLTP.js → chunk-CNWOI7LX.js} +104 -4
  15. package/dist/chunk-CNWOI7LX.js.map +1 -0
  16. package/dist/chunk-MAEB7UOW.mjs +257 -0
  17. package/dist/chunk-MAEB7UOW.mjs.map +1 -0
  18. package/dist/chunk-SUDQ45LY.mjs +2 -0
  19. package/dist/chunk-WYRCAPY4.js +257 -0
  20. package/dist/chunk-WYRCAPY4.js.map +1 -0
  21. package/dist/chunk-ZEPJC46Z.mjs +1031 -0
  22. package/dist/chunk-ZEPJC46Z.mjs.map +1 -0
  23. package/dist/hooks/index.d.mts +446 -79
  24. package/dist/hooks/index.d.ts +446 -79
  25. package/dist/hooks/index.js +8 -3
  26. package/dist/hooks/index.js.map +1 -1
  27. package/dist/hooks/index.mjs +9 -4
  28. package/dist/index.d.mts +4 -2
  29. package/dist/index.d.ts +4 -2
  30. package/dist/index.js +24 -5
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.mjs +31 -12
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/models/index.d.mts +213 -0
  35. package/dist/models/index.d.ts +213 -0
  36. package/dist/models/index.js +1 -1
  37. package/dist/models/index.mjs +1 -1
  38. package/dist/transport/index.d.mts +365 -0
  39. package/dist/transport/index.d.ts +365 -0
  40. package/dist/transport/index.js +10 -0
  41. package/dist/transport/index.js.map +1 -0
  42. package/dist/transport/index.mjs +10 -0
  43. package/dist/transport/index.mjs.map +1 -0
  44. package/dist/utils/index.js +1 -1
  45. package/dist/utils/index.mjs +1 -1
  46. package/package.json +3 -3
  47. package/dist/chunk-2TJCYLTP.js.map +0 -1
  48. package/dist/chunk-7RW5MHP5.js +0 -497
  49. package/dist/chunk-7RW5MHP5.js.map +0 -1
  50. package/dist/chunk-HCDFJCQL.mjs.map +0 -1
  51. package/dist/chunk-JZ7UXVRW.mjs +0 -497
  52. package/dist/chunk-JZ7UXVRW.mjs.map +0 -1
  53. package/dist/chunk-NJNBEGDB.mjs +0 -2
  54. package/dist/chunk-W4XVBGE7.js +0 -2
  55. /package/dist/{chunk-NJNBEGDB.mjs.map → chunk-SUDQ45LY.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../transport/quick-ingest.ts","../transport/full-ingest.ts"],"sourcesContent":["/**\n * Quick Ingestion SSE Transport\n *\n * Handles real-time progress updates for quick ingestion jobs.\n *\n * @example\n * ```typescript\n * import { createQuickIngestTransport } from \"@elqnt/kg/transport\";\n *\n * const transport = createQuickIngestTransport({ debug: true });\n * await transport.connect({ baseUrl, orgId });\n *\n * transport.on(\"item_start\", (event) => {\n * console.log(\"Started processing:\", event.itemId);\n * });\n *\n * transport.on(\"item_progress\", (event) => {\n * console.log(`Progress: ${event.progress}% - ${event.text}`);\n * });\n *\n * transport.on(\"item_complete\", (event) => {\n * console.log(`Completed: ${event.articles} articles, ${event.topics} topics`);\n * });\n *\n * transport.on(\"job_complete\", (event) => {\n * console.log(`Job done: ${event.totalArticles} articles, ${event.totalTopics} topics`);\n * });\n *\n * transport.subscribeToJob(\"qij_xyz789\");\n * ```\n */\n\nimport type { KGApiOptions } from \"../api\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Transport configuration\n */\nexport interface QuickIngestTransportConfig {\n /** Base URL for the API */\n baseUrl: string;\n /** Organization ID */\n orgId: string;\n /** Optional graph ID */\n graphId?: string;\n /** User ID for authentication */\n userId?: string;\n}\n\n/**\n * Transport options\n */\nexport interface QuickIngestTransportOptions {\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Event when an item starts processing\n */\nexport interface QuickIngestItemStartEvent {\n type: \"item_start\";\n itemId: string;\n timestamp: number;\n}\n\n/**\n * Event when an item has progress update\n */\nexport interface QuickIngestItemProgressEvent {\n type: \"item_progress\";\n itemId: string;\n progress: number;\n text: string;\n timestamp: number;\n}\n\n/**\n * Event when an item completes successfully\n */\nexport interface QuickIngestItemCompleteEvent {\n type: \"item_complete\";\n itemId: string;\n articles: number;\n topics: number;\n timestamp: number;\n}\n\n/**\n * Event when an item encounters an error\n */\nexport interface QuickIngestItemErrorEvent {\n type: \"item_error\";\n itemId: string;\n error: string;\n timestamp: number;\n}\n\n/**\n * Event when the entire job completes\n */\nexport interface QuickIngestJobCompleteEvent {\n type: \"job_complete\";\n totalArticles: number;\n totalTopics: number;\n timestamp: number;\n}\n\n/**\n * Union of all quick ingest events\n */\nexport type QuickIngestEvent =\n | QuickIngestItemStartEvent\n | QuickIngestItemProgressEvent\n | QuickIngestItemCompleteEvent\n | QuickIngestItemErrorEvent\n | QuickIngestJobCompleteEvent;\n\n/**\n * Event handler function type\n */\nexport type QuickIngestEventHandler<T = QuickIngestEvent> = (event: T) => void;\n\n/**\n * Unsubscribe function\n */\nexport type Unsubscribe = () => void;\n\n/**\n * Quick Ingest Transport interface\n */\nexport interface QuickIngestTransport {\n /**\n * Connect to the transport\n */\n connect(options: KGApiOptions): Promise<void>;\n\n /**\n * Subscribe to a specific job's events\n */\n subscribeToJob(jobId: string): void;\n\n /**\n * Subscribe to specific event type\n */\n on<T extends QuickIngestEvent[\"type\"]>(\n eventType: T,\n handler: QuickIngestEventHandler<Extract<QuickIngestEvent, { type: T }>>\n ): Unsubscribe;\n\n /**\n * Disconnect from the transport\n */\n disconnect(): void;\n\n /**\n * Get current connection state\n */\n getState(): \"disconnected\" | \"connecting\" | \"connected\";\n}\n\n// =============================================================================\n// IMPLEMENTATION\n// =============================================================================\n\n/**\n * Create a Quick Ingest SSE transport\n */\nexport function createQuickIngestTransport(\n options: QuickIngestTransportOptions = {}\n): QuickIngestTransport {\n const { debug = false } = options;\n\n // Internal state\n let eventSource: EventSource | undefined;\n let config: QuickIngestTransportConfig | undefined;\n let state: \"disconnected\" | \"connecting\" | \"connected\" = \"disconnected\";\n let currentJobId: string | undefined;\n\n // Event handlers\n const typeHandlers = new Map<string, Set<QuickIngestEventHandler<QuickIngestEvent>>>();\n\n // Logger\n const log = debug\n ? (msg: string, ...args: unknown[]) => console.log(`[kg-quick-ingest] ${msg}`, ...args)\n : () => {};\n\n // Helper to emit events\n function emit(event: QuickIngestEvent): void {\n const handlers = typeHandlers.get(event.type);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n console.error(`[kg-quick-ingest] Error in ${event.type} handler:`, err);\n }\n });\n }\n }\n\n // Handle SSE message\n function handleMessage(event: MessageEvent): void {\n if (!event.data || event.data === \"\") return;\n\n try {\n const data = JSON.parse(event.data) as QuickIngestEvent;\n log(\"Received:\", data.type);\n emit(data);\n\n // Handle job completion\n if (data.type === \"job_complete\") {\n state = \"connected\";\n currentJobId = undefined;\n }\n } catch (err) {\n console.error(\"[kg-quick-ingest] Failed to parse SSE message:\", err);\n }\n }\n\n // Setup event listeners\n function setupEventListeners(es: EventSource): void {\n es.addEventListener(\"message\", handleMessage);\n\n const eventTypes = [\"item_start\", \"item_progress\", \"item_complete\", \"item_error\", \"job_complete\"];\n eventTypes.forEach((type) => {\n es.addEventListener(type, handleMessage);\n });\n }\n\n const transport: QuickIngestTransport = {\n async connect(opts: KGApiOptions): Promise<void> {\n config = {\n baseUrl: opts.baseUrl,\n orgId: opts.orgId,\n graphId: opts.graphId,\n userId: opts.userId,\n };\n state = \"connected\";\n log(\"Transport ready\");\n },\n\n subscribeToJob(jobId: string): void {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n // Close existing connection\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n currentJobId = jobId;\n state = \"connecting\";\n\n const params = new URLSearchParams({\n orgId: config.orgId,\n });\n if (config.graphId) {\n params.set(\"graphId\", config.graphId);\n }\n\n const streamUrl = `${config.baseUrl}/api/v1/kg/quick-ingest/${jobId}/progress?${params.toString()}`;\n log(\"Connecting to stream:\", streamUrl);\n\n const es = new EventSource(streamUrl);\n\n // Setup listeners\n setupEventListeners(es);\n\n es.onopen = () => {\n log(\"Stream connected\");\n state = \"connected\";\n };\n\n es.onerror = () => {\n if (es.readyState === EventSource.CLOSED) {\n log(\"Stream closed\");\n state = \"disconnected\";\n currentJobId = undefined;\n }\n };\n\n eventSource = es;\n },\n\n on<T extends QuickIngestEvent[\"type\"]>(\n eventType: T,\n handler: QuickIngestEventHandler<Extract<QuickIngestEvent, { type: T }>>\n ): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler as QuickIngestEventHandler<QuickIngestEvent>);\n\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler as QuickIngestEventHandler<QuickIngestEvent>);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n disconnect(): void {\n log(\"Disconnecting\");\n\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n state = \"disconnected\";\n currentJobId = undefined;\n },\n\n getState(): \"disconnected\" | \"connecting\" | \"connected\" {\n return state;\n },\n };\n\n return transport;\n}\n","/**\n * Full Ingestion SSE Transport\n *\n * Handles real-time progress updates and node streaming for full ingestion extraction.\n *\n * @example\n * ```typescript\n * import { createFullIngestTransport } from \"@elqnt/kg/transport\";\n *\n * const transport = createFullIngestTransport({ debug: true });\n * await transport.connect({ baseUrl, orgId });\n *\n * transport.on(\"progress\", (event) => {\n * console.log(`Extracting page ${event.currentPage} of ${event.totalPages}`);\n * });\n *\n * transport.on(\"node\", (event) => {\n * console.log(\"Extracted node:\", event.label, event.fields);\n * });\n *\n * transport.on(\"complete\", (event) => {\n * console.log(`Extraction done: ${event.totalNodes} nodes`);\n * });\n *\n * transport.subscribeToJob(\"fij_extract_789\");\n * ```\n */\n\nimport type { KGApiOptions } from \"../api\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Transport configuration\n */\nexport interface FullIngestTransportConfig {\n /** Base URL for the API */\n baseUrl: string;\n /** Organization ID */\n orgId: string;\n /** Optional graph ID */\n graphId?: string;\n /** User ID for authentication */\n userId?: string;\n}\n\n/**\n * Transport options\n */\nexport interface FullIngestTransportOptions {\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Event for extraction progress\n */\nexport interface FullIngestProgressEvent {\n type: \"progress\";\n currentPage: number;\n totalPages: number;\n timestamp: number;\n}\n\n/**\n * Event when a node is extracted\n */\nexport interface FullIngestNodeEvent {\n type: \"node\";\n id: string;\n label: string;\n fields: Record<string, unknown>;\n timestamp: number;\n}\n\n/**\n * Event when consolidation is starting\n */\nexport interface FullIngestConsolidatingEvent {\n type: \"consolidating\";\n message: string;\n rawCount?: number;\n timestamp: number;\n}\n\n/**\n * Event when consolidation progress updates\n */\nexport interface FullIngestConsolidateProgressEvent {\n type: \"consolidate_progress\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when consolidation completes\n */\nexport interface FullIngestConsolidatedEvent {\n type: \"consolidated\";\n totalNodes: number;\n mergedCount: number;\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when linking/relationship extraction starts\n */\nexport interface FullIngestLinkingEvent {\n type: \"linking\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when linking completes\n */\nexport interface FullIngestLinkedEvent {\n type: \"linked\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when an edge is extracted\n */\nexport interface FullIngestEdgeEvent {\n type: \"edge\";\n id: string;\n fromLabel: string;\n fromName: string;\n toLabel: string;\n toName: string;\n edgeLabel: string;\n confidence: number;\n timestamp: number;\n}\n\n/**\n * Event when extraction completes\n */\nexport interface FullIngestCompleteEvent {\n type: \"complete\";\n totalNodes: number;\n totalEdges?: number;\n message?: string;\n timestamp: number;\n}\n\n/**\n * Event when extraction encounters an error\n */\nexport interface FullIngestErrorEvent {\n type: \"error\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when ingestion to KG starts\n */\nexport interface FullIngestIngestingEvent {\n type: \"ingesting\";\n message: string;\n totalNodes: number;\n totalEdges: number;\n timestamp: number;\n}\n\n/**\n * Event for ingestion progress (node/edge being ingested)\n */\nexport interface FullIngestIngestProgressEvent {\n type: \"ingest_progress\";\n message: string;\n currentNode: number;\n totalNodes: number;\n currentEdge: number;\n totalEdges: number;\n timestamp: number;\n}\n\n/**\n * Event when ingestion to KG completes\n */\nexport interface FullIngestIngestCompleteEvent {\n type: \"ingest_complete\";\n message: string;\n nodesIngested: number;\n edgesIngested: number;\n timestamp: number;\n}\n\n/**\n * Union of all full ingest events\n */\nexport type FullIngestEvent =\n | FullIngestProgressEvent\n | FullIngestNodeEvent\n | FullIngestConsolidatingEvent\n | FullIngestConsolidateProgressEvent\n | FullIngestConsolidatedEvent\n | FullIngestLinkingEvent\n | FullIngestLinkedEvent\n | FullIngestEdgeEvent\n | FullIngestCompleteEvent\n | FullIngestErrorEvent\n | FullIngestIngestingEvent\n | FullIngestIngestProgressEvent\n | FullIngestIngestCompleteEvent;\n\n/**\n * Event handler function type\n */\nexport type FullIngestEventHandler<T = FullIngestEvent> = (event: T) => void;\n\n// Unsubscribe type is exported from quick-ingest.ts\nimport type { Unsubscribe } from \"./quick-ingest\";\n\n/**\n * Full Ingest Transport interface\n */\nexport interface FullIngestTransport {\n /**\n * Connect to the transport\n */\n connect(options: KGApiOptions): Promise<void>;\n\n /**\n * Subscribe to a specific job's events\n */\n subscribeToJob(jobId: string): void;\n\n /**\n * Subscribe to specific event type\n */\n on<T extends FullIngestEvent[\"type\"]>(\n eventType: T,\n handler: FullIngestEventHandler<Extract<FullIngestEvent, { type: T }>>\n ): Unsubscribe;\n\n /**\n * Disconnect from the transport\n */\n disconnect(): void;\n\n /**\n * Get current connection state\n */\n getState(): \"disconnected\" | \"connecting\" | \"connected\";\n}\n\n// =============================================================================\n// IMPLEMENTATION\n// =============================================================================\n\n/**\n * Create a Full Ingest SSE transport\n */\nexport function createFullIngestTransport(\n options: FullIngestTransportOptions = {}\n): FullIngestTransport {\n const { debug = false } = options;\n\n // Internal state\n let eventSource: EventSource | undefined;\n let config: FullIngestTransportConfig | undefined;\n let state: \"disconnected\" | \"connecting\" | \"connected\" = \"disconnected\";\n let currentJobId: string | undefined;\n\n // Event handlers\n const typeHandlers = new Map<string, Set<FullIngestEventHandler<FullIngestEvent>>>();\n\n // Logger\n const log = debug\n ? (msg: string, ...args: unknown[]) => console.log(`[kg-full-ingest] ${msg}`, ...args)\n : () => {};\n\n // Helper to emit events\n function emit(event: FullIngestEvent): void {\n const handlers = typeHandlers.get(event.type);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n console.error(`[kg-full-ingest] Error in ${event.type} handler:`, err);\n }\n });\n }\n }\n\n // Handle SSE message\n function handleMessage(event: MessageEvent): void {\n if (!event.data || event.data === \"\") return;\n\n try {\n const data = JSON.parse(event.data) as FullIngestEvent;\n log(\"Received:\", data.type);\n emit(data);\n\n // Handle completion or error\n if (data.type === \"complete\" || data.type === \"error\") {\n state = \"connected\";\n currentJobId = undefined;\n }\n } catch (err) {\n console.error(\"[kg-full-ingest] Failed to parse SSE message:\", err);\n }\n }\n\n // Setup event listeners\n function setupEventListeners(es: EventSource): void {\n es.addEventListener(\"message\", handleMessage);\n\n const eventTypes = [\n \"progress\",\n \"node\",\n \"consolidating\",\n \"consolidate_progress\",\n \"consolidated\",\n \"linking\",\n \"linked\",\n \"edge\",\n \"complete\",\n \"error\",\n \"ingesting\",\n \"ingest_progress\",\n \"ingest_complete\",\n ];\n eventTypes.forEach((type) => {\n es.addEventListener(type, handleMessage);\n });\n }\n\n const transport: FullIngestTransport = {\n async connect(opts: KGApiOptions): Promise<void> {\n config = {\n baseUrl: opts.baseUrl,\n orgId: opts.orgId,\n graphId: opts.graphId,\n userId: opts.userId,\n };\n state = \"connected\";\n log(\"Transport ready\");\n },\n\n subscribeToJob(jobId: string): void {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n // Close existing connection\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n currentJobId = jobId;\n state = \"connecting\";\n\n const params = new URLSearchParams({\n orgId: config.orgId,\n });\n if (config.graphId) {\n params.set(\"graphId\", config.graphId);\n }\n\n const streamUrl = `${config.baseUrl}/api/v1/kg/full-ingest/${jobId}/progress?${params.toString()}`;\n log(\"Connecting to stream:\", streamUrl);\n\n const es = new EventSource(streamUrl);\n\n es.onopen = () => {\n log(\"Stream connected\");\n state = \"connected\";\n setupEventListeners(es);\n };\n\n es.onerror = () => {\n if (es.readyState === EventSource.CLOSED) {\n log(\"Stream closed\");\n state = \"disconnected\";\n currentJobId = undefined;\n }\n };\n\n eventSource = es;\n },\n\n on<T extends FullIngestEvent[\"type\"]>(\n eventType: T,\n handler: FullIngestEventHandler<Extract<FullIngestEvent, { type: T }>>\n ): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler as FullIngestEventHandler<FullIngestEvent>);\n\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler as FullIngestEventHandler<FullIngestEvent>);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n disconnect(): void {\n log(\"Disconnecting\");\n\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n state = \"disconnected\";\n currentJobId = undefined;\n },\n\n getState(): \"disconnected\" | \"connecting\" | \"connected\" {\n return state;\n },\n };\n\n return transport;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ //# sourceMappingURL=chunk-SUDQ45LY.mjs.map
@@ -0,0 +1,257 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
+
3
+ // transport/quick-ingest.ts
4
+ function createQuickIngestTransport(options = {}) {
5
+ const { debug = false } = options;
6
+ let eventSource;
7
+ let config;
8
+ let state = "disconnected";
9
+ let currentJobId;
10
+ const typeHandlers = /* @__PURE__ */ new Map();
11
+ const log = debug ? (msg, ...args) => console.log(`[kg-quick-ingest] ${msg}`, ...args) : () => {
12
+ };
13
+ function emit(event) {
14
+ const handlers = typeHandlers.get(event.type);
15
+ if (handlers) {
16
+ handlers.forEach((handler) => {
17
+ try {
18
+ handler(event);
19
+ } catch (err) {
20
+ console.error(`[kg-quick-ingest] Error in ${event.type} handler:`, err);
21
+ }
22
+ });
23
+ }
24
+ }
25
+ function handleMessage(event) {
26
+ if (!event.data || event.data === "") return;
27
+ try {
28
+ const data = JSON.parse(event.data);
29
+ log("Received:", data.type);
30
+ emit(data);
31
+ if (data.type === "job_complete") {
32
+ state = "connected";
33
+ currentJobId = void 0;
34
+ }
35
+ } catch (err) {
36
+ console.error("[kg-quick-ingest] Failed to parse SSE message:", err);
37
+ }
38
+ }
39
+ function setupEventListeners(es) {
40
+ es.addEventListener("message", handleMessage);
41
+ const eventTypes = ["item_start", "item_progress", "item_complete", "item_error", "job_complete"];
42
+ eventTypes.forEach((type) => {
43
+ es.addEventListener(type, handleMessage);
44
+ });
45
+ }
46
+ const transport = {
47
+ async connect(opts) {
48
+ config = {
49
+ baseUrl: opts.baseUrl,
50
+ orgId: opts.orgId,
51
+ graphId: opts.graphId,
52
+ userId: opts.userId
53
+ };
54
+ state = "connected";
55
+ log("Transport ready");
56
+ },
57
+ subscribeToJob(jobId) {
58
+ if (!config) {
59
+ throw new Error("Transport not connected");
60
+ }
61
+ if (eventSource) {
62
+ eventSource.close();
63
+ eventSource = void 0;
64
+ }
65
+ currentJobId = jobId;
66
+ state = "connecting";
67
+ const params = new URLSearchParams({
68
+ orgId: config.orgId
69
+ });
70
+ if (config.graphId) {
71
+ params.set("graphId", config.graphId);
72
+ }
73
+ const streamUrl = `${config.baseUrl}/api/v1/kg/quick-ingest/${jobId}/progress?${params.toString()}`;
74
+ log("Connecting to stream:", streamUrl);
75
+ const es = new EventSource(streamUrl);
76
+ setupEventListeners(es);
77
+ es.onopen = () => {
78
+ log("Stream connected");
79
+ state = "connected";
80
+ };
81
+ es.onerror = () => {
82
+ if (es.readyState === EventSource.CLOSED) {
83
+ log("Stream closed");
84
+ state = "disconnected";
85
+ currentJobId = void 0;
86
+ }
87
+ };
88
+ eventSource = es;
89
+ },
90
+ on(eventType, handler) {
91
+ if (!typeHandlers.has(eventType)) {
92
+ typeHandlers.set(eventType, /* @__PURE__ */ new Set());
93
+ }
94
+ typeHandlers.get(eventType).add(handler);
95
+ return () => {
96
+ const handlers = typeHandlers.get(eventType);
97
+ if (handlers) {
98
+ handlers.delete(handler);
99
+ if (handlers.size === 0) {
100
+ typeHandlers.delete(eventType);
101
+ }
102
+ }
103
+ };
104
+ },
105
+ disconnect() {
106
+ log("Disconnecting");
107
+ if (eventSource) {
108
+ eventSource.close();
109
+ eventSource = void 0;
110
+ }
111
+ state = "disconnected";
112
+ currentJobId = void 0;
113
+ },
114
+ getState() {
115
+ return state;
116
+ }
117
+ };
118
+ return transport;
119
+ }
120
+
121
+ // transport/full-ingest.ts
122
+ function createFullIngestTransport(options = {}) {
123
+ const { debug = false } = options;
124
+ let eventSource;
125
+ let config;
126
+ let state = "disconnected";
127
+ let currentJobId;
128
+ const typeHandlers = /* @__PURE__ */ new Map();
129
+ const log = debug ? (msg, ...args) => console.log(`[kg-full-ingest] ${msg}`, ...args) : () => {
130
+ };
131
+ function emit(event) {
132
+ const handlers = typeHandlers.get(event.type);
133
+ if (handlers) {
134
+ handlers.forEach((handler) => {
135
+ try {
136
+ handler(event);
137
+ } catch (err) {
138
+ console.error(`[kg-full-ingest] Error in ${event.type} handler:`, err);
139
+ }
140
+ });
141
+ }
142
+ }
143
+ function handleMessage(event) {
144
+ if (!event.data || event.data === "") return;
145
+ try {
146
+ const data = JSON.parse(event.data);
147
+ log("Received:", data.type);
148
+ emit(data);
149
+ if (data.type === "complete" || data.type === "error") {
150
+ state = "connected";
151
+ currentJobId = void 0;
152
+ }
153
+ } catch (err) {
154
+ console.error("[kg-full-ingest] Failed to parse SSE message:", err);
155
+ }
156
+ }
157
+ function setupEventListeners(es) {
158
+ es.addEventListener("message", handleMessage);
159
+ const eventTypes = [
160
+ "progress",
161
+ "node",
162
+ "consolidating",
163
+ "consolidate_progress",
164
+ "consolidated",
165
+ "linking",
166
+ "linked",
167
+ "edge",
168
+ "complete",
169
+ "error",
170
+ "ingesting",
171
+ "ingest_progress",
172
+ "ingest_complete"
173
+ ];
174
+ eventTypes.forEach((type) => {
175
+ es.addEventListener(type, handleMessage);
176
+ });
177
+ }
178
+ const transport = {
179
+ async connect(opts) {
180
+ config = {
181
+ baseUrl: opts.baseUrl,
182
+ orgId: opts.orgId,
183
+ graphId: opts.graphId,
184
+ userId: opts.userId
185
+ };
186
+ state = "connected";
187
+ log("Transport ready");
188
+ },
189
+ subscribeToJob(jobId) {
190
+ if (!config) {
191
+ throw new Error("Transport not connected");
192
+ }
193
+ if (eventSource) {
194
+ eventSource.close();
195
+ eventSource = void 0;
196
+ }
197
+ currentJobId = jobId;
198
+ state = "connecting";
199
+ const params = new URLSearchParams({
200
+ orgId: config.orgId
201
+ });
202
+ if (config.graphId) {
203
+ params.set("graphId", config.graphId);
204
+ }
205
+ const streamUrl = `${config.baseUrl}/api/v1/kg/full-ingest/${jobId}/progress?${params.toString()}`;
206
+ log("Connecting to stream:", streamUrl);
207
+ const es = new EventSource(streamUrl);
208
+ es.onopen = () => {
209
+ log("Stream connected");
210
+ state = "connected";
211
+ setupEventListeners(es);
212
+ };
213
+ es.onerror = () => {
214
+ if (es.readyState === EventSource.CLOSED) {
215
+ log("Stream closed");
216
+ state = "disconnected";
217
+ currentJobId = void 0;
218
+ }
219
+ };
220
+ eventSource = es;
221
+ },
222
+ on(eventType, handler) {
223
+ if (!typeHandlers.has(eventType)) {
224
+ typeHandlers.set(eventType, /* @__PURE__ */ new Set());
225
+ }
226
+ typeHandlers.get(eventType).add(handler);
227
+ return () => {
228
+ const handlers = typeHandlers.get(eventType);
229
+ if (handlers) {
230
+ handlers.delete(handler);
231
+ if (handlers.size === 0) {
232
+ typeHandlers.delete(eventType);
233
+ }
234
+ }
235
+ };
236
+ },
237
+ disconnect() {
238
+ log("Disconnecting");
239
+ if (eventSource) {
240
+ eventSource.close();
241
+ eventSource = void 0;
242
+ }
243
+ state = "disconnected";
244
+ currentJobId = void 0;
245
+ },
246
+ getState() {
247
+ return state;
248
+ }
249
+ };
250
+ return transport;
251
+ }
252
+
253
+
254
+
255
+
256
+ exports.createQuickIngestTransport = createQuickIngestTransport; exports.createFullIngestTransport = createFullIngestTransport;
257
+ //# sourceMappingURL=chunk-WYRCAPY4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/eloquent/eloquent/packages/@elqnt/kg/dist/chunk-WYRCAPY4.js","../transport/quick-ingest.ts","../transport/full-ingest.ts"],"names":[],"mappings":"AAAA,qFAAY;AACZ;AACA;ACyKO,SAAS,0BAAA,CACd,QAAA,EAAuC,CAAC,CAAA,EAClB;AACtB,EAAA,MAAM,EAAE,MAAA,EAAQ,MAAM,EAAA,EAAI,OAAA;AAG1B,EAAA,IAAI,WAAA;AACJ,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,MAAA,EAAqD,cAAA;AACzD,EAAA,IAAI,YAAA;AAGJ,EAAA,MAAM,aAAA,kBAAe,IAAI,GAAA,CAA4D,CAAA;AAGrF,EAAA,MAAM,IAAA,EAAM,MAAA,EACR,CAAC,GAAA,EAAA,GAAgB,IAAA,EAAA,GAAoB,OAAA,CAAQ,GAAA,CAAI,CAAA,kBAAA,EAAqB,GAAG,CAAA,CAAA;AAClE,EAAA;AAGkC,EAAA;AACC,IAAA;AAC9B,IAAA;AACkB,MAAA;AACxB,QAAA;AACW,UAAA;AACD,QAAA;AACuD,UAAA;AACrE,QAAA;AACD,MAAA;AACH,IAAA;AACF,EAAA;AAGkD,EAAA;AACV,IAAA;AAElC,IAAA;AACgC,MAAA;AACR,MAAA;AACjB,MAAA;AAGyB,MAAA;AACxB,QAAA;AACO,QAAA;AACjB,MAAA;AACY,IAAA;AACuD,MAAA;AACrE,IAAA;AACF,EAAA;AAGoD,EAAA;AACN,IAAA;AAEwB,IAAA;AACvC,IAAA;AACY,MAAA;AACxC,IAAA;AACH,EAAA;AAEwC,EAAA;AACW,IAAA;AACtC,MAAA;AACO,QAAA;AACF,QAAA;AACE,QAAA;AACD,QAAA;AACf,MAAA;AACQ,MAAA;AACa,MAAA;AACvB,IAAA;AAEoC,IAAA;AACrB,MAAA;AAC8B,QAAA;AAC3C,MAAA;AAGiB,MAAA;AACG,QAAA;AACJ,QAAA;AAChB,MAAA;AAEe,MAAA;AACP,MAAA;AAE2B,MAAA;AACnB,QAAA;AACf,MAAA;AACmB,MAAA;AACkB,QAAA;AACtC,MAAA;AAEmE,MAAA;AAC7B,MAAA;AAEF,MAAA;AAGd,MAAA;AAEJ,MAAA;AACM,QAAA;AACd,QAAA;AACV,MAAA;AAEmB,MAAA;AACyB,QAAA;AACrB,UAAA;AACX,UAAA;AACO,UAAA;AACjB,QAAA;AACF,MAAA;AAEc,MAAA;AAChB,IAAA;AAKe,IAAA;AACqB,MAAA;AACK,QAAA;AACvC,MAAA;AACqF,MAAA;AAExE,MAAA;AACgC,QAAA;AAC7B,QAAA;AACwD,UAAA;AAC3C,UAAA;AACM,YAAA;AAC/B,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AAEmB,IAAA;AACE,MAAA;AAEF,MAAA;AACG,QAAA;AACJ,QAAA;AAChB,MAAA;AAEQ,MAAA;AACO,MAAA;AACjB,IAAA;AAEwD,IAAA;AAC/C,MAAA;AACT,IAAA;AACF,EAAA;AAEO,EAAA;AACT;ADjN6E;AACA;AE+ItD;AACK,EAAA;AAGtB,EAAA;AACA,EAAA;AACqD,EAAA;AACrD,EAAA;AAG+E,EAAA;AAIP,EAAA;AACjE,EAAA;AAGiC,EAAA;AACE,IAAA;AAC9B,IAAA;AACkB,MAAA;AACxB,QAAA;AACW,UAAA;AACD,QAAA;AACsD,UAAA;AACpE,QAAA;AACD,MAAA;AACH,IAAA;AACF,EAAA;AAGkD,EAAA;AACV,IAAA;AAElC,IAAA;AACgC,MAAA;AACR,MAAA;AACjB,MAAA;AAG8C,MAAA;AAC7C,QAAA;AACO,QAAA;AACjB,MAAA;AACY,IAAA;AACsD,MAAA;AACpE,IAAA;AACF,EAAA;AAGoD,EAAA;AACN,IAAA;AAEzB,IAAA;AACjB,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACA,MAAA;AACF,IAAA;AAC6B,IAAA;AACY,MAAA;AACxC,IAAA;AACH,EAAA;AAEuC,EAAA;AACY,IAAA;AACtC,MAAA;AACO,QAAA;AACF,QAAA;AACE,QAAA;AACD,QAAA;AACf,MAAA;AACQ,MAAA;AACa,MAAA;AACvB,IAAA;AAEoC,IAAA;AACrB,MAAA;AAC8B,QAAA;AAC3C,MAAA;AAGiB,MAAA;AACG,QAAA;AACJ,QAAA;AAChB,MAAA;AAEe,MAAA;AACP,MAAA;AAE2B,MAAA;AACnB,QAAA;AACf,MAAA;AACmB,MAAA;AACkB,QAAA;AACtC,MAAA;AAEkE,MAAA;AAC5B,MAAA;AAEF,MAAA;AAElB,MAAA;AACM,QAAA;AACd,QAAA;AACc,QAAA;AACxB,MAAA;AAEmB,MAAA;AACyB,QAAA;AACrB,UAAA;AACX,UAAA;AACO,UAAA;AACjB,QAAA;AACF,MAAA;AAEc,MAAA;AAChB,IAAA;AAKe,IAAA;AACqB,MAAA;AACK,QAAA;AACvC,MAAA;AACmF,MAAA;AAEtE,MAAA;AACgC,QAAA;AAC7B,QAAA;AACsD,UAAA;AACzC,UAAA;AACM,YAAA;AAC/B,UAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AAEmB,IAAA;AACE,MAAA;AAEF,MAAA;AACG,QAAA;AACJ,QAAA;AAChB,MAAA;AAEQ,MAAA;AACO,MAAA;AACjB,IAAA;AAEwD,IAAA;AAC/C,MAAA;AACT,IAAA;AACF,EAAA;AAEO,EAAA;AACT;AFnL6E;AACA;AACA;AACA;AACA","file":"/home/runner/work/eloquent/eloquent/packages/@elqnt/kg/dist/chunk-WYRCAPY4.js","sourcesContent":[null,"/**\n * Quick Ingestion SSE Transport\n *\n * Handles real-time progress updates for quick ingestion jobs.\n *\n * @example\n * ```typescript\n * import { createQuickIngestTransport } from \"@elqnt/kg/transport\";\n *\n * const transport = createQuickIngestTransport({ debug: true });\n * await transport.connect({ baseUrl, orgId });\n *\n * transport.on(\"item_start\", (event) => {\n * console.log(\"Started processing:\", event.itemId);\n * });\n *\n * transport.on(\"item_progress\", (event) => {\n * console.log(`Progress: ${event.progress}% - ${event.text}`);\n * });\n *\n * transport.on(\"item_complete\", (event) => {\n * console.log(`Completed: ${event.articles} articles, ${event.topics} topics`);\n * });\n *\n * transport.on(\"job_complete\", (event) => {\n * console.log(`Job done: ${event.totalArticles} articles, ${event.totalTopics} topics`);\n * });\n *\n * transport.subscribeToJob(\"qij_xyz789\");\n * ```\n */\n\nimport type { KGApiOptions } from \"../api\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Transport configuration\n */\nexport interface QuickIngestTransportConfig {\n /** Base URL for the API */\n baseUrl: string;\n /** Organization ID */\n orgId: string;\n /** Optional graph ID */\n graphId?: string;\n /** User ID for authentication */\n userId?: string;\n}\n\n/**\n * Transport options\n */\nexport interface QuickIngestTransportOptions {\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Event when an item starts processing\n */\nexport interface QuickIngestItemStartEvent {\n type: \"item_start\";\n itemId: string;\n timestamp: number;\n}\n\n/**\n * Event when an item has progress update\n */\nexport interface QuickIngestItemProgressEvent {\n type: \"item_progress\";\n itemId: string;\n progress: number;\n text: string;\n timestamp: number;\n}\n\n/**\n * Event when an item completes successfully\n */\nexport interface QuickIngestItemCompleteEvent {\n type: \"item_complete\";\n itemId: string;\n articles: number;\n topics: number;\n timestamp: number;\n}\n\n/**\n * Event when an item encounters an error\n */\nexport interface QuickIngestItemErrorEvent {\n type: \"item_error\";\n itemId: string;\n error: string;\n timestamp: number;\n}\n\n/**\n * Event when the entire job completes\n */\nexport interface QuickIngestJobCompleteEvent {\n type: \"job_complete\";\n totalArticles: number;\n totalTopics: number;\n timestamp: number;\n}\n\n/**\n * Union of all quick ingest events\n */\nexport type QuickIngestEvent =\n | QuickIngestItemStartEvent\n | QuickIngestItemProgressEvent\n | QuickIngestItemCompleteEvent\n | QuickIngestItemErrorEvent\n | QuickIngestJobCompleteEvent;\n\n/**\n * Event handler function type\n */\nexport type QuickIngestEventHandler<T = QuickIngestEvent> = (event: T) => void;\n\n/**\n * Unsubscribe function\n */\nexport type Unsubscribe = () => void;\n\n/**\n * Quick Ingest Transport interface\n */\nexport interface QuickIngestTransport {\n /**\n * Connect to the transport\n */\n connect(options: KGApiOptions): Promise<void>;\n\n /**\n * Subscribe to a specific job's events\n */\n subscribeToJob(jobId: string): void;\n\n /**\n * Subscribe to specific event type\n */\n on<T extends QuickIngestEvent[\"type\"]>(\n eventType: T,\n handler: QuickIngestEventHandler<Extract<QuickIngestEvent, { type: T }>>\n ): Unsubscribe;\n\n /**\n * Disconnect from the transport\n */\n disconnect(): void;\n\n /**\n * Get current connection state\n */\n getState(): \"disconnected\" | \"connecting\" | \"connected\";\n}\n\n// =============================================================================\n// IMPLEMENTATION\n// =============================================================================\n\n/**\n * Create a Quick Ingest SSE transport\n */\nexport function createQuickIngestTransport(\n options: QuickIngestTransportOptions = {}\n): QuickIngestTransport {\n const { debug = false } = options;\n\n // Internal state\n let eventSource: EventSource | undefined;\n let config: QuickIngestTransportConfig | undefined;\n let state: \"disconnected\" | \"connecting\" | \"connected\" = \"disconnected\";\n let currentJobId: string | undefined;\n\n // Event handlers\n const typeHandlers = new Map<string, Set<QuickIngestEventHandler<QuickIngestEvent>>>();\n\n // Logger\n const log = debug\n ? (msg: string, ...args: unknown[]) => console.log(`[kg-quick-ingest] ${msg}`, ...args)\n : () => {};\n\n // Helper to emit events\n function emit(event: QuickIngestEvent): void {\n const handlers = typeHandlers.get(event.type);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n console.error(`[kg-quick-ingest] Error in ${event.type} handler:`, err);\n }\n });\n }\n }\n\n // Handle SSE message\n function handleMessage(event: MessageEvent): void {\n if (!event.data || event.data === \"\") return;\n\n try {\n const data = JSON.parse(event.data) as QuickIngestEvent;\n log(\"Received:\", data.type);\n emit(data);\n\n // Handle job completion\n if (data.type === \"job_complete\") {\n state = \"connected\";\n currentJobId = undefined;\n }\n } catch (err) {\n console.error(\"[kg-quick-ingest] Failed to parse SSE message:\", err);\n }\n }\n\n // Setup event listeners\n function setupEventListeners(es: EventSource): void {\n es.addEventListener(\"message\", handleMessage);\n\n const eventTypes = [\"item_start\", \"item_progress\", \"item_complete\", \"item_error\", \"job_complete\"];\n eventTypes.forEach((type) => {\n es.addEventListener(type, handleMessage);\n });\n }\n\n const transport: QuickIngestTransport = {\n async connect(opts: KGApiOptions): Promise<void> {\n config = {\n baseUrl: opts.baseUrl,\n orgId: opts.orgId,\n graphId: opts.graphId,\n userId: opts.userId,\n };\n state = \"connected\";\n log(\"Transport ready\");\n },\n\n subscribeToJob(jobId: string): void {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n // Close existing connection\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n currentJobId = jobId;\n state = \"connecting\";\n\n const params = new URLSearchParams({\n orgId: config.orgId,\n });\n if (config.graphId) {\n params.set(\"graphId\", config.graphId);\n }\n\n const streamUrl = `${config.baseUrl}/api/v1/kg/quick-ingest/${jobId}/progress?${params.toString()}`;\n log(\"Connecting to stream:\", streamUrl);\n\n const es = new EventSource(streamUrl);\n\n // Setup listeners\n setupEventListeners(es);\n\n es.onopen = () => {\n log(\"Stream connected\");\n state = \"connected\";\n };\n\n es.onerror = () => {\n if (es.readyState === EventSource.CLOSED) {\n log(\"Stream closed\");\n state = \"disconnected\";\n currentJobId = undefined;\n }\n };\n\n eventSource = es;\n },\n\n on<T extends QuickIngestEvent[\"type\"]>(\n eventType: T,\n handler: QuickIngestEventHandler<Extract<QuickIngestEvent, { type: T }>>\n ): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler as QuickIngestEventHandler<QuickIngestEvent>);\n\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler as QuickIngestEventHandler<QuickIngestEvent>);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n disconnect(): void {\n log(\"Disconnecting\");\n\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n state = \"disconnected\";\n currentJobId = undefined;\n },\n\n getState(): \"disconnected\" | \"connecting\" | \"connected\" {\n return state;\n },\n };\n\n return transport;\n}\n","/**\n * Full Ingestion SSE Transport\n *\n * Handles real-time progress updates and node streaming for full ingestion extraction.\n *\n * @example\n * ```typescript\n * import { createFullIngestTransport } from \"@elqnt/kg/transport\";\n *\n * const transport = createFullIngestTransport({ debug: true });\n * await transport.connect({ baseUrl, orgId });\n *\n * transport.on(\"progress\", (event) => {\n * console.log(`Extracting page ${event.currentPage} of ${event.totalPages}`);\n * });\n *\n * transport.on(\"node\", (event) => {\n * console.log(\"Extracted node:\", event.label, event.fields);\n * });\n *\n * transport.on(\"complete\", (event) => {\n * console.log(`Extraction done: ${event.totalNodes} nodes`);\n * });\n *\n * transport.subscribeToJob(\"fij_extract_789\");\n * ```\n */\n\nimport type { KGApiOptions } from \"../api\";\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Transport configuration\n */\nexport interface FullIngestTransportConfig {\n /** Base URL for the API */\n baseUrl: string;\n /** Organization ID */\n orgId: string;\n /** Optional graph ID */\n graphId?: string;\n /** User ID for authentication */\n userId?: string;\n}\n\n/**\n * Transport options\n */\nexport interface FullIngestTransportOptions {\n /** Enable debug logging */\n debug?: boolean;\n}\n\n/**\n * Event for extraction progress\n */\nexport interface FullIngestProgressEvent {\n type: \"progress\";\n currentPage: number;\n totalPages: number;\n timestamp: number;\n}\n\n/**\n * Event when a node is extracted\n */\nexport interface FullIngestNodeEvent {\n type: \"node\";\n id: string;\n label: string;\n fields: Record<string, unknown>;\n timestamp: number;\n}\n\n/**\n * Event when consolidation is starting\n */\nexport interface FullIngestConsolidatingEvent {\n type: \"consolidating\";\n message: string;\n rawCount?: number;\n timestamp: number;\n}\n\n/**\n * Event when consolidation progress updates\n */\nexport interface FullIngestConsolidateProgressEvent {\n type: \"consolidate_progress\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when consolidation completes\n */\nexport interface FullIngestConsolidatedEvent {\n type: \"consolidated\";\n totalNodes: number;\n mergedCount: number;\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when linking/relationship extraction starts\n */\nexport interface FullIngestLinkingEvent {\n type: \"linking\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when linking completes\n */\nexport interface FullIngestLinkedEvent {\n type: \"linked\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when an edge is extracted\n */\nexport interface FullIngestEdgeEvent {\n type: \"edge\";\n id: string;\n fromLabel: string;\n fromName: string;\n toLabel: string;\n toName: string;\n edgeLabel: string;\n confidence: number;\n timestamp: number;\n}\n\n/**\n * Event when extraction completes\n */\nexport interface FullIngestCompleteEvent {\n type: \"complete\";\n totalNodes: number;\n totalEdges?: number;\n message?: string;\n timestamp: number;\n}\n\n/**\n * Event when extraction encounters an error\n */\nexport interface FullIngestErrorEvent {\n type: \"error\";\n message: string;\n timestamp: number;\n}\n\n/**\n * Event when ingestion to KG starts\n */\nexport interface FullIngestIngestingEvent {\n type: \"ingesting\";\n message: string;\n totalNodes: number;\n totalEdges: number;\n timestamp: number;\n}\n\n/**\n * Event for ingestion progress (node/edge being ingested)\n */\nexport interface FullIngestIngestProgressEvent {\n type: \"ingest_progress\";\n message: string;\n currentNode: number;\n totalNodes: number;\n currentEdge: number;\n totalEdges: number;\n timestamp: number;\n}\n\n/**\n * Event when ingestion to KG completes\n */\nexport interface FullIngestIngestCompleteEvent {\n type: \"ingest_complete\";\n message: string;\n nodesIngested: number;\n edgesIngested: number;\n timestamp: number;\n}\n\n/**\n * Union of all full ingest events\n */\nexport type FullIngestEvent =\n | FullIngestProgressEvent\n | FullIngestNodeEvent\n | FullIngestConsolidatingEvent\n | FullIngestConsolidateProgressEvent\n | FullIngestConsolidatedEvent\n | FullIngestLinkingEvent\n | FullIngestLinkedEvent\n | FullIngestEdgeEvent\n | FullIngestCompleteEvent\n | FullIngestErrorEvent\n | FullIngestIngestingEvent\n | FullIngestIngestProgressEvent\n | FullIngestIngestCompleteEvent;\n\n/**\n * Event handler function type\n */\nexport type FullIngestEventHandler<T = FullIngestEvent> = (event: T) => void;\n\n// Unsubscribe type is exported from quick-ingest.ts\nimport type { Unsubscribe } from \"./quick-ingest\";\n\n/**\n * Full Ingest Transport interface\n */\nexport interface FullIngestTransport {\n /**\n * Connect to the transport\n */\n connect(options: KGApiOptions): Promise<void>;\n\n /**\n * Subscribe to a specific job's events\n */\n subscribeToJob(jobId: string): void;\n\n /**\n * Subscribe to specific event type\n */\n on<T extends FullIngestEvent[\"type\"]>(\n eventType: T,\n handler: FullIngestEventHandler<Extract<FullIngestEvent, { type: T }>>\n ): Unsubscribe;\n\n /**\n * Disconnect from the transport\n */\n disconnect(): void;\n\n /**\n * Get current connection state\n */\n getState(): \"disconnected\" | \"connecting\" | \"connected\";\n}\n\n// =============================================================================\n// IMPLEMENTATION\n// =============================================================================\n\n/**\n * Create a Full Ingest SSE transport\n */\nexport function createFullIngestTransport(\n options: FullIngestTransportOptions = {}\n): FullIngestTransport {\n const { debug = false } = options;\n\n // Internal state\n let eventSource: EventSource | undefined;\n let config: FullIngestTransportConfig | undefined;\n let state: \"disconnected\" | \"connecting\" | \"connected\" = \"disconnected\";\n let currentJobId: string | undefined;\n\n // Event handlers\n const typeHandlers = new Map<string, Set<FullIngestEventHandler<FullIngestEvent>>>();\n\n // Logger\n const log = debug\n ? (msg: string, ...args: unknown[]) => console.log(`[kg-full-ingest] ${msg}`, ...args)\n : () => {};\n\n // Helper to emit events\n function emit(event: FullIngestEvent): void {\n const handlers = typeHandlers.get(event.type);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(event);\n } catch (err) {\n console.error(`[kg-full-ingest] Error in ${event.type} handler:`, err);\n }\n });\n }\n }\n\n // Handle SSE message\n function handleMessage(event: MessageEvent): void {\n if (!event.data || event.data === \"\") return;\n\n try {\n const data = JSON.parse(event.data) as FullIngestEvent;\n log(\"Received:\", data.type);\n emit(data);\n\n // Handle completion or error\n if (data.type === \"complete\" || data.type === \"error\") {\n state = \"connected\";\n currentJobId = undefined;\n }\n } catch (err) {\n console.error(\"[kg-full-ingest] Failed to parse SSE message:\", err);\n }\n }\n\n // Setup event listeners\n function setupEventListeners(es: EventSource): void {\n es.addEventListener(\"message\", handleMessage);\n\n const eventTypes = [\n \"progress\",\n \"node\",\n \"consolidating\",\n \"consolidate_progress\",\n \"consolidated\",\n \"linking\",\n \"linked\",\n \"edge\",\n \"complete\",\n \"error\",\n \"ingesting\",\n \"ingest_progress\",\n \"ingest_complete\",\n ];\n eventTypes.forEach((type) => {\n es.addEventListener(type, handleMessage);\n });\n }\n\n const transport: FullIngestTransport = {\n async connect(opts: KGApiOptions): Promise<void> {\n config = {\n baseUrl: opts.baseUrl,\n orgId: opts.orgId,\n graphId: opts.graphId,\n userId: opts.userId,\n };\n state = \"connected\";\n log(\"Transport ready\");\n },\n\n subscribeToJob(jobId: string): void {\n if (!config) {\n throw new Error(\"Transport not connected\");\n }\n\n // Close existing connection\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n currentJobId = jobId;\n state = \"connecting\";\n\n const params = new URLSearchParams({\n orgId: config.orgId,\n });\n if (config.graphId) {\n params.set(\"graphId\", config.graphId);\n }\n\n const streamUrl = `${config.baseUrl}/api/v1/kg/full-ingest/${jobId}/progress?${params.toString()}`;\n log(\"Connecting to stream:\", streamUrl);\n\n const es = new EventSource(streamUrl);\n\n es.onopen = () => {\n log(\"Stream connected\");\n state = \"connected\";\n setupEventListeners(es);\n };\n\n es.onerror = () => {\n if (es.readyState === EventSource.CLOSED) {\n log(\"Stream closed\");\n state = \"disconnected\";\n currentJobId = undefined;\n }\n };\n\n eventSource = es;\n },\n\n on<T extends FullIngestEvent[\"type\"]>(\n eventType: T,\n handler: FullIngestEventHandler<Extract<FullIngestEvent, { type: T }>>\n ): Unsubscribe {\n if (!typeHandlers.has(eventType)) {\n typeHandlers.set(eventType, new Set());\n }\n typeHandlers.get(eventType)!.add(handler as FullIngestEventHandler<FullIngestEvent>);\n\n return () => {\n const handlers = typeHandlers.get(eventType);\n if (handlers) {\n handlers.delete(handler as FullIngestEventHandler<FullIngestEvent>);\n if (handlers.size === 0) {\n typeHandlers.delete(eventType);\n }\n }\n };\n },\n\n disconnect(): void {\n log(\"Disconnecting\");\n\n if (eventSource) {\n eventSource.close();\n eventSource = undefined;\n }\n\n state = \"disconnected\";\n currentJobId = undefined;\n },\n\n getState(): \"disconnected\" | \"connecting\" | \"connected\" {\n return state;\n },\n };\n\n return transport;\n}\n"]}