mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	resolve linter errors
This commit is contained in:
		
							parent
							
								
									2d745c12c8
								
							
						
					
					
						commit
						c716481ef8
					
				| @ -41,7 +41,10 @@ Format your answer as a valid JSON array without markdown code blocks, like this | |||||||
|                 return cached; |                 return cached; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             const messages: Message[] = [ |             const messages: Array<{ | ||||||
|  |                 role: 'user' | 'assistant' | 'system'; | ||||||
|  |                 content: string; | ||||||
|  |             }> = [ | ||||||
|                 { role: "system", content: this.getEnhancedPrompt() }, |                 { role: "system", content: this.getEnhancedPrompt() }, | ||||||
|                 { role: "user", content: userQuestion } |                 { role: "user", content: userQuestion } | ||||||
|             ]; |             ]; | ||||||
|  | |||||||
| @ -34,12 +34,12 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo | |||||||
|                     maxResults, |                     maxResults, | ||||||
|                     useEnhancedQueries: true, |                     useEnhancedQueries: true, | ||||||
|                     threshold: 0.6, |                     threshold: 0.6, | ||||||
|                     llmService: null // Will use default service
 |                     llmService: undefined // Let the vectorSearchStage use the default service
 | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             log.info(`Vector search found ${vectorSearchResult.searchResults.length} relevant notes`); |             log.info(`Vector search found ${vectorSearchResult.searchResults.length} relevant notes`); | ||||||
|              | 
 | ||||||
|             // If no results, return empty context
 |             // If no results, return empty context
 | ||||||
