noteconnection 1.7.0 → 1.9.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/LICENSE +674 -21
- package/README.md +260 -1626
- package/dist/src/agent_workspace.contract.parity.test.js +159 -0
- package/dist/src/agent_workspace.frontend.test.js +10388 -0
- package/dist/src/agent_workspace.locale.contract.test.js +95 -0
- package/dist/src/agent_workspace.runtime.behavior.test.js +5072 -0
- package/dist/src/android.knowledgebase.picker.contract.test.js +102 -0
- package/dist/src/appimage.patchelf.test.js +113 -0
- package/dist/src/appimage.portability.test.js +156 -0
- package/dist/src/backend/FileLoader.js +18 -4
- package/dist/src/backend/FileLoader.test.js +125 -0
- package/dist/src/backend/GraphBuilder.identity.test.js +86 -0
- package/dist/src/backend/GraphBuilder.js +66 -18
- package/dist/src/backend/GraphBuilder.matching.test.js +127 -0
- package/dist/src/backend/GraphMetrics.js +0 -3
- package/dist/src/backend/ResourceIdentity.js +155 -0
- package/dist/src/backend/ResourceIdentity.test.js +113 -0
- package/dist/src/backend/algorithms/CycleDetection.js +0 -1
- package/dist/src/backend/algorithms/HybridEngine.js +0 -3
- package/dist/src/backend/algorithms/LayoutEngine.js +0 -1
- package/dist/src/backend/algorithms/StatisticalAnalyzer.js +0 -4
- package/dist/src/backend/algorithms/TopologicalSort.js +0 -2
- package/dist/src/backend/build_dag.js +0 -1
- package/dist/src/capacitor.bridge.serialization.contract.test.js +3 -0
- package/dist/src/capacitor.runtime.contract.test.js +11 -2
- package/dist/src/copy.assets.contract.test.js +130 -0
- package/dist/src/core/Graph.js +138 -42
- package/dist/src/core/Graph.test.js +74 -0
- package/dist/src/core/NoteConnection.js +2 -2
- package/dist/src/core/PathBridge.js +293 -5
- package/dist/src/core/ResourceReference.js +17 -0
- package/dist/src/desktop.godot.pack.test.js +142 -0
- package/dist/src/desktop.runtime.graph.test.js +66 -0
- package/dist/src/export/WorkspaceExportBundle.js +1174 -0
- package/dist/src/export/WorkspaceExportBundle.test.js +1541 -0
- package/dist/src/export/index.js +18 -0
- package/dist/src/export/types.js +2 -0
- package/dist/src/fixrisk.issue.verifier.contract.test.js +3 -1
- package/dist/src/foundation.ann.runtime.contract.test.js +81 -0
- package/dist/src/foundation.release.evidence.contract.test.js +524 -0
- package/dist/src/foundation.sqlite.runtime.contract.test.js +88 -0
- package/dist/src/frontend/README.md +260 -1626
- package/dist/src/frontend/agent_workspace.js +6011 -0
- package/dist/src/frontend/agent_workspace_runtime.js +4434 -0
- package/dist/src/frontend/analysis.js +31 -4
- package/dist/src/frontend/app.js +2178 -62
- package/dist/src/frontend/focus_mode_interactions.js +33 -0
- package/dist/src/frontend/godot_future_path_renderer.js +540 -0
- package/dist/src/frontend/godot_tree_interactions.js +178 -0
- package/dist/src/frontend/graph_state.mjs +105 -0
- package/dist/src/frontend/hosted_future_path_runtime.js +157 -0
- package/dist/src/frontend/i18n.mjs +186 -0
- package/dist/src/frontend/index.html +672 -268
- package/dist/src/frontend/knowledge_projection_contract.js +230 -0
- package/dist/src/frontend/knowledge_projection_store.js +214 -0
- package/dist/src/frontend/layout_gpu.js +12 -4
- package/dist/src/frontend/libs/path_core.js +158 -42
- package/dist/src/frontend/locales/en.json +753 -5
- package/dist/src/frontend/locales/zh.json +753 -5
- package/dist/src/frontend/main.mjs +60 -0
- package/dist/src/frontend/markdown_runtime.js +827 -0
- package/dist/src/frontend/mobile_budget_runtime.js +33 -0
- package/dist/src/frontend/mobile_exact_analyzer.js +393 -0
- package/dist/src/frontend/mobile_identity_contract.js +221 -0
- package/dist/src/frontend/mobile_semantic_comparator.js +264 -0
- package/dist/src/frontend/notemd.css +49 -0
- package/dist/src/frontend/notemd.html +7 -1
- package/dist/src/frontend/notemd.js +64 -0
- package/dist/src/frontend/path.html +113 -2
- package/dist/src/frontend/path_app.js +2108 -130
- package/dist/src/frontend/path_layout.mjs +143 -0
- package/dist/src/frontend/path_mermaid_utils.mjs +108 -0
- package/dist/src/frontend/path_modules_bridge.js +486 -0
- package/dist/src/frontend/path_state.mjs +118 -0
- package/dist/src/frontend/path_styles.css +146 -0
- package/dist/src/frontend/path_worker_bridge.mjs +85 -0
- package/dist/src/frontend/reader.js +393 -33
- package/dist/src/frontend/runtime_bridge.js +67 -54
- package/dist/src/frontend/runtime_bridge.mjs +279 -0
- package/dist/src/frontend/settings.js +130 -12
- package/dist/src/frontend/simulationWorker.js +1 -1
- package/dist/src/frontend/source_manager.js +297 -22
- package/dist/src/frontend/storage_provider.js +661 -71
- package/dist/src/frontend/styles.css +2814 -72
- package/dist/src/frontend/workbench_state.mjs +101 -0
- package/dist/src/frontend/workspace_panes.js +10272 -0
- package/dist/src/frontend.locale.contract.test.js +62 -0
- package/dist/src/frontend.runtime.assets.contract.test.js +81 -0
- package/dist/src/godot.sidecar.bootstrap.contract.test.js +244 -0
- package/dist/src/graph.answer.operator.contract.test.js +72 -0
- package/dist/src/index.js +6 -2
- package/dist/src/index.knowledge-root.test.js +118 -0
- package/dist/src/indexing/IndexLifecycle.js +217 -0
- package/dist/src/indexing/IndexLifecycle.test.js +73 -0
- package/dist/src/indexing/SegmentBuilder.js +64 -0
- package/dist/src/indexing/UnitBuilder.js +48 -0
- package/dist/src/indexing/types.js +2 -0
- package/dist/src/knowledge.api.contract.test.js +172 -0
- package/dist/src/knowledge_projection.contract.test.js +134 -0
- package/dist/src/knowledge_projection_store.test.js +200 -0
- package/dist/src/learning/AnswerQualityEvaluation.js +153 -0
- package/dist/src/learning/AnswerQualityEvaluation.test.js +118 -0
- package/dist/src/learning/KnowledgeLearningPlatform.js +11181 -0
- package/dist/src/learning/KnowledgeLearningPlatform.persistence.test.js +745 -0
- package/dist/src/learning/KnowledgeLearningPlatform.program-f.test.js +99 -0
- package/dist/src/learning/KnowledgeLearningPlatform.test.js +3208 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.js +2998 -0
- package/dist/src/learning/KnowledgeWorkspaceConversationRegression.test.js +3936 -0
- package/dist/src/learning/MeasurementEvidenceConflicts.test.js +78 -0
- package/dist/src/learning/PublicAnswerContract.test.js +85 -0
- package/dist/src/learning/PublicEvidenceSelection.test.js +94 -0
- package/dist/src/learning/PublicMeasurementDisclosure.test.js +54 -0
- package/dist/src/learning/agentConversationExecution.js +211 -0
- package/dist/src/learning/agentConversationExecution.test.js +209 -0
- package/dist/src/learning/agentConversationSerialization.js +266 -0
- package/dist/src/learning/agentConversationSerialization.test.js +165 -0
- package/dist/src/learning/agentResponseBudget.js +179 -0
- package/dist/src/learning/agentResponseBudget.test.js +97 -0
- package/dist/src/learning/agentWorkspaceCapabilityContracts.js +65 -0
- package/dist/src/learning/answerReleaseReview.js +5260 -0
- package/dist/src/learning/answerReleaseReview.test.js +4174 -0
- package/dist/src/learning/answerTaskPlan.js +473 -0
- package/dist/src/learning/api.js +2 -0
- package/dist/src/learning/conversationComposer.js +1721 -0
- package/dist/src/learning/conversationComposer.test.js +3220 -0
- package/dist/src/learning/domains/ConversationManager.js +53 -0
- package/dist/src/learning/domains/KnowledgeIngestor.js +238 -0
- package/dist/src/learning/domains/KnowledgeQuerier.js +187 -0
- package/dist/src/learning/domains/MasteryEngine.js +387 -0
- package/dist/src/learning/domains/MemoryPolicyManager.js +408 -0
- package/dist/src/learning/domains/QualityEvaluator.js +307 -0
- package/dist/src/learning/domains/TutorRouter.js +313 -0
- package/dist/src/learning/domains/index.js +33 -0
- package/dist/src/learning/domains/types.js +7 -0
- package/dist/src/learning/errors.js +29 -0
- package/dist/src/learning/evidenceContextAssembler.js +1368 -0
- package/dist/src/learning/evidenceContextAssembler.test.js +6332 -0
- package/dist/src/learning/graphAnswerCoverage.js +37 -0
- package/dist/src/learning/graphAnswerCoverage.test.js +93 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.js +59 -0
- package/dist/src/learning/graphAnswerCoverageCalibration.test.js +46 -0
- package/dist/src/learning/graphAnswerFacts.js +94 -0
- package/dist/src/learning/graphAnswerFacts.test.js +39 -0
- package/dist/src/learning/graphAnswerPlan.js +908 -0
- package/dist/src/learning/graphAnswerPlan.test.js +907 -0
- package/dist/src/learning/graphAnswerQualityCalibration.js +255 -0
- package/dist/src/learning/graphAnswerQualityCalibration.test.js +72 -0
- package/dist/src/learning/graphAnswerQualityPolicy.js +30 -0
- package/dist/src/learning/graphClaimMatcher.js +104 -0
- package/dist/src/learning/graphConditionedContext.js +109 -0
- package/dist/src/learning/graphConditionedContext.test.js +99 -0
- package/dist/src/learning/graphContextAssembler.js +860 -0
- package/dist/src/learning/graphContextAssembler.test.js +1033 -0
- package/dist/src/learning/graphExpansionPolicy.js +22 -0
- package/dist/src/learning/graphExpansionPolicy.test.js +33 -0
- package/dist/src/learning/identityMetadata.test.js +26 -0
- package/dist/src/learning/index.js +29 -0
- package/dist/src/learning/mobileAnswerProjection.js +104 -0
- package/dist/src/learning/mobileAnswerProjection.test.js +102 -0
- package/dist/src/learning/queryBackend.js +1922 -0
- package/dist/src/learning/queryBackend.test.js +976 -0
- package/dist/src/learning/ragContextPack.js +356 -0
- package/dist/src/learning/ragContextPack.test.js +311 -0
- package/dist/src/learning/ragEvidenceQuality.js +96 -0
- package/dist/src/learning/ragEvidenceQuality.test.js +29 -0
- package/dist/src/learning/ragPublicText.js +101 -0
- package/dist/src/learning/ragPublicText.test.js +57 -0
- package/dist/src/learning/ragSufficiencyJudge.js +171 -0
- package/dist/src/learning/ragSufficiencyJudge.test.js +177 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.js +217 -0
- package/dist/src/learning/ragSufficiencyProviderJudge.test.js +207 -0
- package/dist/src/learning/requestNormalization.js +304 -0
- package/dist/src/learning/requestNormalization.test.js +101 -0
- package/dist/src/learning/runtimeCapability.js +4677 -0
- package/dist/src/learning/runtimeCapability.test.js +3635 -0
- package/dist/src/learning/store.js +1344 -0
- package/dist/src/learning/store.test.js +1425 -0
- package/dist/src/learning/tutorAdapter.js +2 -0
- package/dist/src/learning/types.js +2 -0
- package/dist/src/learning/vectorAccelerationAdapter.js +958 -0
- package/dist/src/learning/vectorAccelerationAdapter.test.js +412 -0
- package/dist/src/learning/workspaceHydration.js +168 -0
- package/dist/src/learning/workspaceHydration.test.js +30 -0
- package/dist/src/lfs.asset.policy.contract.test.js +153 -0
- package/dist/src/license.policy.contract.test.js +71 -0
- package/dist/src/markdown/MarkdownGateway.js +4 -0
- package/dist/src/markdown/MarkdownGateway.test.js +59 -0
- package/dist/src/memory/MemoryGovernance.js +74 -0
- package/dist/src/memory/MemoryGovernance.test.js +46 -0
- package/dist/src/memory/types.js +2 -0
- package/dist/src/mermaid.frontend.guard.contract.test.js +77 -0
- package/dist/src/middleware/SseResponseWriter.js +122 -0
- package/dist/src/middleware/SseResponseWriter.test.js +54 -0
- package/dist/src/middleware/auth.js +38 -0
- package/dist/src/middleware/auth.test.js +33 -0
- package/dist/src/middleware/body-parser.js +45 -0
- package/dist/src/middleware/cors.js +44 -0
- package/dist/src/middleware/index.js +22 -0
- package/dist/src/middleware/request-trace.js +96 -0
- package/dist/src/mobile.android.evidence.contract.test.js +146 -0
- package/dist/src/mobile.android.signing.contract.test.js +66 -0
- package/dist/src/mobile.artifact.contract.test.js +144 -0
- package/dist/src/mobile.budget.contract.test.js +90 -0
- package/dist/src/mobile.canonical-id.readiness.test.js +54 -0
- package/dist/src/mobile.graph.parity.contract.test.js +207 -0
- package/dist/src/mobile.identity.contract.test.js +66 -0
- package/dist/src/mobile.identity.corpus.manifest.test.js +72 -0
- package/dist/src/mobile.identity.corpus.test.js +40 -0
- package/dist/src/mobile.native.recovery.contract.test.js +64 -0
- package/dist/src/mobile.pipeline.test.js +11 -1
- package/dist/src/mobile.profile.contract.test.js +225 -0
- package/dist/src/mobile.semantic.parity.test.js +92 -0
- package/dist/src/mobile_exact_analyzer.test.js +113 -0
- package/dist/src/notemd/AppConfigToml.js +6 -4
- package/dist/src/notemd/ContentGenerator.js +4 -9
- package/dist/src/notemd/FileProcessor.js +4 -9
- package/dist/src/notemd/MermaidProcessor.js +400 -50
- package/dist/src/notemd/NotemdService.js +506 -26
- package/dist/src/notemd/PromptManager.js +15 -0
- package/dist/src/notemd/Translator.js +4 -9
- package/dist/src/notemd/cli/commands.js +357 -0
- package/dist/src/notemd/cli/dispatcher.js +225 -0
- package/dist/src/notemd/cli/index.js +169 -0
- package/dist/src/notemd/cli/parser.js +68 -0
- package/dist/src/notemd/cli/types.js +2 -0
- package/dist/src/notemd/constants.js +43 -0
- package/dist/src/notemd/diagram/diagramGenerationService.js +78 -0
- package/dist/src/notemd/diagram/diagramSpec.js +79 -0
- package/dist/src/notemd/diagram/diagramSpecResponseParser.js +131 -0
- package/dist/src/notemd/diagram/intent.js +95 -0
- package/dist/src/notemd/diagram/planner.js +71 -0
- package/dist/src/notemd/diagram/prompts/diagramSpecPrompt.js +42 -0
- package/dist/src/notemd/diagram/types.js +18 -0
- package/dist/src/notemd/index.js +26 -0
- package/dist/src/notemd/operations/capabilityManifest.js +23 -0
- package/dist/src/notemd/operations/cliContracts.js +17 -0
- package/dist/src/notemd/operations/configProfileCommands.js +85 -0
- package/dist/src/notemd/operations/registry.contract.test.js +95 -0
- package/dist/src/notemd/operations/registry.js +991 -0
- package/dist/src/notemd/operations/types.js +2 -0
- package/dist/src/notemd/progressReporter.js +9 -0
- package/dist/src/notemd/providerDiagnostics.js +220 -0
- package/dist/src/notemd/providerProfiles.js +42 -0
- package/dist/src/notemd/providerTemplates.js +231 -0
- package/dist/src/notemd/search/DuckDuckGoProvider.js +39 -0
- package/dist/src/notemd/search/SearchManager.js +13 -0
- package/dist/src/notemd/search/SearchProvider.js +2 -0
- package/dist/src/notemd/search/TavilyProvider.js +44 -0
- package/dist/src/notemd.agent.manifest.test.js +85 -0
- package/dist/src/notemd.api.contract.test.js +14 -1
- package/dist/src/notemd.app_config_toml.test.js +2 -1
- package/dist/src/notemd.batch.workflow.test.js +117 -0
- package/dist/src/notemd.cli.e2e.test.js +136 -0
- package/dist/src/notemd.core.test.js +51 -0
- package/dist/src/notemd.diagram.pipeline.test.js +233 -0
- package/dist/src/notemd.providerTemplates.test.js +34 -0
- package/dist/src/notemd.server.integration.test.js +262 -39
- package/dist/src/notemd.workflow.pipeline.test.js +162 -0
- package/dist/src/pathbridge.handshake.contract.test.js +45 -2
- package/dist/src/pathbridge.host-adapter.contract.test.js +133 -0
- package/dist/src/pathcore.bundle.contract.test.js +8 -0
- package/dist/src/pathmode.background.contract.test.js +69 -0
- package/dist/src/pathmode.settings.api.contract.test.js +9 -0
- package/dist/src/pkg.sidecar.contract.test.js +9 -3
- package/dist/src/platform/ExportProfile.js +86 -0
- package/dist/src/platform/MobileBudget.js +11 -0
- package/dist/src/platform/PlatformCapabilities.js +59 -0
- package/dist/src/platform/PlatformCapabilities.test.js +36 -0
- package/dist/src/platform/RenderMaterializer.js +33 -0
- package/dist/src/platform/RenderMaterializer.test.js +32 -0
- package/dist/src/query_backend.external_http.integration.test.js +410 -0
- package/dist/src/reader_renderer.js +404 -3
- package/dist/src/reader_renderer.test.js +87 -0
- package/dist/src/release.godot.mirror.contract.test.js +97 -0
- package/dist/src/resources/ResourceRegistry.js +263 -0
- package/dist/src/resources/ResourceRegistry.test.js +97 -0
- package/dist/src/resources/types.js +2 -0
- package/dist/src/routes/agentWorkspaceDiagnostics.js +173 -0
- package/dist/src/routes/index.js +19 -0
- package/dist/src/routes/knowledge.js +981 -0
- package/dist/src/routes/knowledgePayload.js +185 -0
- package/dist/src/routes/knowledgePayload.test.js +53 -0
- package/dist/src/routes/markdown.js +295 -0
- package/dist/src/routes/notemd.js +1321 -0
- package/dist/src/routes/registry.contract.test.js +133 -0
- package/dist/src/routes/registry.shadow.contract.test.js +22 -0
- package/dist/src/routes/render.js +248 -0
- package/dist/src/routes/runtimeRunbookRouteOps.js +149 -0
- package/dist/src/routes/runtimeRunbookRouteOps.test.js +194 -0
- package/dist/src/routes/settings.js +6 -0
- package/dist/src/routes/staticFiles.js +94 -0
- package/dist/src/routes/types.js +2 -0
- package/dist/src/runtime.capabilities.test.js +18 -2
- package/dist/src/runtime.transport.adapter.contract.test.js +81 -0
- package/dist/src/server.js +10342 -1325
- package/dist/src/server.migration.test.js +584 -10
- package/dist/src/server.port.fallback.contract.test.js +63 -0
- package/dist/src/session/SessionStateStore.js +81 -0
- package/dist/src/session/SessionStateStore.test.js +58 -0
- package/dist/src/session/types.js +2 -0
- package/dist/src/settings.runtime.contract.test.js +50 -0
- package/dist/src/shared/types.contract.test.js +107 -0
- package/dist/src/shared/types.js +22 -0
- package/dist/src/sidecar.build.lock.contract.test.js +201 -0
- package/dist/src/sidecar.freshness.contract.test.js +184 -0
- package/dist/src/sidecar.replacement.boundary.contract.test.js +131 -0
- package/dist/src/sidecar.supply.readiness.contract.test.js +155 -0
- package/dist/src/simulation.worker.offline.test.js +104 -0
- package/dist/src/source_manager.loadflow.test.js +46 -0
- package/dist/src/startup.layout.snapshot.contract.test.js +57 -0
- package/dist/src/storage.provider.capacitor.content.contract.test.js +4 -1
- package/dist/src/storage.provider.contract.test.js +152 -1
- package/dist/src/tauri.frontend.build.contract.test.js +68 -0
- package/dist/src/tauri.sidecar.cleanup.contract.test.js +21 -0
- package/dist/src/tauri.window.evidence.execution.test.js +68 -0
- package/dist/src/utils/RuntimePaths.js +10 -13
- package/dist/src/utils/RuntimePaths.test.js +27 -0
- package/dist/src/utils/platform.js +153 -0
- package/dist/src/windows.installer.build.test.js +109 -0
- package/dist/src/windows.installer.payload.test.js +76 -0
- package/dist/src/windows.installer.runtime.test.js +69 -0
- package/dist/src/workflows/WorkflowArtifactStore.js +96 -0
- package/dist/src/workflows/WorkflowArtifactStore.test.js +80 -0
- package/dist/src/workflows/types.js +2 -0
- package/dist/src/workspace/WorkspaceRegistry.js +135 -0
- package/dist/src/workspace/WorkspaceRegistry.test.js +29 -0
- package/dist/src/workspace/types.js +2 -0
- package/package.json +80 -15
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
(function attachKnowledgeProjectionContract(root, factory) {
|
|
2
|
+
const api = factory();
|
|
3
|
+
if (typeof module === 'object' && module.exports) {
|
|
4
|
+
module.exports = api;
|
|
5
|
+
}
|
|
6
|
+
if (root) {
|
|
7
|
+
root.NoteConnectionKnowledgeProjection = api;
|
|
8
|
+
}
|
|
9
|
+
}(typeof globalThis !== 'undefined' ? globalThis : this, function createKnowledgeProjectionContract() {
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const SCHEMA_VERSION = 1;
|
|
13
|
+
const MAX_NODES = 50000;
|
|
14
|
+
const MAX_EDGES = 250000;
|
|
15
|
+
const MAX_NEIGHBORS = 64;
|
|
16
|
+
const MAX_EVIDENCE_REFS = 8;
|
|
17
|
+
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function cleanString(value) {
|
|
23
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function cleanStringList(value, fieldName, limit) {
|
|
27
|
+
if (value === undefined || value === null) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
if (!Array.isArray(value)) {
|
|
31
|
+
throw new Error(`${fieldName} must be an array when provided.`);
|
|
32
|
+
}
|
|
33
|
+
const values = Array.from(new Set(value.map(cleanString).filter(Boolean)));
|
|
34
|
+
if (values.length > limit) {
|
|
35
|
+
throw new Error(`${fieldName} exceeds the bounded limit of ${limit}.`);
|
|
36
|
+
}
|
|
37
|
+
return values;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function classifyEdgeKind(rawType, rawKind) {
|
|
41
|
+
const kind = cleanString(rawKind).toLowerCase();
|
|
42
|
+
if (kind === 'explicit' || kind === 'inferred' || kind === 'runtime') {
|
|
43
|
+
return kind;
|
|
44
|
+
}
|
|
45
|
+
const type = cleanString(rawType).toLowerCase();
|
|
46
|
+
if (type.includes('inferred') || type.includes('keyword') || type.includes('vector') || type.includes('statistical')) {
|
|
47
|
+
return 'inferred';
|
|
48
|
+
}
|
|
49
|
+
if (type === 'runtime' || type.includes('runtime')) {
|
|
50
|
+
return 'runtime';
|
|
51
|
+
}
|
|
52
|
+
return 'explicit';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function assertSupportedVersion(value) {
|
|
56
|
+
const version = value === undefined || value === null ? SCHEMA_VERSION : Number(value);
|
|
57
|
+
if (!Number.isInteger(version) || version < 1 || version > SCHEMA_VERSION) {
|
|
58
|
+
throw new Error(`Unsupported knowledge projection schema version: ${String(value)}.`);
|
|
59
|
+
}
|
|
60
|
+
return version;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function normalizeNode(rawNode, maxEvidenceRefs) {
|
|
64
|
+
if (!isRecord(rawNode)) {
|
|
65
|
+
throw new Error('Knowledge projection nodes must be objects.');
|
|
66
|
+
}
|
|
67
|
+
const id = cleanString(rawNode.id);
|
|
68
|
+
if (!id) {
|
|
69
|
+
throw new Error('Knowledge projection node id must be non-empty.');
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
id,
|
|
73
|
+
canonicalId: cleanString(rawNode.canonicalId),
|
|
74
|
+
label: cleanString(rawNode.label) || id,
|
|
75
|
+
sourceUri: cleanString(rawNode.sourceUri),
|
|
76
|
+
revision: cleanString(rawNode.revision),
|
|
77
|
+
identityAliases: cleanStringList(rawNode.identityAliases, `node ${id}.identityAliases`, 16),
|
|
78
|
+
evidenceRefs: cleanStringList(rawNode.evidenceRefs, `node ${id}.evidenceRefs`, maxEvidenceRefs),
|
|
79
|
+
tags: cleanStringList(rawNode.tags || (rawNode.metadata && rawNode.metadata.tags), `node ${id}.tags`, 32),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function normalizeEdge(rawEdge, nodeById, maxEvidenceRefs) {
|
|
84
|
+
if (!isRecord(rawEdge)) {
|
|
85
|
+
throw new Error('Knowledge projection edges must be objects.');
|
|
86
|
+
}
|
|
87
|
+
const source = cleanString(rawEdge.source || rawEdge.from);
|
|
88
|
+
const target = cleanString(rawEdge.target || rawEdge.to);
|
|
89
|
+
if (!source || !target || source === target || !nodeById.has(source) || !nodeById.has(target)) {
|
|
90
|
+
throw new Error(`Knowledge projection edge references an invalid node: ${source || '?'} -> ${target || '?'}.`);
|
|
91
|
+
}
|
|
92
|
+
const type = cleanString(rawEdge.type) || 'association';
|
|
93
|
+
const confidence = Number(rawEdge.confidence ?? rawEdge.weight);
|
|
94
|
+
const sourceNode = nodeById.get(source);
|
|
95
|
+
const targetNode = nodeById.get(target);
|
|
96
|
+
return {
|
|
97
|
+
source,
|
|
98
|
+
target,
|
|
99
|
+
sourceUri: cleanString(rawEdge.sourceUri) || sourceNode.sourceUri,
|
|
100
|
+
targetUri: cleanString(rawEdge.targetUri) || targetNode.sourceUri,
|
|
101
|
+
type,
|
|
102
|
+
kind: classifyEdgeKind(type, rawEdge.kind),
|
|
103
|
+
provenance: cleanString(rawEdge.provenance) || type,
|
|
104
|
+
confidence: Number.isFinite(confidence) ? Math.max(0, Math.min(1, confidence)) : 1,
|
|
105
|
+
evidenceRefs: cleanStringList(rawEdge.evidenceRefs, `edge ${source}->${target}.evidenceRefs`, maxEvidenceRefs),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function buildAdjacency(nodes, edges, maxNeighbors) {
|
|
110
|
+
const adjacency = new Map(nodes.map((node) => [node.id, { outgoing: [], incoming: [] }]));
|
|
111
|
+
edges.forEach((edge) => {
|
|
112
|
+
const source = adjacency.get(edge.source);
|
|
113
|
+
const target = adjacency.get(edge.target);
|
|
114
|
+
if (source.outgoing.length < maxNeighbors && !source.outgoing.includes(edge.target)) {
|
|
115
|
+
source.outgoing.push(edge.target);
|
|
116
|
+
}
|
|
117
|
+
if (target.incoming.length < maxNeighbors && !target.incoming.includes(edge.source)) {
|
|
118
|
+
target.incoming.push(edge.source);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
return Array.from(adjacency, ([nodeId, value]) => ({ nodeId, ...value }));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function normalizeProjection(rawProjection, options) {
|
|
125
|
+
if (!isRecord(rawProjection)) {
|
|
126
|
+
throw new Error('Knowledge projection must be an object.');
|
|
127
|
+
}
|
|
128
|
+
const maxNodes = Math.min(MAX_NODES, Math.max(1, Number(options && options.maxNodes) || MAX_NODES));
|
|
129
|
+
const maxEdges = Math.min(MAX_EDGES, Math.max(1, Number(options && options.maxEdges) || MAX_EDGES));
|
|
130
|
+
const maxNeighbors = Math.min(MAX_NEIGHBORS, Math.max(1, Number(options && options.maxNeighbors) || MAX_NEIGHBORS));
|
|
131
|
+
const maxEvidenceRefs = MAX_EVIDENCE_REFS;
|
|
132
|
+
const declaredSchemaVersion = rawProjection.schemaVersion !== undefined
|
|
133
|
+
? rawProjection.schemaVersion
|
|
134
|
+
: rawProjection.projectionVersion;
|
|
135
|
+
const schemaVersion = assertSupportedVersion(declaredSchemaVersion);
|
|
136
|
+
const rawNodes = Array.isArray(rawProjection.nodes) ? rawProjection.nodes : [];
|
|
137
|
+
const rawEdges = Array.isArray(rawProjection.edges) ? rawProjection.edges : [];
|
|
138
|
+
if (rawNodes.length > maxNodes || rawEdges.length > maxEdges) {
|
|
139
|
+
throw new Error(`Knowledge projection exceeds bounded size: ${rawNodes.length} nodes / ${rawEdges.length} edges.`);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const nodes = rawNodes.map((node) => normalizeNode(node, maxEvidenceRefs));
|
|
143
|
+
const nodeIds = new Set();
|
|
144
|
+
const normalizedIds = new Set();
|
|
145
|
+
const canonicalIds = new Set();
|
|
146
|
+
nodes.forEach((node) => {
|
|
147
|
+
const normalizedId = node.id.normalize ? node.id.normalize('NFC').toLowerCase() : node.id.toLowerCase();
|
|
148
|
+
if (nodeIds.has(node.id) || normalizedIds.has(normalizedId)) {
|
|
149
|
+
throw new Error(`Knowledge projection contains a duplicate node id: ${node.id}.`);
|
|
150
|
+
}
|
|
151
|
+
nodeIds.add(node.id);
|
|
152
|
+
normalizedIds.add(normalizedId);
|
|
153
|
+
if (node.canonicalId) {
|
|
154
|
+
const normalizedCanonicalId = node.canonicalId.normalize
|
|
155
|
+
? node.canonicalId.normalize('NFC').toLowerCase()
|
|
156
|
+
: node.canonicalId.toLowerCase();
|
|
157
|
+
if (canonicalIds.has(normalizedCanonicalId)
|
|
158
|
+
|| (normalizedCanonicalId !== normalizedId && normalizedIds.has(normalizedCanonicalId))) {
|
|
159
|
+
throw new Error(`Knowledge projection contains a duplicate canonical node id: ${node.canonicalId}.`);
|
|
160
|
+
}
|
|
161
|
+
canonicalIds.add(normalizedCanonicalId);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const edgeKeys = new Set();
|
|
166
|
+
const nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
167
|
+
const edges = rawEdges.map((edge) => normalizeEdge(edge, nodeById, maxEvidenceRefs))
|
|
168
|
+
.filter((edge) => {
|
|
169
|
+
// Preserve distinct provenance for the same directed endpoints.
|
|
170
|
+
// Collapsing by kind loses whether a link was explicit-next, wiki, or markdown.
|
|
171
|
+
const key = `${edge.source}->${edge.target}:${edge.kind}:${edge.type}:${edge.provenance}`;
|
|
172
|
+
if (edgeKeys.has(key)) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
edgeKeys.add(key);
|
|
176
|
+
return true;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
schemaVersion,
|
|
181
|
+
projectionVersion: schemaVersion,
|
|
182
|
+
workspaceId: cleanString(rawProjection.workspaceId) || 'workspace',
|
|
183
|
+
revision: cleanString(rawProjection.revision),
|
|
184
|
+
nodes,
|
|
185
|
+
edges,
|
|
186
|
+
adjacency: buildAdjacency(nodes, edges, maxNeighbors),
|
|
187
|
+
extensions: isRecord(rawProjection.extensions) ? rawProjection.extensions : {},
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function createKnowledgeProjection(graph, options) {
|
|
192
|
+
if (!isRecord(graph)) {
|
|
193
|
+
throw new Error('Knowledge graph payload must be an object.');
|
|
194
|
+
}
|
|
195
|
+
const projectionOptions = isRecord(options) ? options : {};
|
|
196
|
+
return normalizeProjection({
|
|
197
|
+
...graph,
|
|
198
|
+
schemaVersion: graph.schemaVersion !== undefined
|
|
199
|
+
? graph.schemaVersion
|
|
200
|
+
: (graph.projectionVersion !== undefined ? graph.projectionVersion : SCHEMA_VERSION),
|
|
201
|
+
workspaceId: projectionOptions.workspaceId !== undefined
|
|
202
|
+
? projectionOptions.workspaceId
|
|
203
|
+
: graph.workspaceId,
|
|
204
|
+
revision: projectionOptions.revision !== undefined
|
|
205
|
+
? projectionOptions.revision
|
|
206
|
+
: graph.revision,
|
|
207
|
+
}, projectionOptions);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function replayKnowledgeProjection(serialized, options) {
|
|
211
|
+
let payload = serialized;
|
|
212
|
+
if (typeof serialized === 'string') {
|
|
213
|
+
try {
|
|
214
|
+
payload = JSON.parse(serialized);
|
|
215
|
+
} catch (error) {
|
|
216
|
+
throw new Error(`Knowledge projection JSON is invalid: ${String(error && error.message || error)}.`);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return normalizeProjection(payload, options);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return Object.freeze({
|
|
223
|
+
schemaVersion: SCHEMA_VERSION,
|
|
224
|
+
limits: Object.freeze({ maxNodes: MAX_NODES, maxEdges: MAX_EDGES, maxNeighbors: MAX_NEIGHBORS, maxEvidenceRefs: MAX_EVIDENCE_REFS }),
|
|
225
|
+
classifyEdgeKind,
|
|
226
|
+
normalizeProjection,
|
|
227
|
+
createKnowledgeProjection,
|
|
228
|
+
replayKnowledgeProjection,
|
|
229
|
+
});
|
|
230
|
+
}));
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
(function attachKnowledgeProjectionStore(root, factory) {
|
|
2
|
+
const api = factory(root && root.NoteConnectionKnowledgeProjection);
|
|
3
|
+
if (typeof module === 'object' && module.exports) {
|
|
4
|
+
module.exports = api;
|
|
5
|
+
}
|
|
6
|
+
if (root) {
|
|
7
|
+
root.NoteConnectionKnowledgeProjectionStore = api;
|
|
8
|
+
}
|
|
9
|
+
}(typeof globalThis !== 'undefined' ? globalThis : this, function createProjectionStoreApi(projectionContract) {
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const STORE_VERSION = 1;
|
|
13
|
+
const FALLBACK_MAX_BYTES = 48 * 1024 * 1024;
|
|
14
|
+
|
|
15
|
+
function defaultMaxBytes() {
|
|
16
|
+
const root = typeof globalThis !== 'undefined' ? globalThis : null;
|
|
17
|
+
const runtime = root && root.NoteConnectionMobileBudget && root.NoteConnectionMobileBudget.runtime;
|
|
18
|
+
return runtime && Number.isInteger(runtime.maxProjectionBytes) && runtime.maxProjectionBytes > 0
|
|
19
|
+
? runtime.maxProjectionBytes
|
|
20
|
+
: FALLBACK_MAX_BYTES;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function requireProjectionContract() {
|
|
24
|
+
if (!projectionContract || typeof projectionContract.replayKnowledgeProjection !== 'function') {
|
|
25
|
+
throw new Error('Knowledge projection contract is unavailable.');
|
|
26
|
+
}
|
|
27
|
+
return projectionContract;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function normalizeProjection(value, options) {
|
|
31
|
+
return requireProjectionContract().replayKnowledgeProjection(value, options);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function measureBytes(value) {
|
|
35
|
+
const text = String(value || '');
|
|
36
|
+
if (typeof TextEncoder === 'function') {
|
|
37
|
+
return new TextEncoder().encode(text).length;
|
|
38
|
+
}
|
|
39
|
+
if (typeof Buffer !== 'undefined' && typeof Buffer.byteLength === 'function') {
|
|
40
|
+
return Buffer.byteLength(text, 'utf8');
|
|
41
|
+
}
|
|
42
|
+
return text.length;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function metadataFor(projection) {
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
schemaVersion: projection.schemaVersion,
|
|
48
|
+
projectionVersion: projection.projectionVersion,
|
|
49
|
+
workspaceId: projection.workspaceId,
|
|
50
|
+
revision: projection.revision,
|
|
51
|
+
nodeCount: projection.nodes.length,
|
|
52
|
+
edgeCount: projection.edges.length,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function createMemoryProjectionStore(initialProjection, options) {
|
|
57
|
+
const normalizedOptions = options && typeof options === 'object' ? options : {};
|
|
58
|
+
let current = initialProjection === undefined || initialProjection === null
|
|
59
|
+
? null
|
|
60
|
+
: normalizeProjection(initialProjection, normalizedOptions);
|
|
61
|
+
|
|
62
|
+
return Object.freeze({
|
|
63
|
+
kind: 'memory',
|
|
64
|
+
async load() {
|
|
65
|
+
return current;
|
|
66
|
+
},
|
|
67
|
+
async save(projection) {
|
|
68
|
+
current = normalizeProjection(projection, normalizedOptions);
|
|
69
|
+
return current;
|
|
70
|
+
},
|
|
71
|
+
async metadata() {
|
|
72
|
+
return current ? metadataFor(current) : null;
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function createPersistentProjectionStore(options) {
|
|
78
|
+
const normalizedOptions = options && typeof options === 'object' ? options : {};
|
|
79
|
+
const read = normalizedOptions.read;
|
|
80
|
+
const write = normalizedOptions.write;
|
|
81
|
+
if (typeof read !== 'function') {
|
|
82
|
+
return createMemoryProjectionStore(normalizedOptions.initialProjection, normalizedOptions);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const maxBytes = Math.max(1024, Math.floor(Number(normalizedOptions.maxBytes) || defaultMaxBytes()));
|
|
86
|
+
let cached = normalizedOptions.initialProjection === undefined || normalizedOptions.initialProjection === null
|
|
87
|
+
? null
|
|
88
|
+
: normalizeProjection(normalizedOptions.initialProjection, normalizedOptions);
|
|
89
|
+
let hasLoaded = false;
|
|
90
|
+
let loadPromise = null;
|
|
91
|
+
|
|
92
|
+
const load = async () => {
|
|
93
|
+
if (hasLoaded && cached) {
|
|
94
|
+
return cached;
|
|
95
|
+
}
|
|
96
|
+
if (loadPromise) {
|
|
97
|
+
return await loadPromise;
|
|
98
|
+
}
|
|
99
|
+
loadPromise = (async () => {
|
|
100
|
+
let payload;
|
|
101
|
+
try {
|
|
102
|
+
payload = await read();
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (cached) {
|
|
105
|
+
return cached;
|
|
106
|
+
}
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
const serialized = typeof payload === 'string' ? payload : JSON.stringify(payload);
|
|
110
|
+
if (typeof serialized !== 'string') {
|
|
111
|
+
throw new Error('Knowledge projection payload is not serializable.');
|
|
112
|
+
}
|
|
113
|
+
if (measureBytes(serialized) > maxBytes) {
|
|
114
|
+
throw new Error(`Knowledge projection payload exceeds ${maxBytes} bytes.`);
|
|
115
|
+
}
|
|
116
|
+
// Validation errors must not be hidden by a stale in-memory value.
|
|
117
|
+
cached = normalizeProjection(payload, normalizedOptions);
|
|
118
|
+
hasLoaded = true;
|
|
119
|
+
return cached;
|
|
120
|
+
})();
|
|
121
|
+
try {
|
|
122
|
+
return await loadPromise;
|
|
123
|
+
} finally {
|
|
124
|
+
loadPromise = null;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return Object.freeze({
|
|
129
|
+
kind: typeof write === 'function' ? 'persistent' : 'read-through',
|
|
130
|
+
load,
|
|
131
|
+
async save(projection) {
|
|
132
|
+
const next = normalizeProjection(projection, normalizedOptions);
|
|
133
|
+
const serialized = JSON.stringify(next);
|
|
134
|
+
if (measureBytes(serialized) > maxBytes) {
|
|
135
|
+
throw new Error(`Knowledge projection payload exceeds ${maxBytes} bytes.`);
|
|
136
|
+
}
|
|
137
|
+
if (typeof write !== 'function') {
|
|
138
|
+
throw new Error('Knowledge projection store is read-only in this runtime.');
|
|
139
|
+
}
|
|
140
|
+
await write(serialized, next);
|
|
141
|
+
cached = next;
|
|
142
|
+
hasLoaded = true;
|
|
143
|
+
return next;
|
|
144
|
+
},
|
|
145
|
+
async metadata() {
|
|
146
|
+
const projection = await load();
|
|
147
|
+
return projection ? metadataFor(projection) : null;
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function createFileProjectionStore(options) {
|
|
153
|
+
const normalizedOptions = options && typeof options === 'object' ? options : {};
|
|
154
|
+
const fileName = typeof normalizedOptions.fileName === 'string'
|
|
155
|
+
? normalizedOptions.fileName.trim()
|
|
156
|
+
: '';
|
|
157
|
+
const readFile = normalizedOptions.readFile;
|
|
158
|
+
const writeAtomic = normalizedOptions.writeAtomic;
|
|
159
|
+
|
|
160
|
+
if (!fileName) {
|
|
161
|
+
throw new Error('App-local projection file name is required.');
|
|
162
|
+
}
|
|
163
|
+
if (typeof readFile !== 'function') {
|
|
164
|
+
throw new Error('App-local projection readFile adapter is required.');
|
|
165
|
+
}
|
|
166
|
+
if (writeAtomic !== undefined && typeof writeAtomic !== 'function') {
|
|
167
|
+
throw new Error('App-local projection writeAtomic adapter must be callable.');
|
|
168
|
+
}
|
|
169
|
+
if (normalizedOptions.write !== undefined) {
|
|
170
|
+
throw new Error('App-local projection writes must use the writeAtomic adapter.');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const persistentOptions = {
|
|
174
|
+
...Object.fromEntries(Object.entries(normalizedOptions).filter(([key]) => (
|
|
175
|
+
key !== 'fileName'
|
|
176
|
+
&& key !== 'readFile'
|
|
177
|
+
&& key !== 'writeAtomic'
|
|
178
|
+
&& key !== 'read'
|
|
179
|
+
&& key !== 'write'
|
|
180
|
+
))),
|
|
181
|
+
read: async () => await readFile(fileName),
|
|
182
|
+
};
|
|
183
|
+
if (typeof writeAtomic === 'function') {
|
|
184
|
+
persistentOptions.write = async (serialized, projection) => {
|
|
185
|
+
await writeAtomic(fileName, serialized, projection);
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const store = createPersistentProjectionStore(persistentOptions);
|
|
190
|
+
return Object.freeze({
|
|
191
|
+
...store,
|
|
192
|
+
kind: typeof writeAtomic === 'function' ? 'file-persistent' : 'file-read-through',
|
|
193
|
+
fileName,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function createProjectionStore(options) {
|
|
198
|
+
const normalizedOptions = options && typeof options === 'object' ? options : {};
|
|
199
|
+
if (typeof normalizedOptions.read === 'function') {
|
|
200
|
+
return createPersistentProjectionStore(normalizedOptions);
|
|
201
|
+
}
|
|
202
|
+
return createMemoryProjectionStore(normalizedOptions.initialProjection, normalizedOptions);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return Object.freeze({
|
|
206
|
+
storeVersion: STORE_VERSION,
|
|
207
|
+
defaultMaxBytes: FALLBACK_MAX_BYTES,
|
|
208
|
+
createProjectionStore,
|
|
209
|
+
createMemoryProjectionStore,
|
|
210
|
+
createPersistentProjectionStore,
|
|
211
|
+
createFileProjectionStore,
|
|
212
|
+
metadataFor,
|
|
213
|
+
});
|
|
214
|
+
}));
|
|
@@ -232,7 +232,17 @@ class GPULinkForce {
|
|
|
232
232
|
const nLinks = this._links.length;
|
|
233
233
|
console.log(`[GPULink] Initializing for ${n} nodes, ${nLinks} links.`);
|
|
234
234
|
|
|
235
|
-
if (
|
|
235
|
+
if (this.kernel) {
|
|
236
|
+
this.kernel.destroy();
|
|
237
|
+
this.kernel = null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (n === 0 || nLinks === 0) {
|
|
241
|
+
this.adjHead = new Float32Array(n);
|
|
242
|
+
this.adjCount = new Float32Array(n);
|
|
243
|
+
this.flatIndices = new Float32Array(0);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
236
246
|
|
|
237
247
|
// Build Adjacency List (Source <-> Target)
|
|
238
248
|
// D3 Link Force is symmetric: force acts on both ends.
|
|
@@ -295,8 +305,6 @@ class GPULinkForce {
|
|
|
295
305
|
// Limit max neighbors width for texture if needed?
|
|
296
306
|
// gpu.js handles 1D arrays well.
|
|
297
307
|
|
|
298
|
-
if (this.kernel) this.kernel.destroy();
|
|
299
|
-
|
|
300
308
|
// ---------------------------------------------------------
|
|
301
309
|
// KERNEL
|
|
302
310
|
// ---------------------------------------------------------
|
|
@@ -368,7 +376,7 @@ class GPULinkForce {
|
|
|
368
376
|
}
|
|
369
377
|
|
|
370
378
|
force(alpha) {
|
|
371
|
-
if (!this.available || this.nodes.length === 0) return;
|
|
379
|
+
if (!this.available || this.nodes.length === 0 || this._links.length === 0 || this.flatIndices.length === 0) return;
|
|
372
380
|
|
|
373
381
|
const n = this.nodes.length;
|
|
374
382
|
const posX = new Float32Array(n);
|