@comake/skl-js-engine 1.5.2 → 1.5.4
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/package.json +1 -1
- package/src/SklEngine.ts +8 -1
- package/src/util/TripleUtil.ts +22 -2
- package/dist/JsExecutor/PermissionBuilder.d.ts +0 -14
- package/dist/JsExecutor/PermissionBuilder.d.ts.map +0 -1
- package/dist/JsExecutor/PermissionBuilder.js +0 -58
- package/dist/JsExecutor/PermissionBuilder.js.map +0 -1
- package/dist/JsExecutor/constants.d.ts +0 -27
- package/dist/JsExecutor/constants.d.ts.map +0 -1
- package/dist/JsExecutor/constants.js +0 -30
- package/dist/JsExecutor/constants.js.map +0 -1
- package/dist/JsExecutor/denoUtils.d.ts +0 -10
- package/dist/JsExecutor/denoUtils.d.ts.map +0 -1
- package/dist/JsExecutor/denoUtils.js +0 -24
- package/dist/JsExecutor/denoUtils.js.map +0 -1
- package/dist/JsExecutor/errors.d.ts +0 -40
- package/dist/JsExecutor/errors.d.ts.map +0 -1
- package/dist/JsExecutor/errors.js +0 -67
- package/dist/JsExecutor/errors.js.map +0 -1
- package/dist/JsExecutor/examples/basic/index.d.ts +0 -1
- package/dist/JsExecutor/examples/basic/index.d.ts.map +0 -1
- package/dist/JsExecutor/examples/basic/index.js +0 -46
- package/dist/JsExecutor/examples/basic/index.js.map +0 -1
- package/dist/JsExecutor/examples/basic/process.d.ts +0 -1
- package/dist/JsExecutor/examples/basic/process.d.ts.map +0 -1
- package/dist/JsExecutor/examples/basic/process.js +0 -34
- package/dist/JsExecutor/examples/basic/process.js.map +0 -1
- package/dist/JsExecutor/examples/jsExecutor/index.d.ts +0 -2
- package/dist/JsExecutor/examples/jsExecutor/index.d.ts.map +0 -1
- package/dist/JsExecutor/examples/jsExecutor/index.js +0 -47
- package/dist/JsExecutor/examples/jsExecutor/index.js.map +0 -1
- package/dist/JsExecutor/examples/jsExecutor/process.d.ts +0 -2
- package/dist/JsExecutor/examples/jsExecutor/process.d.ts.map +0 -1
- package/dist/JsExecutor/examples/jsExecutor/process.js +0 -58
- package/dist/JsExecutor/examples/jsExecutor/process.js.map +0 -1
- package/dist/JsExecutor/index.d.ts +0 -7
- package/dist/JsExecutor/index.d.ts.map +0 -1
- package/dist/JsExecutor/index.js +0 -36
- package/dist/JsExecutor/index.js.map +0 -1
- package/dist/JsExecutor/jsExecutor.d.ts +0 -68
- package/dist/JsExecutor/jsExecutor.d.ts.map +0 -1
- package/dist/JsExecutor/jsExecutor.js +0 -171
- package/dist/JsExecutor/jsExecutor.js.map +0 -1
- package/dist/JsExecutor/jsonRpc/JsonRpcClient.d.ts +0 -165
- package/dist/JsExecutor/jsonRpc/JsonRpcClient.d.ts.map +0 -1
- package/dist/JsExecutor/jsonRpc/JsonRpcClient.js +0 -335
- package/dist/JsExecutor/jsonRpc/JsonRpcClient.js.map +0 -1
- package/dist/JsExecutor/jsonRpc/JsonRpcServer.d.ts +0 -125
- package/dist/JsExecutor/jsonRpc/JsonRpcServer.d.ts.map +0 -1
- package/dist/JsExecutor/jsonRpc/JsonRpcServer.js +0 -391
- package/dist/JsExecutor/jsonRpc/JsonRpcServer.js.map +0 -1
- package/dist/JsExecutor/jsonRpc/index.d.ts +0 -4
- package/dist/JsExecutor/jsonRpc/index.d.ts.map +0 -1
- package/dist/JsExecutor/jsonRpc/index.js +0 -23
- package/dist/JsExecutor/jsonRpc/index.js.map +0 -1
- package/dist/JsExecutor/jsonRpc/types.d.ts +0 -193
- package/dist/JsExecutor/jsonRpc/types.d.ts.map +0 -1
- package/dist/JsExecutor/jsonRpc/types.js +0 -37
- package/dist/JsExecutor/jsonRpc/types.js.map +0 -1
- package/dist/JsExecutor/transport/Transport.d.ts +0 -74
- package/dist/JsExecutor/transport/Transport.d.ts.map +0 -1
- package/dist/JsExecutor/transport/Transport.js +0 -14
- package/dist/JsExecutor/transport/Transport.js.map +0 -1
- package/dist/JsExecutor/transport/base/BaseTransport.d.ts +0 -51
- package/dist/JsExecutor/transport/base/BaseTransport.d.ts.map +0 -1
- package/dist/JsExecutor/transport/base/BaseTransport.js +0 -68
- package/dist/JsExecutor/transport/base/BaseTransport.js.map +0 -1
- package/dist/JsExecutor/transport/index.d.ts +0 -13
- package/dist/JsExecutor/transport/index.d.ts.map +0 -1
- package/dist/JsExecutor/transport/index.js +0 -36
- package/dist/JsExecutor/transport/index.js.map +0 -1
- package/dist/JsExecutor/transport/process/ProcessManager.d.ts +0 -96
- package/dist/JsExecutor/transport/process/ProcessManager.d.ts.map +0 -1
- package/dist/JsExecutor/transport/process/ProcessManager.js +0 -219
- package/dist/JsExecutor/transport/process/ProcessManager.js.map +0 -1
- package/dist/JsExecutor/transport/stdio/ChildStdioTransport.d.ts +0 -87
- package/dist/JsExecutor/transport/stdio/ChildStdioTransport.d.ts.map +0 -1
- package/dist/JsExecutor/transport/stdio/ChildStdioTransport.js +0 -219
- package/dist/JsExecutor/transport/stdio/ChildStdioTransport.js.map +0 -1
- package/dist/JsExecutor/transport/stdio/ParentStdioTransport.d.ts +0 -81
- package/dist/JsExecutor/transport/stdio/ParentStdioTransport.d.ts.map +0 -1
- package/dist/JsExecutor/transport/stdio/ParentStdioTransport.js +0 -259
- package/dist/JsExecutor/transport/stdio/ParentStdioTransport.js.map +0 -1
- package/dist/JsExecutor/transport/utils/MessageUtils.d.ts +0 -68
- package/dist/JsExecutor/transport/utils/MessageUtils.d.ts.map +0 -1
- package/dist/JsExecutor/transport/utils/MessageUtils.js +0 -135
- package/dist/JsExecutor/transport/utils/MessageUtils.js.map +0 -1
- package/dist/JsExecutor/transport/utils/PollingUtils.d.ts +0 -53
- package/dist/JsExecutor/transport/utils/PollingUtils.d.ts.map +0 -1
- package/dist/JsExecutor/transport/utils/PollingUtils.js +0 -92
- package/dist/JsExecutor/transport/utils/PollingUtils.js.map +0 -1
- package/dist/JsExecutor/types.d.ts +0 -113
- package/dist/JsExecutor/types.d.ts.map +0 -1
- package/dist/JsExecutor/types.js +0 -3
- package/dist/JsExecutor/types.js.map +0 -1
- package/dist/SklEngine.d.ts +0 -132
- package/dist/SklEngine.d.ts.map +0 -1
- package/dist/SklEngine.js +0 -1501
- package/dist/SklEngine.js.map +0 -1
- package/dist/SklEngineOptions.d.ts +0 -58
- package/dist/SklEngineOptions.d.ts.map +0 -1
- package/dist/SklEngineOptions.js +0 -3
- package/dist/SklEngineOptions.js.map +0 -1
- package/dist/constants.d.ts +0 -96
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -103
- package/dist/constants.js.map +0 -1
- package/dist/customCapabilities.d.ts +0 -22
- package/dist/customCapabilities.d.ts.map +0 -1
- package/dist/customCapabilities.js +0 -45
- package/dist/customCapabilities.js.map +0 -1
- package/dist/examples/customCapabilitiesExample.d.ts +0 -2
- package/dist/examples/customCapabilitiesExample.d.ts.map +0 -1
- package/dist/examples/customCapabilitiesExample.js +0 -59
- package/dist/examples/customCapabilitiesExample.js.map +0 -1
- package/dist/executor.js +0 -216
- package/dist/hooks/globalHooks.d.ts +0 -50
- package/dist/hooks/globalHooks.d.ts.map +0 -1
- package/dist/hooks/globalHooks.js +0 -164
- package/dist/hooks/globalHooks.js.map +0 -1
- package/dist/hooks/types.d.ts +0 -9
- package/dist/hooks/types.d.ts.map +0 -1
- package/dist/hooks/types.js +0 -3
- package/dist/hooks/types.js.map +0 -1
- package/dist/index.d.ts +0 -41
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -68
- package/dist/index.js.map +0 -1
- package/dist/logger.d.ts +0 -35
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -119
- package/dist/logger.js.map +0 -1
- package/dist/mapping/Mapper.d.ts +0 -13
- package/dist/mapping/Mapper.d.ts.map +0 -1
- package/dist/mapping/Mapper.js +0 -64
- package/dist/mapping/Mapper.js.map +0 -1
- package/dist/storage/FindOperator.d.ts +0 -19
- package/dist/storage/FindOperator.d.ts.map +0 -1
- package/dist/storage/FindOperator.js +0 -23
- package/dist/storage/FindOperator.js.map +0 -1
- package/dist/storage/FindOptionsTypes.d.ts +0 -79
- package/dist/storage/FindOptionsTypes.d.ts.map +0 -1
- package/dist/storage/FindOptionsTypes.js +0 -3
- package/dist/storage/FindOptionsTypes.js.map +0 -1
- package/dist/storage/GroupOptionTypes.d.ts +0 -29
- package/dist/storage/GroupOptionTypes.d.ts.map +0 -1
- package/dist/storage/GroupOptionTypes.js +0 -3
- package/dist/storage/GroupOptionTypes.js.map +0 -1
- package/dist/storage/operator/And.d.ts +0 -4
- package/dist/storage/operator/And.d.ts.map +0 -1
- package/dist/storage/operator/And.js +0 -13
- package/dist/storage/operator/And.js.map +0 -1
- package/dist/storage/operator/Contains.d.ts +0 -3
- package/dist/storage/operator/Contains.d.ts.map +0 -1
- package/dist/storage/operator/Contains.js +0 -13
- package/dist/storage/operator/Contains.js.map +0 -1
- package/dist/storage/operator/Equal.d.ts +0 -5
- package/dist/storage/operator/Equal.d.ts.map +0 -1
- package/dist/storage/operator/Equal.js +0 -13
- package/dist/storage/operator/Equal.js.map +0 -1
- package/dist/storage/operator/Exists.d.ts +0 -3
- package/dist/storage/operator/Exists.d.ts.map +0 -1
- package/dist/storage/operator/Exists.js +0 -10
- package/dist/storage/operator/Exists.js.map +0 -1
- package/dist/storage/operator/GreaterThan.d.ts +0 -4
- package/dist/storage/operator/GreaterThan.d.ts.map +0 -1
- package/dist/storage/operator/GreaterThan.js +0 -13
- package/dist/storage/operator/GreaterThan.js.map +0 -1
- package/dist/storage/operator/GreaterThanOrEqual.d.ts +0 -4
- package/dist/storage/operator/GreaterThanOrEqual.d.ts.map +0 -1
- package/dist/storage/operator/GreaterThanOrEqual.js +0 -13
- package/dist/storage/operator/GreaterThanOrEqual.js.map +0 -1
- package/dist/storage/operator/In.d.ts +0 -4
- package/dist/storage/operator/In.d.ts.map +0 -1
- package/dist/storage/operator/In.js +0 -13
- package/dist/storage/operator/In.js.map +0 -1
- package/dist/storage/operator/Inverse.d.ts +0 -3
- package/dist/storage/operator/Inverse.d.ts.map +0 -1
- package/dist/storage/operator/Inverse.js +0 -13
- package/dist/storage/operator/Inverse.js.map +0 -1
- package/dist/storage/operator/InversePath.d.ts +0 -7
- package/dist/storage/operator/InversePath.d.ts.map +0 -1
- package/dist/storage/operator/InversePath.js +0 -13
- package/dist/storage/operator/InversePath.js.map +0 -1
- package/dist/storage/operator/InverseRelation.d.ts +0 -9
- package/dist/storage/operator/InverseRelation.d.ts.map +0 -1
- package/dist/storage/operator/InverseRelation.js +0 -13
- package/dist/storage/operator/InverseRelation.js.map +0 -1
- package/dist/storage/operator/InverseRelationOrder.d.ts +0 -8
- package/dist/storage/operator/InverseRelationOrder.d.ts.map +0 -1
- package/dist/storage/operator/InverseRelationOrder.js +0 -13
- package/dist/storage/operator/InverseRelationOrder.js.map +0 -1
- package/dist/storage/operator/LessThan.d.ts +0 -4
- package/dist/storage/operator/LessThan.d.ts.map +0 -1
- package/dist/storage/operator/LessThan.js +0 -13
- package/dist/storage/operator/LessThan.js.map +0 -1
- package/dist/storage/operator/LessThanOrEqual.d.ts +0 -4
- package/dist/storage/operator/LessThanOrEqual.d.ts.map +0 -1
- package/dist/storage/operator/LessThanOrEqual.js +0 -13
- package/dist/storage/operator/LessThanOrEqual.js.map +0 -1
- package/dist/storage/operator/Not.d.ts +0 -3
- package/dist/storage/operator/Not.d.ts.map +0 -1
- package/dist/storage/operator/Not.js +0 -13
- package/dist/storage/operator/Not.js.map +0 -1
- package/dist/storage/operator/OneOrMorePath.d.ts +0 -7
- package/dist/storage/operator/OneOrMorePath.d.ts.map +0 -1
- package/dist/storage/operator/OneOrMorePath.js +0 -13
- package/dist/storage/operator/OneOrMorePath.js.map +0 -1
- package/dist/storage/operator/Or.d.ts +0 -4
- package/dist/storage/operator/Or.d.ts.map +0 -1
- package/dist/storage/operator/Or.js +0 -13
- package/dist/storage/operator/Or.js.map +0 -1
- package/dist/storage/operator/Sequence.d.ts +0 -3
- package/dist/storage/operator/Sequence.d.ts.map +0 -1
- package/dist/storage/operator/Sequence.js +0 -13
- package/dist/storage/operator/Sequence.js.map +0 -1
- package/dist/storage/operator/SequencePath.d.ts +0 -7
- package/dist/storage/operator/SequencePath.d.ts.map +0 -1
- package/dist/storage/operator/SequencePath.js +0 -13
- package/dist/storage/operator/SequencePath.js.map +0 -1
- package/dist/storage/operator/ZeroOrMorePath.d.ts +0 -7
- package/dist/storage/operator/ZeroOrMorePath.d.ts.map +0 -1
- package/dist/storage/operator/ZeroOrMorePath.js +0 -13
- package/dist/storage/operator/ZeroOrMorePath.js.map +0 -1
- package/dist/storage/query-adapter/QueryAdapter.d.ts +0 -99
- package/dist/storage/query-adapter/QueryAdapter.d.ts.map +0 -1
- package/dist/storage/query-adapter/QueryAdapter.js +0 -3
- package/dist/storage/query-adapter/QueryAdapter.js.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.d.ts +0 -40
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.js +0 -315
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.js.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapterOptions.d.ts +0 -34
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapterOptions.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapterOptions.js +0 -3
- package/dist/storage/query-adapter/sparql/SparqlQueryAdapterOptions.js.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.d.ts +0 -104
- package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.js +0 -1210
- package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.js.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlUpdateBuilder.d.ts +0 -41
- package/dist/storage/query-adapter/sparql/SparqlUpdateBuilder.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/SparqlUpdateBuilder.js +0 -305
- package/dist/storage/query-adapter/sparql/SparqlUpdateBuilder.js.map +0 -1
- package/dist/storage/query-adapter/sparql/VariableGenerator.d.ts +0 -5
- package/dist/storage/query-adapter/sparql/VariableGenerator.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/VariableGenerator.js +0 -14
- package/dist/storage/query-adapter/sparql/VariableGenerator.js.map +0 -1
- package/dist/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.d.ts +0 -19
- package/dist/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.js +0 -90
- package/dist/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.js.map +0 -1
- package/dist/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.d.ts +0 -27
- package/dist/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.js +0 -116
- package/dist/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.js.map +0 -1
- package/dist/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.d.ts +0 -34
- package/dist/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.d.ts.map +0 -1
- package/dist/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.js +0 -3
- package/dist/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.js.map +0 -1
- package/dist/tools/explain-findall-sparql.d.ts +0 -2
- package/dist/tools/explain-findall-sparql.d.ts.map +0 -1
- package/dist/tools/explain-findall-sparql.js +0 -303
- package/dist/tools/explain-findall-sparql.js.map +0 -1
- package/dist/util/PerformanceLogger.d.ts +0 -28
- package/dist/util/PerformanceLogger.d.ts.map +0 -1
- package/dist/util/PerformanceLogger.js +0 -223
- package/dist/util/PerformanceLogger.js.map +0 -1
- package/dist/util/ReadCacheHelper.d.ts +0 -14
- package/dist/util/ReadCacheHelper.d.ts.map +0 -1
- package/dist/util/ReadCacheHelper.js +0 -61
- package/dist/util/ReadCacheHelper.js.map +0 -1
- package/dist/util/SparqlUtil.d.ts +0 -72
- package/dist/util/SparqlUtil.d.ts.map +0 -1
- package/dist/util/SparqlUtil.js +0 -456
- package/dist/util/SparqlUtil.js.map +0 -1
- package/dist/util/TripleUtil.d.ts +0 -10
- package/dist/util/TripleUtil.d.ts.map +0 -1
- package/dist/util/TripleUtil.js +0 -402
- package/dist/util/TripleUtil.js.map +0 -1
- package/dist/util/Types.d.ts +0 -271
- package/dist/util/Types.d.ts.map +0 -1
- package/dist/util/Types.js +0 -3
- package/dist/util/Types.js.map +0 -1
- package/dist/util/Util.d.ts +0 -26
- package/dist/util/Util.d.ts.map +0 -1
- package/dist/util/Util.js +0 -138
- package/dist/util/Util.js.map +0 -1
- package/dist/util/Vocabularies/Shared.d.ts +0 -13
- package/dist/util/Vocabularies/Shared.d.ts.map +0 -1
- package/dist/util/Vocabularies/Shared.js +0 -96
- package/dist/util/Vocabularies/Shared.js.map +0 -1
- package/dist/util/Vocabularies/helper.d.ts +0 -5
- package/dist/util/Vocabularies/helper.d.ts.map +0 -1
- package/dist/util/Vocabularies/helper.js +0 -10
- package/dist/util/Vocabularies/helper.js.map +0 -1
- package/dist/util/Vocabularies/index.d.ts +0 -8
- package/dist/util/Vocabularies/index.d.ts.map +0 -1
- package/dist/util/Vocabularies/index.js +0 -114
- package/dist/util/Vocabularies/index.js.map +0 -1
- package/dist/util/safeJsonStringify.d.ts +0 -1
- package/dist/util/safeJsonStringify.d.ts.map +0 -1
- package/dist/util/safeJsonStringify.js +0 -19
- package/dist/util/safeJsonStringify.js.map +0 -1
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
/* eslint-disable */
|
|
7
|
-
/* eslint-comments/no-unlimited-disable */
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const path_1 = __importDefault(require("path"));
|
|
10
|
-
const data_model_1 = __importDefault(require("@rdfjs/data-model"));
|
|
11
|
-
const sparqljs_1 = require("sparqljs");
|
|
12
|
-
const SparqlQueryBuilder_1 = require("../storage/query-adapter/sparql/SparqlQueryBuilder");
|
|
13
|
-
const SparqlUtil_1 = require("../util/SparqlUtil");
|
|
14
|
-
const Util_1 = require("../util/Util");
|
|
15
|
-
function usageAndExit(exitCode) {
|
|
16
|
-
const msg = [
|
|
17
|
-
'Usage:',
|
|
18
|
-
' node dist/tools/explain-findall-sparql.js --input <file.json> [--format text|json] [--simulate-entity-values N]',
|
|
19
|
-
'',
|
|
20
|
-
'Input JSON can be either:',
|
|
21
|
-
' 1) a full FindAllOptions object: { "where": { ... }, "relations": { ... }, "order": { ... }, "limit": 10, ... }',
|
|
22
|
-
' 2) a FindOptionsWhere object (treated as { where: <object> })',
|
|
23
|
-
'',
|
|
24
|
-
'Notes:',
|
|
25
|
-
' - This utility does not query a SPARQL endpoint. When findAll would inject VALUES(?entity) from a pre-SELECT,',
|
|
26
|
-
' you can pass --simulate-entity-values N to show an example VALUES block with N placeholder IRIs.',
|
|
27
|
-
''
|
|
28
|
-
].join('\n');
|
|
29
|
-
console.error(msg);
|
|
30
|
-
process.exit(exitCode);
|
|
31
|
-
}
|
|
32
|
-
function parseArgs(argv) {
|
|
33
|
-
const out = {
|
|
34
|
-
format: 'text',
|
|
35
|
-
simulateEntityValues: 0
|
|
36
|
-
};
|
|
37
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
38
|
-
const arg = argv[i];
|
|
39
|
-
if (arg === '--help' || arg === '-h') {
|
|
40
|
-
usageAndExit(0);
|
|
41
|
-
}
|
|
42
|
-
if (arg === '--input' || arg === '-i') {
|
|
43
|
-
out.input = argv[i + 1];
|
|
44
|
-
i += 1;
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
if (arg === '--format' || arg === '-f') {
|
|
48
|
-
const v = argv[i + 1];
|
|
49
|
-
if (v !== 'text' && v !== 'json') {
|
|
50
|
-
console.error(`Invalid --format: ${String(v)}`);
|
|
51
|
-
usageAndExit(2);
|
|
52
|
-
}
|
|
53
|
-
out.format = v;
|
|
54
|
-
i += 1;
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
if (arg === '--simulate-entity-values') {
|
|
58
|
-
const v = Number.parseInt(argv[i + 1] ?? '', 10);
|
|
59
|
-
if (!Number.isFinite(v) || v < 0) {
|
|
60
|
-
console.error(`Invalid --simulate-entity-values: ${argv[i + 1]}`);
|
|
61
|
-
usageAndExit(2);
|
|
62
|
-
}
|
|
63
|
-
out.simulateEntityValues = v;
|
|
64
|
-
i += 1;
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
if (arg.startsWith('-')) {
|
|
68
|
-
console.error(`Unknown arg: ${arg}`);
|
|
69
|
-
usageAndExit(2);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return out;
|
|
73
|
-
}
|
|
74
|
-
function readJsonFile(p) {
|
|
75
|
-
const abs = path_1.default.isAbsolute(p) ? p : path_1.default.join(process.cwd(), p);
|
|
76
|
-
const raw = fs_1.default.readFileSync(abs, 'utf8');
|
|
77
|
-
try {
|
|
78
|
-
return JSON.parse(raw);
|
|
79
|
-
}
|
|
80
|
-
catch (e) {
|
|
81
|
-
throw new Error(`Failed to parse JSON from ${abs}: ${e.message}`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
function coerceSparqlVariable(v) {
|
|
85
|
-
if (!v)
|
|
86
|
-
return undefined;
|
|
87
|
-
if (typeof v === 'string') {
|
|
88
|
-
const name = v.startsWith('?') ? v.slice(1) : v;
|
|
89
|
-
return data_model_1.default.variable(name);
|
|
90
|
-
}
|
|
91
|
-
if (typeof v === 'object' && v.termType === 'Variable' && typeof v.value === 'string') {
|
|
92
|
-
return v;
|
|
93
|
-
}
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
|
-
function normalizeFindAllOptions(input) {
|
|
97
|
-
const asOptions = typeof input === 'object' &&
|
|
98
|
-
input !== null &&
|
|
99
|
-
('where' in input || 'select' in input || 'relations' in input || 'order' in input || 'limit' in input || 'offset' in input || 'subQueries' in input);
|
|
100
|
-
const options = asOptions ? input : { where: input };
|
|
101
|
-
// Allow simple JSON-friendly forms for variables.
|
|
102
|
-
const group = coerceSparqlVariable(options.group);
|
|
103
|
-
const entitySelectVariable = coerceSparqlVariable(options.entitySelectVariable);
|
|
104
|
-
const subQueries = Array.isArray(options.subQueries)
|
|
105
|
-
? options.subQueries.map((sq) => {
|
|
106
|
-
const select = Array.isArray(sq?.select) ? sq.select.map(coerceSparqlVariable).filter(Boolean) : sq?.select;
|
|
107
|
-
return { ...sq, ...(select ? { select } : {}) };
|
|
108
|
-
})
|
|
109
|
-
: options.subQueries;
|
|
110
|
-
return {
|
|
111
|
-
...options,
|
|
112
|
-
...(group ? { group } : {}),
|
|
113
|
-
...(entitySelectVariable ? { entitySelectVariable } : {}),
|
|
114
|
-
...(subQueries ? { subQueries } : {})
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
function stringifyQuery(query) {
|
|
118
|
-
const gen = new sparqljs_1.Generator();
|
|
119
|
-
return gen.stringify(query);
|
|
120
|
-
}
|
|
121
|
-
function buildEntitySelectQueryForFindAll(selectQueryData, options) {
|
|
122
|
-
// Mirrors SparqlQueryAdapter.buildFindAllQueryData() for the entitySelectQuery creation.
|
|
123
|
-
const wherePatterns = [...selectQueryData.where, ...selectQueryData.graphWhere];
|
|
124
|
-
wherePatterns.push({
|
|
125
|
-
type: 'bgp',
|
|
126
|
-
triples: [
|
|
127
|
-
{
|
|
128
|
-
subject: SparqlUtil_1.entityVariable,
|
|
129
|
-
predicate: SparqlUtil_1.rdfTypeNamedNode,
|
|
130
|
-
object: SparqlUtil_1.rdfTypeVariable
|
|
131
|
-
}
|
|
132
|
-
]
|
|
133
|
-
});
|
|
134
|
-
const entitySelectVariable = options?.entitySelectVariable ?? SparqlUtil_1.entityVariable;
|
|
135
|
-
const groupBy = (0, Util_1.ensureArray)(selectQueryData?.group ?? options?.group ?? []);
|
|
136
|
-
groupBy.push(entitySelectVariable);
|
|
137
|
-
// All non-aggregated variables in SELECT must be in GROUP BY
|
|
138
|
-
for (const selectVariable of selectQueryData.selectVariables ?? []) {
|
|
139
|
-
const expr = selectVariable.expression;
|
|
140
|
-
if (!('aggregation' in expr) && expr?.constructor?.name === 'Variable') {
|
|
141
|
-
groupBy.push(expr);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (selectQueryData.where.length === 0) {
|
|
145
|
-
return undefined;
|
|
146
|
-
}
|
|
147
|
-
return (0, SparqlUtil_1.createSparqlSelectQuery)([
|
|
148
|
-
entitySelectVariable,
|
|
149
|
-
// (GROUP_CONCAT(DISTINCT str(?rdfType); SEPARATOR = " | ") AS ?rdfTypes)
|
|
150
|
-
{
|
|
151
|
-
expression: {
|
|
152
|
-
type: 'aggregate',
|
|
153
|
-
aggregation: 'group_concat',
|
|
154
|
-
separator: ' | ',
|
|
155
|
-
distinct: true,
|
|
156
|
-
expression: {
|
|
157
|
-
type: 'operation',
|
|
158
|
-
operator: 'STR',
|
|
159
|
-
args: [SparqlUtil_1.rdfTypeVariable]
|
|
160
|
-
}
|
|
161
|
-
},
|
|
162
|
-
variable: SparqlUtil_1.rdfTypesVariable
|
|
163
|
-
},
|
|
164
|
-
...(selectQueryData.selectVariables?.map(({ variable, expression }) => {
|
|
165
|
-
if (!expression)
|
|
166
|
-
return variable;
|
|
167
|
-
return { variable, expression };
|
|
168
|
-
}) ?? [])
|
|
169
|
-
], wherePatterns, selectQueryData.orders, groupBy, options?.limit, options?.offset);
|
|
170
|
-
}
|
|
171
|
-
function simulateEntityIdValues(n) {
|
|
172
|
-
const values = [];
|
|
173
|
-
for (let i = 1; i <= n; i += 1) {
|
|
174
|
-
values.push(data_model_1.default.namedNode(`urn:skl-dry-run:entity-${i}`));
|
|
175
|
-
}
|
|
176
|
-
return values;
|
|
177
|
-
}
|
|
178
|
-
async function main() {
|
|
179
|
-
const args = parseArgs(process.argv.slice(2));
|
|
180
|
-
if (!args.input) {
|
|
181
|
-
usageAndExit(2);
|
|
182
|
-
}
|
|
183
|
-
const input = readJsonFile(args.input);
|
|
184
|
-
const options = normalizeFindAllOptions(input);
|
|
185
|
-
const qb = new SparqlQueryBuilder_1.SparqlQueryBuilder();
|
|
186
|
-
const queryData = qb.buildEntitySelectPatternsFromOptions(SparqlUtil_1.entityVariable, options);
|
|
187
|
-
const selectQueryData = qb.buildEntitySelectPatternsFromOptions(SparqlUtil_1.entityVariable, {
|
|
188
|
-
...options,
|
|
189
|
-
relations: undefined
|
|
190
|
-
});
|
|
191
|
-
// Mirrors SparqlQueryAdapter.buildFindAllQueryData() for the relations union tweak.
|
|
192
|
-
if ((queryData?.relationsQueryData?.unionPatterns ?? []).length > 0) {
|
|
193
|
-
queryData?.relationsQueryData?.unionPatterns.push((0, SparqlUtil_1.createSparqlGraphPattern)(SparqlUtil_1.entityVariable, [(0, SparqlUtil_1.createSparqlBasicGraphPattern)([SparqlUtil_1.entityGraphTriple])]));
|
|
194
|
-
}
|
|
195
|
-
const entitySelectQuery = buildEntitySelectQueryForFindAll(selectQueryData, options);
|
|
196
|
-
const wouldPreSelectForOrderingAndValues = queryData.orders.length > 0 && options?.limit !== 1 && !!entitySelectQuery;
|
|
197
|
-
const steps = [];
|
|
198
|
-
if (entitySelectQuery) {
|
|
199
|
-
const notes = [];
|
|
200
|
-
if (wouldPreSelectForOrderingAndValues) {
|
|
201
|
-
notes.push('In SparqlQueryAdapter.findAll(), this SELECT is executed first to compute entity ordering.', 'Its results are then used to inject a VALUES block over ?entity into the main CONSTRUCT query.');
|
|
202
|
-
if (options?.limit === undefined) {
|
|
203
|
-
notes.push('Warning: limit is undefined, so this pre-SELECT may return all matching entity IDs (potentially huge).');
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
notes.push(`VALUES size is <= limit (${options.limit}).`);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
notes.push('In some cases (relations/type constraints), findAll executes this SELECT to support framing/type handling.');
|
|
211
|
-
notes.push('In that path, it also embeds this SELECT as a subquery inside the CONSTRUCT.');
|
|
212
|
-
}
|
|
213
|
-
steps.push({
|
|
214
|
-
kind: 'select',
|
|
215
|
-
name: 'Entity Pre-SELECT',
|
|
216
|
-
wouldExecute: wouldPreSelectForOrderingAndValues,
|
|
217
|
-
sparql: stringifyQuery(entitySelectQuery),
|
|
218
|
-
notes
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
let constructWhere = queryData.graphWhere;
|
|
222
|
-
let constructNotes = [];
|
|
223
|
-
if (wouldPreSelectForOrderingAndValues) {
|
|
224
|
-
if (args.simulateEntityValues > 0) {
|
|
225
|
-
const variableValueFilters = (0, SparqlUtil_1.createValuesPatternsForVariables)({
|
|
226
|
-
[SparqlUtil_1.entityVariable.value]: simulateEntityIdValues(args.simulateEntityValues)
|
|
227
|
-
});
|
|
228
|
-
constructWhere = [...variableValueFilters, ...constructWhere];
|
|
229
|
-
constructNotes = [
|
|
230
|
-
`This CONSTRUCT includes a simulated VALUES(?${SparqlUtil_1.entityVariable.value}) with ${args.simulateEntityValues} placeholder IRIs.`,
|
|
231
|
-
'In real execution, those VALUES come from the pre-SELECT results.'
|
|
232
|
-
];
|
|
233
|
-
}
|
|
234
|
-
else {
|
|
235
|
-
constructNotes = [
|
|
236
|
-
'In real execution, this CONSTRUCT is preceded by the pre-SELECT and will have a VALUES(?entity) block injected.',
|
|
237
|
-
'Pass --simulate-entity-values N to show an example VALUES block.'
|
|
238
|
-
];
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
else if (entitySelectQuery) {
|
|
242
|
-
// Mirrors the else-if path where the entity select is embedded into the CONSTRUCT.
|
|
243
|
-
const entitySelectGroupQuery = (0, SparqlUtil_1.createSparqlSelectGroup)([entitySelectQuery]);
|
|
244
|
-
constructWhere = [entitySelectGroupQuery, ...constructWhere];
|
|
245
|
-
constructNotes = ['This CONSTRUCT embeds the entity SELECT as a subquery (GROUP pattern) in its WHERE.'];
|
|
246
|
-
}
|
|
247
|
-
const constructQuery = qb.buildConstructFromEntitySelectQuery(constructWhere, queryData.graphSelectionTriples, options?.select, queryData.selectVariables);
|
|
248
|
-
steps.push({
|
|
249
|
-
kind: 'construct',
|
|
250
|
-
name: 'Main CONSTRUCT',
|
|
251
|
-
wouldExecute: true,
|
|
252
|
-
sparql: stringifyQuery(constructQuery),
|
|
253
|
-
...(constructNotes.length > 0 ? { notes: constructNotes } : {})
|
|
254
|
-
});
|
|
255
|
-
if (wouldPreSelectForOrderingAndValues && options?.limit === undefined) {
|
|
256
|
-
steps.push({
|
|
257
|
-
kind: 'note',
|
|
258
|
-
name: 'Performance Hint',
|
|
259
|
-
wouldExecute: false,
|
|
260
|
-
notes: [
|
|
261
|
-
'findAll() with no limit triggers a pre-SELECT that can return a very large ID set, then injects it into VALUES(?entity).',
|
|
262
|
-
'This often causes slow queries due to large intermediate results and huge VALUES blocks.'
|
|
263
|
-
]
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
const plan = {
|
|
267
|
-
input,
|
|
268
|
-
normalizedOptions: options,
|
|
269
|
-
steps,
|
|
270
|
-
meta: {
|
|
271
|
-
wouldPreSelectForOrderingAndValues,
|
|
272
|
-
hasRelations: (queryData?.relationsQueryData?.unionPatterns ?? []).length > 0,
|
|
273
|
-
hasTypeConstraint: options?.where?.type !== undefined,
|
|
274
|
-
limit: options?.limit,
|
|
275
|
-
offset: options?.offset
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
if (args.format === 'json') {
|
|
279
|
-
console.log(JSON.stringify(plan, null, 2));
|
|
280
|
-
return;
|
|
281
|
-
}
|
|
282
|
-
// Text
|
|
283
|
-
for (const step of plan.steps) {
|
|
284
|
-
if (step.kind === 'note') {
|
|
285
|
-
console.log(`\n# ${step.name}\n`);
|
|
286
|
-
for (const n of step.notes)
|
|
287
|
-
console.log(`- ${n}`);
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
console.log(`\n# ${step.name}\n`);
|
|
291
|
-
if ('notes' in step && step.notes?.length) {
|
|
292
|
-
for (const n of step.notes)
|
|
293
|
-
console.log(`- ${n}`);
|
|
294
|
-
console.log('');
|
|
295
|
-
}
|
|
296
|
-
console.log(step.sparql.trim());
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
main().catch((err) => {
|
|
300
|
-
console.error(err);
|
|
301
|
-
process.exit(1);
|
|
302
|
-
});
|
|
303
|
-
//# sourceMappingURL=explain-findall-sparql.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"explain-findall-sparql.js","sourceRoot":"","sources":["../../src/tools/explain-findall-sparql.ts"],"names":[],"mappings":";;;;;AAAA,oBAAoB;AACpB,0CAA0C;AAC1C,4CAAoB;AACpB,gDAAwB;AAExB,mEAA4C;AAG5C,uCAAqC;AAGrC,2FAAwF;AACxF,mDAW4B;AAC5B,uCAA2C;AAiC3C,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,GAAG,GAAG;QACV,QAAQ;QACR,mHAAmH;QACnH,EAAE;QACF,2BAA2B;QAC3B,mHAAmH;QACnH,iEAAiE;QACjE,EAAE;QACF,QAAQ;QACR,iHAAiH;QACjH,sGAAsG;QACtG,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEnB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,GAAG,GAA2E;QAClF,MAAM,EAAE,MAAM;QACd,oBAAoB,EAAE,CAAC;KACxB,CAAC;IAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;YACpC,YAAY,CAAC,CAAC,CAAC,CAAC;SACjB;QACD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE;YACrC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;SACV;QACD,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,IAAI,EAAE;YACtC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAA6B,CAAC;YAClD,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,MAAM,EAAE;gBAChC,OAAO,CAAC,KAAK,CAAC,qBAAqB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAChD,YAAY,CAAC,CAAC,CAAC,CAAC;aACjB;YACD,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;YACf,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;SACV;QACD,IAAI,GAAG,KAAK,0BAA0B,EAAE;YACtC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;gBAChC,OAAO,CAAC,KAAK,CAAC,qCAAqC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;gBAClE,YAAY,CAAC,CAAC,CAAC,CAAC;aACjB;YACD,GAAG,CAAC,oBAAoB,GAAG,CAAC,CAAC;YAC7B,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;SACV;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;YACvB,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;YACrC,YAAY,CAAC,CAAC,CAAC,CAAC;SACjB;KACF;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,MAAM,GAAG,GAAG,cAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;KACxB;IAAC,OAAO,CAAC,EAAE;QACV,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;KAC9E;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,CAAM;IAClC,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE;QACzB,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,OAAO,oBAAW,CAAC,QAAQ,CAAC,IAAI,CAAQ,CAAC;KAC1C;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE;QACrF,OAAO,CAAC,CAAC;KACV;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAU;IACzC,MAAM,SAAS,GACb,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,WAAW,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,CAAC,CAAC;IAExJ,MAAM,OAAO,GAAmB,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAyB,EAAE,CAAC;IAEzF,kDAAkD;IAClD,MAAM,KAAK,GAAG,oBAAoB,CAAE,OAAe,CAAC,KAAK,CAAC,CAAC;IAC3D,MAAM,oBAAoB,GAAG,oBAAoB,CAAE,OAAe,CAAC,oBAAoB,CAAC,CAAC;IAEzF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAE,OAAe,CAAC,UAAU,CAAC;QAC3D,CAAC,CAAE,OAAe,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAO,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC;YAC5G,OAAO,EAAE,GAAG,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAClD,CAAC,CAAC;QACJ,CAAC,CAAE,OAAe,CAAC,UAAU,CAAC;IAEhC,OAAO;QACL,GAAG,OAAO;QACV,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAmC;IACzD,MAAM,GAAG,GAAG,IAAI,oBAAS,EAAE,CAAC;IAC5B,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,gCAAgC,CACvC,eAAuF,EACvF,OAAwB;IAExB,yFAAyF;IACzF,MAAM,aAAa,GAAc,CAAC,GAAG,eAAe,CAAC,KAAK,EAAE,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC3F,aAAa,CAAC,IAAI,CAAC;QACjB,IAAI,EAAE,KAAK;QACX,OAAO,EAAE;YACP;gBACE,OAAO,EAAE,2BAAc;gBACvB,SAAS,EAAE,6BAAgB;gBAC3B,MAAM,EAAE,4BAAe;aACxB;SACF;KACF,CAAC,CAAC;IAEH,MAAM,oBAAoB,GAAG,OAAO,EAAE,oBAAoB,IAAI,2BAAc,CAAC;IAC7E,MAAM,OAAO,GAAG,IAAA,kBAAW,EAAC,eAAe,EAAE,KAAK,IAAI,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAC5E,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAEnC,6DAA6D;IAC7D,KAAK,MAAM,cAAc,IAAI,eAAe,CAAC,eAAe,IAAI,EAAE,EAAE;QAClE,MAAM,IAAI,GAAG,cAAc,CAAC,UAAiB,CAAC;QAC9C,IAAI,CAAC,CAAC,aAAa,IAAK,IAA4B,CAAC,IAAI,IAAI,EAAE,WAAW,EAAE,IAAI,KAAK,UAAU,EAAE;YAC/F,OAAO,CAAC,IAAI,CAAC,IAAgB,CAAC,CAAC;SAChC;KACF;IAED,IAAI,eAAe,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;QACtC,OAAO,SAAS,CAAC;KAClB;IAED,OAAO,IAAA,oCAAuB,EAC5B;QACE,oBAAoB;QACpB,yEAAyE;QACzE;YACE,UAAU,EAAE;gBACV,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,cAAc;gBAC3B,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,IAAI;gBACd,UAAU,EAAE;oBACV,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,KAAK;oBACf,IAAI,EAAE,CAAC,4BAAe,CAAC;iBACxB;aACF;YACD,QAAQ,EAAE,6BAAgB;SACpB;QACR,GAAG,CAAC,eAAe,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;YACpE,IAAI,CAAC,UAAU;gBAAE,OAAO,QAAe,CAAC;YACxC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAS,CAAC;QACzC,CAAC,CAAC,IAAI,EAAE,CAAC;KACH,EACR,aAAa,EACb,eAAe,CAAC,MAAM,EACtB,OAAc,EACd,OAAO,EAAE,KAAK,EACd,OAAO,EAAE,MAAM,CAChB,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,CAAS;IACvC,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE;QAC9B,MAAM,CAAC,IAAI,CAAC,oBAAW,CAAC,SAAS,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC,CAAC;KACnE;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;QACf,YAAY,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAE/C,MAAM,EAAE,GAAG,IAAI,uCAAkB,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,EAAE,CAAC,oCAAoC,CAAC,2BAAc,EAAE,OAAO,CAAC,CAAC;IACnF,MAAM,eAAe,GAAG,EAAE,CAAC,oCAAoC,CAAC,2BAAc,EAAE;QAC9E,GAAG,OAAO;QACV,SAAS,EAAE,SAAS;KACrB,CAAC,CAAC;IAEH,oFAAoF;IACpF,IAAI,CAAC,SAAS,EAAE,kBAAkB,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;QACnE,SAAS,EAAE,kBAAkB,EAAE,aAAa,CAAC,IAAI,CAAC,IAAA,qCAAwB,EAAC,2BAAc,EAAE,CAAC,IAAA,0CAA6B,EAAC,CAAC,8BAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACnJ;IAED,MAAM,iBAAiB,GAAG,gCAAgC,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IACrF,MAAM,kCAAkC,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,EAAE,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC;IAEtH,MAAM,KAAK,GAAe,EAAE,CAAC;IAE7B,IAAI,iBAAiB,EAAE;QACrB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,kCAAkC,EAAE;YACtC,KAAK,CAAC,IAAI,CACR,4FAA4F,EAC5F,gGAAgG,CACjG,CAAC;YACF,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE;gBAChC,KAAK,CAAC,IAAI,CAAC,wGAAwG,CAAC,CAAC;aACtH;iBAAM;gBACL,KAAK,CAAC,IAAI,CAAC,4BAA4B,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;aAC3D;SACF;aAAM;YACL,KAAK,CAAC,IAAI,CAAC,4GAA4G,CAAC,CAAC;YACzH,KAAK,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;SAC5F;QAED,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,mBAAmB;YACzB,YAAY,EAAE,kCAAkC;YAChD,MAAM,EAAE,cAAc,CAAC,iBAAiB,CAAC;YACzC,KAAK;SACN,CAAC,CAAC;KACJ;IAED,IAAI,cAAc,GAAG,SAAS,CAAC,UAAU,CAAC;IAC1C,IAAI,cAAc,GAAa,EAAE,CAAC;IAElC,IAAI,kCAAkC,EAAE;QACtC,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,EAAE;YACjC,MAAM,oBAAoB,GAAG,IAAA,6CAAgC,EAAC;gBAC5D,CAAC,2BAAc,CAAC,KAAK,CAAC,EAAE,sBAAsB,CAAC,IAAI,CAAC,oBAAoB,CAAQ;aACjF,CAAC,CAAC;YACH,cAAc,GAAG,CAAC,GAAG,oBAAoB,EAAE,GAAG,cAAc,CAAC,CAAC;YAC9D,cAAc,GAAG;gBACf,+CAA+C,2BAAc,CAAC,KAAK,UAAU,IAAI,CAAC,oBAAoB,oBAAoB;gBAC1H,mEAAmE;aACpE,CAAC;SACH;aAAM;YACL,cAAc,GAAG;gBACf,iHAAiH;gBACjH,kEAAkE;aACnE,CAAC;SACH;KACF;SAAM,IAAI,iBAAiB,EAAE;QAC5B,mFAAmF;QACnF,MAAM,sBAAsB,GAAG,IAAA,oCAAuB,EAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC5E,cAAc,GAAG,CAAC,sBAAsB,EAAE,GAAG,cAAc,CAAC,CAAC;QAC7D,cAAc,GAAG,CAAC,qFAAqF,CAAC,CAAC;KAC1G;IAED,MAAM,cAAc,GAAG,EAAE,CAAC,mCAAmC,CAAC,cAAc,EAAE,SAAS,CAAC,qBAAqB,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;IAE3J,KAAK,CAAC,IAAI,CAAC;QACT,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,gBAAgB;QACtB,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,cAAc,CAAC,cAAc,CAAC;QACtC,GAAG,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChE,CAAC,CAAC;IAEH,IAAI,kCAAkC,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE;QACtE,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,kBAAkB;YACxB,YAAY,EAAE,KAAK;YACnB,KAAK,EAAE;gBACL,0HAA0H;gBAC1H,0FAA0F;aAC3F;SACF,CAAC,CAAC;KACJ;IAED,MAAM,IAAI,GAAgB;QACxB,KAAK;QACL,iBAAiB,EAAE,OAAO;QAC1B,KAAK;QACL,IAAI,EAAE;YACJ,kCAAkC;YAClC,YAAY,EAAE,CAAC,SAAS,EAAE,kBAAkB,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;YAC7E,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,KAAK,SAAS;YACrD,KAAK,EAAE,OAAO,EAAE,KAAK;YACrB,MAAM,EAAE,OAAO,EAAE,MAAM;SACxB;KACF,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE;QAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO;KACR;IAED,OAAO;IACP,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE;YACxB,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;YAClC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClD,SAAS;SACV;QACD,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;QAClC,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE;YACzC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;SACjB;QACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;KACjC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC","sourcesContent":["/* eslint-disable */\n/* eslint-comments/no-unlimited-disable */\nimport fs from 'fs';\nimport path from 'path';\n\nimport DataFactory from '@rdfjs/data-model';\nimport type { NamedNode, Literal } from '@rdfjs/types';\nimport type { AggregateExpression, ConstructQuery, Pattern, SelectQuery, Variable } from 'sparqljs';\nimport { Generator } from 'sparqljs';\n\nimport type { FindAllOptions, FindOptionsWhere } from '../storage/FindOptionsTypes';\nimport { SparqlQueryBuilder } from '../storage/query-adapter/sparql/SparqlQueryBuilder';\nimport {\n createSparqlBasicGraphPattern,\n createSparqlGraphPattern,\n createSparqlSelectQuery,\n createValuesPatternsForVariables,\n entityGraphTriple,\n entityVariable,\n rdfTypeNamedNode,\n rdfTypesVariable,\n rdfTypeVariable,\n createSparqlSelectGroup\n} from '../util/SparqlUtil';\nimport { ensureArray } from '../util/Util';\n\ntype OutputFormat = 'text' | 'json';\n\ntype PlanStep =\n | {\n kind: 'select';\n name: string;\n wouldExecute: boolean;\n sparql: string;\n notes?: string[];\n }\n | {\n kind: 'construct';\n name: string;\n wouldExecute: boolean;\n sparql: string;\n notes?: string[];\n }\n | {\n kind: 'note';\n name: string;\n wouldExecute: boolean;\n notes: string[];\n };\n\ninterface ExplainPlan {\n input: unknown;\n normalizedOptions: FindAllOptions;\n steps: PlanStep[];\n meta: Record<string, any>;\n}\n\nfunction usageAndExit(exitCode: number): never {\n const msg = [\n 'Usage:',\n ' node dist/tools/explain-findall-sparql.js --input <file.json> [--format text|json] [--simulate-entity-values N]',\n '',\n 'Input JSON can be either:',\n ' 1) a full FindAllOptions object: { \"where\": { ... }, \"relations\": { ... }, \"order\": { ... }, \"limit\": 10, ... }',\n ' 2) a FindOptionsWhere object (treated as { where: <object> })',\n '',\n 'Notes:',\n ' - This utility does not query a SPARQL endpoint. When findAll would inject VALUES(?entity) from a pre-SELECT,',\n ' you can pass --simulate-entity-values N to show an example VALUES block with N placeholder IRIs.',\n ''\n ].join('\\n');\n\n console.error(msg);\n\n process.exit(exitCode);\n}\n\nfunction parseArgs(argv: string[]): { input?: string; format: OutputFormat; simulateEntityValues: number } {\n const out: { input?: string; format: OutputFormat; simulateEntityValues: number } = {\n format: 'text',\n simulateEntityValues: 0\n };\n\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (arg === '--help' || arg === '-h') {\n usageAndExit(0);\n }\n if (arg === '--input' || arg === '-i') {\n out.input = argv[i + 1];\n i += 1;\n continue;\n }\n if (arg === '--format' || arg === '-f') {\n const v = argv[i + 1] as OutputFormat | undefined;\n if (v !== 'text' && v !== 'json') {\n console.error(`Invalid --format: ${String(v)}`);\n usageAndExit(2);\n }\n out.format = v;\n i += 1;\n continue;\n }\n if (arg === '--simulate-entity-values') {\n const v = Number.parseInt(argv[i + 1] ?? '', 10);\n if (!Number.isFinite(v) || v < 0) {\n console.error(`Invalid --simulate-entity-values: ${argv[i + 1]}`);\n usageAndExit(2);\n }\n out.simulateEntityValues = v;\n i += 1;\n continue;\n }\n if (arg.startsWith('-')) {\n console.error(`Unknown arg: ${arg}`);\n usageAndExit(2);\n }\n }\n\n return out;\n}\n\nfunction readJsonFile(p: string): any {\n const abs = path.isAbsolute(p) ? p : path.join(process.cwd(), p);\n const raw = fs.readFileSync(abs, 'utf8');\n try {\n return JSON.parse(raw);\n } catch (e) {\n throw new Error(`Failed to parse JSON from ${abs}: ${(e as Error).message}`);\n }\n}\n\nfunction coerceSparqlVariable(v: any): Variable | undefined {\n if (!v) return undefined;\n if (typeof v === 'string') {\n const name = v.startsWith('?') ? v.slice(1) : v;\n return DataFactory.variable(name) as any;\n }\n if (typeof v === 'object' && v.termType === 'Variable' && typeof v.value === 'string') {\n return v;\n }\n return undefined;\n}\n\nfunction normalizeFindAllOptions(input: any): FindAllOptions {\n const asOptions =\n typeof input === 'object' &&\n input !== null &&\n ('where' in input || 'select' in input || 'relations' in input || 'order' in input || 'limit' in input || 'offset' in input || 'subQueries' in input);\n\n const options: FindAllOptions = asOptions ? input : { where: input as FindOptionsWhere };\n\n // Allow simple JSON-friendly forms for variables.\n const group = coerceSparqlVariable((options as any).group);\n const entitySelectVariable = coerceSparqlVariable((options as any).entitySelectVariable);\n\n const subQueries = Array.isArray((options as any).subQueries)\n ? (options as any).subQueries.map((sq: any) => {\n const select = Array.isArray(sq?.select) ? sq.select.map(coerceSparqlVariable).filter(Boolean) : sq?.select;\n return { ...sq, ...(select ? { select } : {}) };\n })\n : (options as any).subQueries;\n\n return {\n ...options,\n ...(group ? { group } : {}),\n ...(entitySelectVariable ? { entitySelectVariable } : {}),\n ...(subQueries ? { subQueries } : {})\n };\n}\n\nfunction stringifyQuery(query: SelectQuery | ConstructQuery): string {\n const gen = new Generator();\n return gen.stringify(query);\n}\n\nfunction buildEntitySelectQueryForFindAll(\n selectQueryData: ReturnType<SparqlQueryBuilder['buildEntitySelectPatternsFromOptions']>,\n options?: FindAllOptions\n): SelectQuery | undefined {\n // Mirrors SparqlQueryAdapter.buildFindAllQueryData() for the entitySelectQuery creation.\n const wherePatterns: Pattern[] = [...selectQueryData.where, ...selectQueryData.graphWhere];\n wherePatterns.push({\n type: 'bgp',\n triples: [\n {\n subject: entityVariable,\n predicate: rdfTypeNamedNode,\n object: rdfTypeVariable\n }\n ]\n });\n\n const entitySelectVariable = options?.entitySelectVariable ?? entityVariable;\n const groupBy = ensureArray(selectQueryData?.group ?? options?.group ?? []);\n groupBy.push(entitySelectVariable);\n\n // All non-aggregated variables in SELECT must be in GROUP BY\n for (const selectVariable of selectQueryData.selectVariables ?? []) {\n const expr = selectVariable.expression as any;\n if (!('aggregation' in (expr as AggregateExpression)) && expr?.constructor?.name === 'Variable') {\n groupBy.push(expr as Variable);\n }\n }\n\n if (selectQueryData.where.length === 0) {\n return undefined;\n }\n\n return createSparqlSelectQuery(\n [\n entitySelectVariable,\n // (GROUP_CONCAT(DISTINCT str(?rdfType); SEPARATOR = \" | \") AS ?rdfTypes)\n {\n expression: {\n type: 'aggregate',\n aggregation: 'group_concat',\n separator: ' | ',\n distinct: true,\n expression: {\n type: 'operation',\n operator: 'STR',\n args: [rdfTypeVariable]\n }\n },\n variable: rdfTypesVariable\n } as any,\n ...(selectQueryData.selectVariables?.map(({ variable, expression }) => {\n if (!expression) return variable as any;\n return { variable, expression } as any;\n }) ?? [])\n ] as any,\n wherePatterns,\n selectQueryData.orders,\n groupBy as any,\n options?.limit,\n options?.offset\n );\n}\n\nfunction simulateEntityIdValues(n: number): (NamedNode | Literal)[] {\n const values: NamedNode[] = [];\n for (let i = 1; i <= n; i += 1) {\n values.push(DataFactory.namedNode(`urn:skl-dry-run:entity-${i}`));\n }\n return values;\n}\n\nasync function main(): Promise<void> {\n const args = parseArgs(process.argv.slice(2));\n if (!args.input) {\n usageAndExit(2);\n }\n\n const input = readJsonFile(args.input);\n const options = normalizeFindAllOptions(input);\n\n const qb = new SparqlQueryBuilder();\n const queryData = qb.buildEntitySelectPatternsFromOptions(entityVariable, options);\n const selectQueryData = qb.buildEntitySelectPatternsFromOptions(entityVariable, {\n ...options,\n relations: undefined\n });\n\n // Mirrors SparqlQueryAdapter.buildFindAllQueryData() for the relations union tweak.\n if ((queryData?.relationsQueryData?.unionPatterns ?? []).length > 0) {\n queryData?.relationsQueryData?.unionPatterns.push(createSparqlGraphPattern(entityVariable, [createSparqlBasicGraphPattern([entityGraphTriple])]));\n }\n\n const entitySelectQuery = buildEntitySelectQueryForFindAll(selectQueryData, options);\n const wouldPreSelectForOrderingAndValues = queryData.orders.length > 0 && options?.limit !== 1 && !!entitySelectQuery;\n\n const steps: PlanStep[] = [];\n\n if (entitySelectQuery) {\n const notes: string[] = [];\n if (wouldPreSelectForOrderingAndValues) {\n notes.push(\n 'In SparqlQueryAdapter.findAll(), this SELECT is executed first to compute entity ordering.',\n 'Its results are then used to inject a VALUES block over ?entity into the main CONSTRUCT query.'\n );\n if (options?.limit === undefined) {\n notes.push('Warning: limit is undefined, so this pre-SELECT may return all matching entity IDs (potentially huge).');\n } else {\n notes.push(`VALUES size is <= limit (${options.limit}).`);\n }\n } else {\n notes.push('In some cases (relations/type constraints), findAll executes this SELECT to support framing/type handling.');\n notes.push('In that path, it also embeds this SELECT as a subquery inside the CONSTRUCT.');\n }\n\n steps.push({\n kind: 'select',\n name: 'Entity Pre-SELECT',\n wouldExecute: wouldPreSelectForOrderingAndValues,\n sparql: stringifyQuery(entitySelectQuery),\n notes\n });\n }\n\n let constructWhere = queryData.graphWhere;\n let constructNotes: string[] = [];\n\n if (wouldPreSelectForOrderingAndValues) {\n if (args.simulateEntityValues > 0) {\n const variableValueFilters = createValuesPatternsForVariables({\n [entityVariable.value]: simulateEntityIdValues(args.simulateEntityValues) as any\n });\n constructWhere = [...variableValueFilters, ...constructWhere];\n constructNotes = [\n `This CONSTRUCT includes a simulated VALUES(?${entityVariable.value}) with ${args.simulateEntityValues} placeholder IRIs.`,\n 'In real execution, those VALUES come from the pre-SELECT results.'\n ];\n } else {\n constructNotes = [\n 'In real execution, this CONSTRUCT is preceded by the pre-SELECT and will have a VALUES(?entity) block injected.',\n 'Pass --simulate-entity-values N to show an example VALUES block.'\n ];\n }\n } else if (entitySelectQuery) {\n // Mirrors the else-if path where the entity select is embedded into the CONSTRUCT.\n const entitySelectGroupQuery = createSparqlSelectGroup([entitySelectQuery]);\n constructWhere = [entitySelectGroupQuery, ...constructWhere];\n constructNotes = ['This CONSTRUCT embeds the entity SELECT as a subquery (GROUP pattern) in its WHERE.'];\n }\n\n const constructQuery = qb.buildConstructFromEntitySelectQuery(constructWhere, queryData.graphSelectionTriples, options?.select, queryData.selectVariables);\n\n steps.push({\n kind: 'construct',\n name: 'Main CONSTRUCT',\n wouldExecute: true,\n sparql: stringifyQuery(constructQuery),\n ...(constructNotes.length > 0 ? { notes: constructNotes } : {})\n });\n\n if (wouldPreSelectForOrderingAndValues && options?.limit === undefined) {\n steps.push({\n kind: 'note',\n name: 'Performance Hint',\n wouldExecute: false,\n notes: [\n 'findAll() with no limit triggers a pre-SELECT that can return a very large ID set, then injects it into VALUES(?entity).',\n 'This often causes slow queries due to large intermediate results and huge VALUES blocks.'\n ]\n });\n }\n\n const plan: ExplainPlan = {\n input,\n normalizedOptions: options,\n steps,\n meta: {\n wouldPreSelectForOrderingAndValues,\n hasRelations: (queryData?.relationsQueryData?.unionPatterns ?? []).length > 0,\n hasTypeConstraint: options?.where?.type !== undefined,\n limit: options?.limit,\n offset: options?.offset\n }\n };\n\n if (args.format === 'json') {\n console.log(JSON.stringify(plan, null, 2));\n return;\n }\n\n // Text\n for (const step of plan.steps) {\n if (step.kind === 'note') {\n console.log(`\\n# ${step.name}\\n`);\n for (const n of step.notes) console.log(`- ${n}`);\n continue;\n }\n console.log(`\\n# ${step.name}\\n`);\n if ('notes' in step && step.notes?.length) {\n for (const n of step.notes) console.log(`- ${n}`);\n console.log('');\n }\n console.log(step.sparql.trim());\n }\n}\n\nmain().catch((err: unknown) => {\n console.error(err);\n\n process.exit(1);\n});\n"]}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export interface Span {
|
|
2
|
-
id: string;
|
|
3
|
-
parentId?: string;
|
|
4
|
-
name: string;
|
|
5
|
-
startTime: number;
|
|
6
|
-
endTime?: number;
|
|
7
|
-
duration?: number;
|
|
8
|
-
attributes: Record<string, any>;
|
|
9
|
-
children: Span[];
|
|
10
|
-
}
|
|
11
|
-
export declare class PerformanceLogger {
|
|
12
|
-
private static asyncLocalStorage?;
|
|
13
|
-
private static enabled;
|
|
14
|
-
private static initialized;
|
|
15
|
-
private static spanCounter;
|
|
16
|
-
private static initialize;
|
|
17
|
-
private static generateSpanId;
|
|
18
|
-
static startSpan(name: string, attributes?: Record<string, any>): Span;
|
|
19
|
-
static endSpan(span: Span, additionalAttributes?: Record<string, any>): void;
|
|
20
|
-
static withSpan<T>(name: string, fn: () => Promise<T> | T, attributes?: Record<string, any>): Promise<T>;
|
|
21
|
-
static withSpanRoot<T>(name: string, fn: () => Promise<T> | T, attributes?: Record<string, any>): Promise<T>;
|
|
22
|
-
static getCurrentSpan(): Span | undefined;
|
|
23
|
-
static logSpanTree(rootSpan: Span): void;
|
|
24
|
-
private static buildSpanTreeLines;
|
|
25
|
-
private static addAttributeLines;
|
|
26
|
-
private static formatQuery;
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=PerformanceLogger.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PerformanceLogger.d.ts","sourceRoot":"","sources":["../../src/util/PerformanceLogger.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,QAAQ,EAAE,IAAI,EAAE,CAAC;CAClB;AAWD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAM;IACvC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAU;IAChC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAS;IACnC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAK;IAE/B,OAAO,CAAC,MAAM,CAAC,UAAU;IAezB,OAAO,CAAC,MAAM,CAAC,cAAc;WAKf,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;WAyB/D,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;WAa/D,QAAQ,CAAC,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;WAiCO,YAAY,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;WAqCC,cAAc,IAAI,IAAI,GAAG,SAAS;WAUlC,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI;IAyB/C,OAAO,CAAC,MAAM,CAAC,kBAAkB;IA0BjC,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAoChC,OAAO,CAAC,MAAM,CAAC,WAAW;CAqB3B"}
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PerformanceLogger = void 0;
|
|
4
|
-
/* eslint-disable require-unicode-regexp */
|
|
5
|
-
/* eslint-disable @typescript-eslint/naming-convention */
|
|
6
|
-
const perf_hooks_1 = require("perf_hooks");
|
|
7
|
-
let AsyncLocalStorage;
|
|
8
|
-
try {
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports, prefer-destructuring, global-require, @typescript-eslint/no-var-requires
|
|
10
|
-
AsyncLocalStorage = require('async_hooks').AsyncLocalStorage;
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
// AsyncLocalStorage not available
|
|
14
|
-
}
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
16
|
-
class PerformanceLogger {
|
|
17
|
-
static initialize() {
|
|
18
|
-
if (this.initialized) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
this.initialized = true;
|
|
22
|
-
// eslint-disable-next-line no-process-env
|
|
23
|
-
this.enabled = process.env.SKL_ENGINE_DEBUG_QUERIES === 'true' ||
|
|
24
|
-
// eslint-disable-next-line no-process-env
|
|
25
|
-
process.env.SKL_ENGINE_DEBUG_QUERIES === '1';
|
|
26
|
-
if (this.enabled && AsyncLocalStorage) {
|
|
27
|
-
this.asyncLocalStorage = new AsyncLocalStorage();
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
static generateSpanId() {
|
|
31
|
-
// eslint-disable-next-line no-plusplus
|
|
32
|
-
return `span-${++this.spanCounter}-${Date.now()}`;
|
|
33
|
-
}
|
|
34
|
-
static startSpan(name, attributes) {
|
|
35
|
-
this.initialize();
|
|
36
|
-
if (!this.enabled) {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
const parent = this.asyncLocalStorage?.getStore();
|
|
40
|
-
const span = {
|
|
41
|
-
id: this.generateSpanId(),
|
|
42
|
-
parentId: parent?.id,
|
|
43
|
-
name,
|
|
44
|
-
startTime: perf_hooks_1.performance.now(),
|
|
45
|
-
attributes: attributes ?? {},
|
|
46
|
-
children: []
|
|
47
|
-
};
|
|
48
|
-
if (parent) {
|
|
49
|
-
parent.children.push(span);
|
|
50
|
-
}
|
|
51
|
-
return span;
|
|
52
|
-
}
|
|
53
|
-
static endSpan(span, additionalAttributes) {
|
|
54
|
-
if (!this.enabled || !span) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
span.endTime = perf_hooks_1.performance.now();
|
|
58
|
-
span.duration = span.endTime - span.startTime;
|
|
59
|
-
if (additionalAttributes) {
|
|
60
|
-
span.attributes = { ...span.attributes, ...additionalAttributes };
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
static async withSpan(name, fn, attributes) {
|
|
64
|
-
this.initialize();
|
|
65
|
-
if (!this.enabled) {
|
|
66
|
-
return fn();
|
|
67
|
-
}
|
|
68
|
-
const span = this.startSpan(name, attributes);
|
|
69
|
-
if (this.asyncLocalStorage) {
|
|
70
|
-
return this.asyncLocalStorage.run(span, async () => {
|
|
71
|
-
try {
|
|
72
|
-
const result = await fn();
|
|
73
|
-
this.endSpan(span);
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });
|
|
78
|
-
throw error;
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
// Fallback without AsyncLocalStorage
|
|
83
|
-
try {
|
|
84
|
-
const result = await fn();
|
|
85
|
-
this.endSpan(span);
|
|
86
|
-
return result;
|
|
87
|
-
}
|
|
88
|
-
catch (error) {
|
|
89
|
-
this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });
|
|
90
|
-
throw error;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
static async withSpanRoot(name, fn, attributes) {
|
|
94
|
-
this.initialize();
|
|
95
|
-
if (!this.enabled) {
|
|
96
|
-
return fn();
|
|
97
|
-
}
|
|
98
|
-
const span = this.startSpan(name, attributes);
|
|
99
|
-
if (this.asyncLocalStorage) {
|
|
100
|
-
return this.asyncLocalStorage.run(span, async () => {
|
|
101
|
-
try {
|
|
102
|
-
const result = await fn();
|
|
103
|
-
this.endSpan(span);
|
|
104
|
-
this.logSpanTree(span);
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });
|
|
109
|
-
this.logSpanTree(span);
|
|
110
|
-
throw error;
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
// Fallback without AsyncLocalStorage
|
|
115
|
-
try {
|
|
116
|
-
const result = await fn();
|
|
117
|
-
this.endSpan(span);
|
|
118
|
-
this.logSpanTree(span);
|
|
119
|
-
return result;
|
|
120
|
-
}
|
|
121
|
-
catch (error) {
|
|
122
|
-
this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });
|
|
123
|
-
this.logSpanTree(span);
|
|
124
|
-
throw error;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
static getCurrentSpan() {
|
|
128
|
-
this.initialize();
|
|
129
|
-
if (!this.enabled || !this.asyncLocalStorage) {
|
|
130
|
-
return undefined;
|
|
131
|
-
}
|
|
132
|
-
return this.asyncLocalStorage.getStore();
|
|
133
|
-
}
|
|
134
|
-
static logSpanTree(rootSpan) {
|
|
135
|
-
if (!this.enabled || !rootSpan) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
const timestamp = new Date().toISOString();
|
|
139
|
-
const lines = [];
|
|
140
|
-
lines.push('');
|
|
141
|
-
lines.push('╔══════════════════════════════════════════════════════════════╗');
|
|
142
|
-
lines.push(`║ SKL Engine Performance Trace ║`);
|
|
143
|
-
lines.push(`║ Started: ${timestamp} ║`);
|
|
144
|
-
lines.push('╚══════════════════════════════════════════════════════════════╝');
|
|
145
|
-
lines.push('');
|
|
146
|
-
this.buildSpanTreeLines(rootSpan, lines, '', true);
|
|
147
|
-
lines.push('');
|
|
148
|
-
lines.push('═══════════════════════════════════════════════════════════════');
|
|
149
|
-
lines.push('');
|
|
150
|
-
// eslint-disable-next-line no-console
|
|
151
|
-
console.log(lines.join('\n'));
|
|
152
|
-
}
|
|
153
|
-
static buildSpanTreeLines(span, lines, prefix, isRoot) {
|
|
154
|
-
const duration = span.duration !== undefined ? `${span.duration.toFixed(2)}ms` : 'running...';
|
|
155
|
-
const status = span.attributes.error ? '✗' : '✓';
|
|
156
|
-
lines.push(`${prefix}${span.name} [${duration}] ${status}`);
|
|
157
|
-
// Show important attributes
|
|
158
|
-
this.addAttributeLines(span, lines, prefix);
|
|
159
|
-
// Process children
|
|
160
|
-
const childCount = span.children.length;
|
|
161
|
-
span.children.forEach((child, index) => {
|
|
162
|
-
const isLast = index === childCount - 1;
|
|
163
|
-
const childPrefix = prefix + (isRoot ? '' : '│ ');
|
|
164
|
-
const connector = isLast ? '└─ ' : '├─ ';
|
|
165
|
-
const nextPrefix = prefix + (isRoot ? '' : (isLast ? ' ' : '│ '));
|
|
166
|
-
this.buildSpanTreeLines(child, lines, childPrefix + connector, false);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
static addAttributeLines(span, lines, prefix) {
|
|
170
|
-
const { query, resultCount, options, error, errorMessage, ...otherAttrs } = span.attributes;
|
|
171
|
-
// Show query if present (and format it) - but make it easy to copy
|
|
172
|
-
if (query && typeof query === 'string') {
|
|
173
|
-
lines.push(`${prefix}│ Query:`);
|
|
174
|
-
// Empty line before query
|
|
175
|
-
lines.push('');
|
|
176
|
-
const formattedQuery = this.formatQuery(query);
|
|
177
|
-
formattedQuery.split('\n').forEach(line => {
|
|
178
|
-
// Simple indentation without tree chars
|
|
179
|
-
lines.push(` ${line}`);
|
|
180
|
-
});
|
|
181
|
-
// Empty line after query
|
|
182
|
-
lines.push('');
|
|
183
|
-
}
|
|
184
|
-
// Show result count
|
|
185
|
-
if (resultCount !== undefined) {
|
|
186
|
-
lines.push(`${prefix}│ Result: ${resultCount} ${resultCount === 1 ? 'row' : 'rows'}`);
|
|
187
|
-
}
|
|
188
|
-
// Show error if present
|
|
189
|
-
if (error && errorMessage) {
|
|
190
|
-
lines.push(`${prefix}│ Error: ${errorMessage}`);
|
|
191
|
-
}
|
|
192
|
-
// Show other important attributes
|
|
193
|
-
if (Object.keys(otherAttrs).length > 0) {
|
|
194
|
-
const attrStr = JSON.stringify(otherAttrs);
|
|
195
|
-
if (attrStr.length < 100) {
|
|
196
|
-
lines.push(`${prefix}│ Attributes: ${attrStr}`);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
static formatQuery(query) {
|
|
201
|
-
// Simple query formatting with proper indentation
|
|
202
|
-
let formatted = query.trim();
|
|
203
|
-
// Add line breaks after key SPARQL keywords for readability
|
|
204
|
-
formatted = formatted
|
|
205
|
-
.replace(/\s+/g, ' ')
|
|
206
|
-
.replace(/\s*{\s*/g, ' {\n ')
|
|
207
|
-
.replace(/\s*}\s*/g, '\n}')
|
|
208
|
-
.replace(/\s*\.\s*(?=[?A-Z])/g, ' .\n ')
|
|
209
|
-
.replace(/\bWHERE\b/g, '\nWHERE')
|
|
210
|
-
.replace(/\bFILTER\b/g, '\n FILTER')
|
|
211
|
-
.replace(/\bOPTIONAL\b/g, '\n OPTIONAL')
|
|
212
|
-
.replace(/\bUNION\b/g, '\nUNION')
|
|
213
|
-
.replace(/\bGRAPH\b/g, '\n GRAPH')
|
|
214
|
-
.replace(/\bORDER BY\b/g, '\nORDER BY')
|
|
215
|
-
.replace(/\bLIMIT\b/g, '\nLIMIT')
|
|
216
|
-
.replace(/\bOFFSET\b/g, '\nOFFSET');
|
|
217
|
-
return formatted;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
exports.PerformanceLogger = PerformanceLogger;
|
|
221
|
-
PerformanceLogger.initialized = false;
|
|
222
|
-
PerformanceLogger.spanCounter = 0;
|
|
223
|
-
//# sourceMappingURL=PerformanceLogger.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PerformanceLogger.js","sourceRoot":"","sources":["../../src/util/PerformanceLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable require-unicode-regexp */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport { performance } from 'perf_hooks';\n\nexport interface Span {\n id: string;\n parentId?: string;\n name: string;\n startTime: number;\n endTime?: number;\n duration?: number;\n attributes: Record<string, any>;\n children: Span[];\n}\n\nlet AsyncLocalStorage: any;\ntry {\n // eslint-disable-next-line @typescript-eslint/no-require-imports, prefer-destructuring, global-require, @typescript-eslint/no-var-requires\n AsyncLocalStorage = require('async_hooks').AsyncLocalStorage;\n} catch {\n // AsyncLocalStorage not available\n}\n\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport class PerformanceLogger {\n private static asyncLocalStorage?: any;\n private static enabled: boolean;\n private static initialized = false;\n private static spanCounter = 0;\n\n private static initialize(): void {\n if (this.initialized) {\n return;\n }\n this.initialized = true;\n // eslint-disable-next-line no-process-env\n this.enabled = process.env.SKL_ENGINE_DEBUG_QUERIES === 'true' || \n // eslint-disable-next-line no-process-env\n process.env.SKL_ENGINE_DEBUG_QUERIES === '1';\n \n if (this.enabled && AsyncLocalStorage) {\n this.asyncLocalStorage = new AsyncLocalStorage();\n }\n }\n\n private static generateSpanId(): string {\n // eslint-disable-next-line no-plusplus\n return `span-${++this.spanCounter}-${Date.now()}`;\n }\n\n public static startSpan(name: string, attributes?: Record<string, any>): Span {\n this.initialize();\n \n if (!this.enabled) {\n return null as any;\n }\n\n const parent = this.asyncLocalStorage?.getStore();\n \n const span: Span = {\n id: this.generateSpanId(),\n parentId: parent?.id,\n name,\n startTime: performance.now(),\n attributes: attributes ?? {},\n children: []\n };\n\n if (parent) {\n parent.children.push(span);\n }\n\n return span;\n }\n\n public static endSpan(span: Span, additionalAttributes?: Record<string, any>): void {\n if (!this.enabled || !span) {\n return;\n }\n\n span.endTime = performance.now();\n span.duration = span.endTime - span.startTime;\n\n if (additionalAttributes) {\n span.attributes = { ...span.attributes, ...additionalAttributes };\n }\n }\n\n public static async withSpan<T>(\n name: string,\n fn: () => Promise<T> | T,\n attributes?: Record<string, any>\n ): Promise<T> {\n this.initialize();\n \n if (!this.enabled) {\n return fn() as any;\n }\n\n const span = this.startSpan(name, attributes);\n\n if (this.asyncLocalStorage) {\n return this.asyncLocalStorage.run(span, async() => {\n try {\n const result = await fn();\n this.endSpan(span);\n return result;\n } catch (error) {\n this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });\n throw error;\n }\n });\n }\n\n // Fallback without AsyncLocalStorage\n try {\n const result = await fn();\n this.endSpan(span);\n return result;\n } catch (error) {\n this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });\n throw error;\n }\n }\n\n public static async withSpanRoot<T>(\n name: string,\n fn: () => Promise<T> | T,\n attributes?: Record<string, any>\n ): Promise<T> {\n this.initialize();\n \n if (!this.enabled) {\n return fn() as any;\n }\n\n const span = this.startSpan(name, attributes);\n\n if (this.asyncLocalStorage) {\n return this.asyncLocalStorage.run(span, async() => {\n try {\n const result = await fn();\n this.endSpan(span);\n this.logSpanTree(span);\n return result;\n } catch (error) {\n this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });\n this.logSpanTree(span);\n throw error;\n }\n });\n }\n\n // Fallback without AsyncLocalStorage\n try {\n const result = await fn();\n this.endSpan(span);\n this.logSpanTree(span);\n return result;\n } catch (error) {\n this.endSpan(span, { error: true, errorMessage: error instanceof Error ? error.message : String(error) });\n this.logSpanTree(span);\n throw error;\n }\n }\n\n public static getCurrentSpan(): Span | undefined {\n this.initialize();\n \n if (!this.enabled || !this.asyncLocalStorage) {\n return undefined;\n }\n\n return this.asyncLocalStorage.getStore();\n }\n\n public static logSpanTree(rootSpan: Span): void {\n if (!this.enabled || !rootSpan) {\n return;\n }\n\n const timestamp = new Date().toISOString();\n const lines: string[] = [];\n\n lines.push('');\n lines.push('╔══════════════════════════════════════════════════════════════╗');\n lines.push(`║ SKL Engine Performance Trace ║`);\n lines.push(`║ Started: ${timestamp} ║`);\n lines.push('╚══════════════════════════════════════════════════════════════╝');\n lines.push('');\n\n this.buildSpanTreeLines(rootSpan, lines, '', true);\n\n lines.push('');\n lines.push('═══════════════════════════════════════════════════════════════');\n lines.push('');\n\n // eslint-disable-next-line no-console\n console.log(lines.join('\\n'));\n }\n\n private static buildSpanTreeLines(\n span: Span,\n lines: string[],\n prefix: string,\n isRoot: boolean\n ): void {\n const duration = span.duration !== undefined ? `${span.duration.toFixed(2)}ms` : 'running...';\n const status = span.attributes.error ? '✗' : '✓';\n \n lines.push(`${prefix}${span.name} [${duration}] ${status}`);\n\n // Show important attributes\n this.addAttributeLines(span, lines, prefix);\n\n // Process children\n const childCount = span.children.length;\n span.children.forEach((child, index) => {\n const isLast = index === childCount - 1;\n const childPrefix = prefix + (isRoot ? '' : '│ ');\n const connector = isLast ? '└─ ' : '├─ ';\n const nextPrefix = prefix + (isRoot ? '' : (isLast ? ' ' : '│ '));\n \n this.buildSpanTreeLines(child, lines, childPrefix + connector, false);\n });\n }\n\n private static addAttributeLines(span: Span, lines: string[], prefix: string): void {\n const { query, resultCount, options, error, errorMessage, ...otherAttrs } = span.attributes;\n\n // Show query if present (and format it) - but make it easy to copy\n if (query && typeof query === 'string') {\n lines.push(`${prefix}│ Query:`);\n // Empty line before query\n lines.push(''); \n const formattedQuery = this.formatQuery(query);\n formattedQuery.split('\\n').forEach(line => {\n // Simple indentation without tree chars\n lines.push(` ${line}`); \n });\n // Empty line after query\n lines.push(''); \n }\n\n // Show result count\n if (resultCount !== undefined) {\n lines.push(`${prefix}│ Result: ${resultCount} ${resultCount === 1 ? 'row' : 'rows'}`);\n }\n\n // Show error if present\n if (error && errorMessage) {\n lines.push(`${prefix}│ Error: ${errorMessage}`);\n }\n\n // Show other important attributes\n if (Object.keys(otherAttrs).length > 0) {\n const attrStr = JSON.stringify(otherAttrs);\n if (attrStr.length < 100) {\n lines.push(`${prefix}│ Attributes: ${attrStr}`);\n }\n }\n }\n\n private static formatQuery(query: string): string {\n // Simple query formatting with proper indentation\n let formatted = query.trim();\n \n // Add line breaks after key SPARQL keywords for readability\n formatted = formatted\n .replace(/\\s+/g, ' ')\n .replace(/\\s*{\\s*/g, ' {\\n ')\n .replace(/\\s*}\\s*/g, '\\n}')\n .replace(/\\s*\\.\\s*(?=[?A-Z])/g, ' .\\n ')\n .replace(/\\bWHERE\\b/g, '\\nWHERE')\n .replace(/\\bFILTER\\b/g, '\\n FILTER')\n .replace(/\\bOPTIONAL\\b/g, '\\n OPTIONAL')\n .replace(/\\bUNION\\b/g, '\\nUNION')\n .replace(/\\bGRAPH\\b/g, '\\n GRAPH')\n .replace(/\\bORDER BY\\b/g, '\\nORDER BY')\n .replace(/\\bLIMIT\\b/g, '\\nLIMIT')\n .replace(/\\bOFFSET\\b/g, '\\nOFFSET');\n\n return formatted;\n }\n}\n\n"]}
|