|             if (vectorSearchResult.searchResults.length === 0) { |             if (vectorSearchResult.searchResults.length === 0) { | ||||||
|                 log.info(`No relevant notes found for context extraction`); |                 log.info(`No relevant notes found for context extraction`); | ||||||
| @ -49,10 +49,10 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo | |||||||
|             // Step 2: Format search results into a context string
 |             // Step 2: Format search results into a context string
 | ||||||
|             const provider = await providerManager.getPreferredEmbeddingProvider(); |             const provider = await providerManager.getPreferredEmbeddingProvider(); | ||||||
|             const providerId = provider?.name || 'default'; |             const providerId = provider?.name || 'default'; | ||||||
|              | 
 | ||||||
|             const context = await contextFormatter.buildContextFromNotes( |             const context = await contextFormatter.buildContextFromNotes( | ||||||
|                 vectorSearchResult.searchResults,  |                 vectorSearchResult.searchResults, | ||||||
|                 query,  |                 query, | ||||||
|                 providerId, |                 providerId, | ||||||
|                 messages |                 messages | ||||||
|             ); |             ); | ||||||
| @ -64,4 +64,4 @@ export class SemanticContextExtractionStage extends BasePipelineStage<SemanticCo | |||||||
|             return { context: "" }; |             return { context: "" }; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -76,12 +76,12 @@ export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { re | |||||||
| 
 | 
 | ||||||
|         // Execute each tool call and add results to messages
 |         // Execute each tool call and add results to messages
 | ||||||
|         log.info(`========== STARTING TOOL EXECUTION ==========`); |         log.info(`========== STARTING TOOL EXECUTION ==========`); | ||||||
|         log.info(`Executing ${response.tool_calls.length} tool calls in parallel`); |         log.info(`Executing ${response.tool_calls?.length || 0} tool calls in parallel`); | ||||||
| 
 | 
 | ||||||
|         const executionStartTime = Date.now(); |         const executionStartTime = Date.now(); | ||||||
|         const toolResults = await Promise.all(response.tool_calls.map(async (toolCall, index) => { |         const toolResults = await Promise.all((response.tool_calls || []).map(async (toolCall, index) => { | ||||||
|             try { |             try { | ||||||
|                 log.info(`========== TOOL CALL ${index + 1} OF ${response.tool_calls.length} ==========`); |                 log.info(`========== TOOL CALL ${index + 1} OF ${response.tool_calls?.length || 0} ==========`); | ||||||
|                 log.info(`Tool call ${index + 1} received - Name: ${toolCall.function.name}, ID: ${toolCall.id || 'unknown'}`); |                 log.info(`Tool call ${index + 1} received - Name: ${toolCall.function.name}, ID: ${toolCall.id || 'unknown'}`); | ||||||
| 
 | 
 | ||||||
|                 // Log parameters
 |                 // Log parameters
 | ||||||
|  | |||||||
| @ -874,8 +874,8 @@ class RestChatService { | |||||||
|                 if (typeof toolCall.function.arguments === 'string') { |                 if (typeof toolCall.function.arguments === 'string') { | ||||||
|                     try { |                     try { | ||||||
|                         args = JSON.parse(toolCall.function.arguments); |                         args = JSON.parse(toolCall.function.arguments); | ||||||
|                     } catch (e) { |                     } catch (e: unknown) { | ||||||
|                         log.error(`Failed to parse tool arguments: ${e.message}`); |                         log.error(`Failed to parse tool arguments: ${e instanceof Error ? e.message : String(e)}`); | ||||||
| 
 | 
 | ||||||
|                         // Try cleanup and retry
 |                         // Try cleanup and retry
 | ||||||
|                         try { |                         try { | ||||||
|  | |||||||
| @ -116,7 +116,7 @@ export class AttributeManagerTool implements ToolHandler { | |||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     // Create the attribute
 |                     // Create the attribute
 | ||||||
|                     await attributes.createAttribute(noteId, attributeName, value); |                     await attributes.createLabel(noteId, attributeName, value); | ||||||
|                     const duration = Date.now() - startTime; |                     const duration = Date.now() - startTime; | ||||||
| 
 | 
 | ||||||
|                     log.info(`Added attribute ${attributeName}=${value || ''} in ${duration}ms`); |                     log.info(`Added attribute ${attributeName}=${value || ''} in ${duration}ms`); | ||||||
| @ -153,7 +153,18 @@ export class AttributeManagerTool implements ToolHandler { | |||||||
| 
 | 
 | ||||||
|                     // Remove all matching attributes
 |                     // Remove all matching attributes
 | ||||||
|                     for (const attr of attributesToRemove) { |                     for (const attr of attributesToRemove) { | ||||||
|                         await attributes.deleteAttribute(attr.attributeId); |                         // Delete attribute by recreating it with isDeleted flag
 | ||||||
|  |                         const attrToDelete = { | ||||||
|  |                             attributeId: attr.attributeId, | ||||||
|  |                             noteId: attr.noteId, | ||||||
|  |                             type: attr.type, | ||||||
|  |                             name: attr.name, | ||||||
|  |                             value: attr.value, | ||||||
|  |                             isDeleted: true, | ||||||
|  |                             position: attr.position, | ||||||
|  |                             utcDateModified: new Date().toISOString() | ||||||
|  |                         }; | ||||||
|  |                         await attributes.createAttribute(attrToDelete); | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     const duration = Date.now() - startTime; |                     const duration = Date.now() - startTime; | ||||||
| @ -195,7 +206,18 @@ export class AttributeManagerTool implements ToolHandler { | |||||||
| 
 | 
 | ||||||
|                     // Update all matching attributes
 |                     // Update all matching attributes
 | ||||||
|                     for (const attr of attributesToUpdate) { |                     for (const attr of attributesToUpdate) { | ||||||
|                         await attributes.updateAttributeValue(attr.attributeId, attributeValue); |                         // Update by recreating with the same ID but new value
 | ||||||
|  |                         const attrToUpdate = { | ||||||
|  |                             attributeId: attr.attributeId, | ||||||
|  |                             noteId: attr.noteId, | ||||||
|  |                             type: attr.type, | ||||||
|  |                             name: attr.name, | ||||||
|  |                             value: attributeValue, | ||||||
|  |                             isDeleted: false, | ||||||
|  |                             position: attr.position, | ||||||
|  |                             utcDateModified: new Date().toISOString() | ||||||
|  |                         }; | ||||||
|  |                         await attributes.createAttribute(attrToUpdate); | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     const duration = Date.now() - startTime; |                     const duration = Date.now() - startTime; | ||||||
|  | |||||||
| @ -221,13 +221,14 @@ export class CalendarIntegrationTool implements ToolHandler { | |||||||
| 
 | 
 | ||||||
|             // Create the new note
 |             // Create the new note
 | ||||||
|             const createStartTime = Date.now(); |             const createStartTime = Date.now(); | ||||||
|             const noteId = await notes.createNewNote({ |             const result = notes.createNewNote({ | ||||||
|                 parentNoteId: parent.noteId, |                 parentNoteId: parent.noteId, | ||||||
|                 title: title, |                 title: title, | ||||||
|                 content: content, |                 content: content, | ||||||
|                 type: 'text', |                 type: 'text' as const, | ||||||
|                 mime: 'text/html' |                 mime: 'text/html' | ||||||
|             }); |             }); | ||||||
|  |             const noteId = result.note.noteId; | ||||||
|             const createDuration = Date.now() - createStartTime; |             const createDuration = Date.now() - createStartTime; | ||||||
| 
 | 
 | ||||||
|             if (!noteId) { |             if (!noteId) { | ||||||
|  | |||||||
| @ -88,22 +88,22 @@ export class ContentExtractionTool implements ToolHandler { | |||||||
|             const extractedContent: any = {}; |             const extractedContent: any = {}; | ||||||
| 
 | 
 | ||||||
|             if (extractionType === 'lists' || extractionType === 'all') { |             if (extractionType === 'lists' || extractionType === 'all') { | ||||||
|                 extractedContent.lists = this.extractLists(content); |                 extractedContent.lists = this.extractLists(typeof content === 'string' ? content : content.toString()); | ||||||
|                 log.info(`Extracted ${extractedContent.lists.length} lists`); |                 log.info(`Extracted ${extractedContent.lists.length} lists`); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (extractionType === 'tables' || extractionType === 'all') { |             if (extractionType === 'tables' || extractionType === 'all') { | ||||||
|                 extractedContent.tables = this.extractTables(content); |                 extractedContent.tables = this.extractTables(typeof content === 'string' ? content : content.toString()); | ||||||
|                 log.info(`Extracted ${extractedContent.tables.length} tables`); |                 log.info(`Extracted ${extractedContent.tables.length} tables`); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (extractionType === 'headings' || extractionType === 'all') { |             if (extractionType === 'headings' || extractionType === 'all') { | ||||||
|                 extractedContent.headings = this.extractHeadings(content); |                 extractedContent.headings = this.extractHeadings(typeof content === 'string' ? content : content.toString()); | ||||||
|                 log.info(`Extracted ${extractedContent.headings.length} headings`); |                 log.info(`Extracted ${extractedContent.headings.length} headings`); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (extractionType === 'codeBlocks' || extractionType === 'all') { |             if (extractionType === 'codeBlocks' || extractionType === 'all') { | ||||||
|                 extractedContent.codeBlocks = this.extractCodeBlocks(content); |                 extractedContent.codeBlocks = this.extractCodeBlocks(typeof content === 'string' ? content : content.toString()); | ||||||
|                 log.info(`Extracted ${extractedContent.codeBlocks.length} code blocks`); |                 log.info(`Extracted ${extractedContent.codeBlocks.length} code blocks`); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -315,46 +315,42 @@ export class ContentExtractionTool implements ToolHandler { | |||||||
|     private filterContentByQuery(content: any, query: string): void { |     private filterContentByQuery(content: any, query: string): void { | ||||||
|         const lowerQuery = query.toLowerCase(); |         const lowerQuery = query.toLowerCase(); | ||||||
| 
 | 
 | ||||||
|         // Filter lists
 |  | ||||||
|         if (content.lists) { |         if (content.lists) { | ||||||
|             content.lists = content.lists.filter(list => { |             content.lists = content.lists.filter((list: { type: string; items: string[] }) => { | ||||||
|                 // Keep the list if any item matches the query
 |                 // Check if any item in the list contains the query
 | ||||||
|                 return list.items.some(item => item.toLowerCase().includes(lowerQuery)); |                 return list.items.some((item: string) => item.toLowerCase().includes(lowerQuery)); | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             // Also filter individual items in each list
 |             // Also filter individual items in each list
 | ||||||
|             content.lists.forEach(list => { |             content.lists.forEach((list: { type: string; items: string[] }) => { | ||||||
|                 list.items = list.items.filter(item => item.toLowerCase().includes(lowerQuery)); |                 list.items = list.items.filter((item: string) => item.toLowerCase().includes(lowerQuery)); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Filter headings
 |  | ||||||
|         if (content.headings) { |         if (content.headings) { | ||||||
|             content.headings = content.headings.filter(heading => |             content.headings = content.headings.filter((heading: { level: number; text: string }) => | ||||||
|                 heading.text.toLowerCase().includes(lowerQuery) |                 heading.text.toLowerCase().includes(lowerQuery) | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Filter tables
 |  | ||||||
|         if (content.tables) { |         if (content.tables) { | ||||||
|             content.tables = content.tables.filter(table => { |             content.tables = content.tables.filter((table: { headers: string[]; rows: string[][] }) => { | ||||||
|                 // Check headers
 |                 // Check if any header contains the query
 | ||||||
|                 const headerMatch = table.headers.some(header => |                 const headerMatch = table.headers.some((header: string) => | ||||||
|                     header.toLowerCase().includes(lowerQuery) |                     header.toLowerCase().includes(lowerQuery) | ||||||
|                 ); |                 ); | ||||||
| 
 | 
 | ||||||
|                 // Check cells
 |                 // Check if any cell in any row contains the query
 | ||||||
|                 const cellMatch = table.rows.some(row => |                 const cellMatch = table.rows.some((row: string[]) => | ||||||
|                     row.some(cell => cell.toLowerCase().includes(lowerQuery)) |                     row.some((cell: string) => cell.toLowerCase().includes(lowerQuery)) | ||||||
|                 ); |                 ); | ||||||
| 
 | 
 | ||||||
|                 return headerMatch || cellMatch; |                 return headerMatch || cellMatch; | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Filter code blocks
 |  | ||||||
|         if (content.codeBlocks) { |         if (content.codeBlocks) { | ||||||
|             content.codeBlocks = content.codeBlocks.filter(block => |             content.codeBlocks = content.codeBlocks.filter((block: { language?: string; code: string }) => | ||||||
|                 block.code.toLowerCase().includes(lowerQuery) |                 block.code.toLowerCase().includes(lowerQuery) | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import type { Tool, ToolHandler } from './tool_interfaces.js'; | |||||||
| import log from '../../log.js'; | import log from '../../log.js'; | ||||||
| import becca from '../../../becca/becca.js'; | import becca from '../../../becca/becca.js'; | ||||||
| import notes from '../../notes.js'; | import notes from '../../notes.js'; | ||||||
|  | import attributes from '../../attributes.js'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Definition of the note creation tool |  * Definition of the note creation tool | ||||||
| @ -43,20 +44,7 @@ export const noteCreationToolDefinition: Tool = { | |||||||
|                 }, |                 }, | ||||||
|                 attributes: { |                 attributes: { | ||||||
|                     type: 'array', |                     type: 'array', | ||||||
|                     description: 'Array of attributes to set on the note (e.g., [{"name":"#tag"}, {"name":"priority", "value":"high"}])', |                     description: 'Array of attributes to set on the note (e.g., [{"name":"#tag"}, {"name":"priority", "value":"high"}])' | ||||||
|                     items: { |  | ||||||
|                         type: 'object', |  | ||||||
|                         properties: { |  | ||||||
|                             name: { |  | ||||||
|                                 type: 'string', |  | ||||||
|                                 description: 'Name of the attribute' |  | ||||||
|                             }, |  | ||||||
|                             value: { |  | ||||||
|                                 type: 'string', |  | ||||||
|                                 description: 'Value of the attribute (if applicable)' |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|             }, |             }, | ||||||
|             required: ['title', 'content'] |             required: ['title', 'content'] | ||||||
| @ -87,7 +75,7 @@ export class NoteCreationTool implements ToolHandler { | |||||||
|             log.info(`Executing create_note tool - Title: "${title}", Type: ${type}, ParentNoteId: ${parentNoteId || 'root'}`); |             log.info(`Executing create_note tool - Title: "${title}", Type: ${type}, ParentNoteId: ${parentNoteId || 'root'}`); | ||||||
| 
 | 
 | ||||||
|             // Validate parent note exists if specified
 |             // Validate parent note exists if specified
 | ||||||
|             let parent; |             let parent = null; | ||||||
|             if (parentNoteId) { |             if (parentNoteId) { | ||||||
|                 parent = becca.notes[parentNoteId]; |                 parent = becca.notes[parentNoteId]; | ||||||
|                 if (!parent) { |                 if (!parent) { | ||||||
| @ -98,6 +86,11 @@ export class NoteCreationTool implements ToolHandler { | |||||||
|                 parent = becca.getNote('root'); |                 parent = becca.getNote('root'); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             // Make sure we have a valid parent at this point
 | ||||||
|  |             if (!parent) { | ||||||
|  |                 return 'Error: Failed to get a valid parent note. Root note may not be accessible.'; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             // Determine the appropriate mime type
 |             // Determine the appropriate mime type
 | ||||||
|             let noteMime = mime; |             let noteMime = mime; | ||||||
|             if (!noteMime) { |             if (!noteMime) { | ||||||
| @ -122,13 +115,14 @@ export class NoteCreationTool implements ToolHandler { | |||||||
| 
 | 
 | ||||||
|             // Create the note
 |             // Create the note
 | ||||||
|             const createStartTime = Date.now(); |             const createStartTime = Date.now(); | ||||||
|             const noteId = await notes.createNewNote({ |             const result = notes.createNewNote({ | ||||||
|                 parentNoteId: parent.noteId, |                 parentNoteId: parent.noteId, | ||||||
|                 title: title, |                 title: title, | ||||||
|                 content: content, |                 content: content, | ||||||
|                 type: type, |                 type: type as any, // Cast as any since not all string values may match the exact NoteType union
 | ||||||
|                 mime: noteMime |                 mime: noteMime | ||||||
|             }); |             }); | ||||||
|  |             const noteId = result.note.noteId; | ||||||
|             const createDuration = Date.now() - createStartTime; |             const createDuration = Date.now() - createStartTime; | ||||||
| 
 | 
 | ||||||
|             if (!noteId) { |             if (!noteId) { | ||||||
| @ -145,7 +139,18 @@ export class NoteCreationTool implements ToolHandler { | |||||||
|                     if (!attr.name) continue; |                     if (!attr.name) continue; | ||||||
| 
 | 
 | ||||||
|                     const attrStartTime = Date.now(); |                     const attrStartTime = Date.now(); | ||||||
|                     await notes.createAttribute(noteId, attr.name, attr.value || ''); |                     // Use createLabel for label attributes
 | ||||||
|  |                     if (attr.name.startsWith('#') || attr.name.startsWith('~')) { | ||||||
|  |                         await attributes.createLabel(noteId, attr.name.substring(1), attr.value || ''); | ||||||
|  |                     } else { | ||||||
|  |                         // Use createRelation for relation attributes if value looks like a note ID
 | ||||||
|  |                         if (attr.value && attr.value.match(/^[a-zA-Z0-9_]{12}$/)) { | ||||||
|  |                             await attributes.createRelation(noteId, attr.name, attr.value); | ||||||
|  |                         } else { | ||||||
|  |                             // Default to label for other attributes
 | ||||||
|  |                             await attributes.createLabel(noteId, attr.name, attr.value || ''); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                     const attrDuration = Date.now() - attrStartTime; |                     const attrDuration = Date.now() - attrStartTime; | ||||||
| 
 | 
 | ||||||
|                     log.info(`Added attribute ${attr.name}=${attr.value || ''} in ${attrDuration}ms`); |                     log.info(`Added attribute ${attr.name}=${attr.value || ''} in ${attrDuration}ms`); | ||||||
|  | |||||||
| @ -7,6 +7,7 @@ | |||||||
| import type { Tool, ToolHandler } from './tool_interfaces.js'; | import type { Tool, ToolHandler } from './tool_interfaces.js'; | ||||||
| import log from '../../log.js'; | import log from '../../log.js'; | ||||||
| import becca from '../../../becca/becca.js'; | import becca from '../../../becca/becca.js'; | ||||||
|  | import notes from '../../notes.js'; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Definition of the note update tool |  * Definition of the note update tool | ||||||
| @ -79,7 +80,10 @@ export class NoteUpdateTool implements ToolHandler { | |||||||
|                 const titleStartTime = Date.now(); |                 const titleStartTime = Date.now(); | ||||||
| 
 | 
 | ||||||
|                 try { |                 try { | ||||||
|                     await note.setTitle(title); |                     // Update the note title by setting it and saving
 | ||||||
|  |                     note.title = title; | ||||||
|  |                     note.save(); | ||||||
|  | 
 | ||||||
|                     const titleDuration = Date.now() - titleStartTime; |                     const titleDuration = Date.now() - titleStartTime; | ||||||
|                     log.info(`Updated note title to "${title}" in ${titleDuration}ms`); |                     log.info(`Updated note title to "${title}" in ${titleDuration}ms`); | ||||||
|                     titleUpdateResult = `Title updated from "${note.title}" to "${title}"`; |                     titleUpdateResult = `Title updated from "${note.title}" to "${title}"`; | ||||||
|  | |||||||
| @ -194,23 +194,27 @@ export class RelationshipTool implements ToolHandler { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // Get incoming relationships (where this note is the target)
 |             // Get incoming relationships (where this note is the target)
 | ||||||
|             const incomingNotes = becca.findNotesWithRelation(sourceNote.noteId); |             // Since becca.findNotesWithRelation doesn't exist, use attributes to find notes with relation
 | ||||||
|             const incomingRelations = []; |             const incomingRelations = []; | ||||||
| 
 | 
 | ||||||
|             for (const sourceOfRelation of incomingNotes) { |             // Find all attributes of type relation that point to this note
 | ||||||
|                 const incomingAttributes = sourceOfRelation.getOwnedAttributes() |             const relationAttributes = sourceNote.getTargetRelations(); | ||||||
|                     .filter((attr: any) => attr.type === 'relation' && attr.value === sourceNote.noteId); |  | ||||||
| 
 | 
 | ||||||
|                 for (const attr of incomingAttributes) { |             for (const attr of relationAttributes) { | ||||||
|                     incomingRelations.push({ |                 if (attr.type === 'relation') { | ||||||
|                         relationName: attr.name, |                     const sourceOfRelation = attr.getNote(); | ||||||
|                         sourceNoteId: sourceOfRelation.noteId, |  | ||||||
|                         sourceTitle: sourceOfRelation.title |  | ||||||
|                     }); |  | ||||||
|                 } |  | ||||||
| 
 | 
 | ||||||
|                 if (incomingRelations.length >= limit) { |                     if (sourceOfRelation && !sourceOfRelation.isDeleted) { | ||||||
|                     break; |                         incomingRelations.push({ | ||||||
|  |                             relationName: attr.name, | ||||||
|  |                             sourceNoteId: sourceOfRelation.noteId, | ||||||
|  |                             sourceTitle: sourceOfRelation.title | ||||||
|  |                         }); | ||||||
|  | 
 | ||||||
|  |                         if (incomingRelations.length >= limit) { | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 perf3ct
						perf3ct