@eagleoutice/flowr 2.1.2 → 2.1.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.
Files changed (108) hide show
  1. package/benchmark/slicer.js +1 -1
  2. package/cli/repl/commands/repl-parse.js +1 -1
  3. package/cli/repl/commands/repl-query.d.ts +0 -5
  4. package/cli/repl/commands/repl-query.js +4 -145
  5. package/cli/repl/server/connection.js +6 -1
  6. package/cli/repl/server/messages/message-query.js +2 -2
  7. package/cli/repl/server/net.js +1 -1
  8. package/cli/repl/server/send.js +3 -6
  9. package/cli/repl/server/server.d.ts +2 -2
  10. package/cli/repl/server/server.js +1 -1
  11. package/config.js +1 -1
  12. package/core/pipeline-executor.js +2 -1
  13. package/core/steps/all/core/00-parse.d.ts +11 -4
  14. package/core/steps/all/core/00-parse.js +5 -5
  15. package/core/steps/all/core/10-normalize.d.ts +2 -1
  16. package/core/steps/all/core/20-dataflow.d.ts +2 -2
  17. package/core/steps/all/core/20-dataflow.js +2 -2
  18. package/core/steps/pipeline/default-pipelines.d.ts +41 -23
  19. package/core/steps/pipeline/pipeline.d.ts +15 -3
  20. package/core/steps/pipeline/pipeline.js +2 -2
  21. package/dataflow/environments/built-in.d.ts +8 -6
  22. package/dataflow/environments/built-in.js +6 -1
  23. package/dataflow/environments/default-builtin-config.js +21 -5
  24. package/dataflow/environments/environment.d.ts +1 -0
  25. package/dataflow/environments/environment.js +5 -5
  26. package/dataflow/extractor.js +23 -0
  27. package/dataflow/graph/dataflowgraph-builder.d.ts +2 -0
  28. package/dataflow/graph/dataflowgraph-builder.js +9 -0
  29. package/dataflow/graph/diff.js +1 -1
  30. package/dataflow/graph/graph.d.ts +7 -2
  31. package/dataflow/graph/graph.js +10 -2
  32. package/dataflow/internal/process/functions/call/argument/unpack-argument.d.ts +1 -1
  33. package/dataflow/internal/process/functions/call/argument/unpack-argument.js +2 -2
  34. package/dataflow/internal/process/functions/call/built-in/built-in-assignment.js +2 -2
  35. package/dataflow/internal/process/functions/call/built-in/built-in-expression-list.js +1 -1
  36. package/dataflow/internal/process/functions/call/built-in/built-in-for-loop.js +1 -1
  37. package/dataflow/internal/process/functions/call/built-in/built-in-if-then-else.js +1 -1
  38. package/dataflow/internal/process/functions/call/built-in/built-in-pipe.js +1 -1
  39. package/dataflow/internal/process/functions/call/built-in/built-in-source.js +13 -1
  40. package/dataflow/internal/process/functions/call/built-in/built-in-while-loop.js +1 -1
  41. package/dataflow/internal/process/functions/call/named-call-handling.js +1 -1
  42. package/dataflow/processor.d.ts +3 -3
  43. package/documentation/data/server/doc-data-server-messages.js +9 -10
  44. package/documentation/doc-util/doc-cli-option.js +4 -4
  45. package/documentation/doc-util/doc-query.d.ts +3 -1
  46. package/documentation/doc-util/doc-query.js +16 -9
  47. package/documentation/doc-util/doc-repl.js +2 -2
  48. package/documentation/print-dataflow-graph-wiki.js +2 -1
  49. package/documentation/print-interface-wiki.js +8 -3
  50. package/documentation/print-query-wiki.js +139 -16
  51. package/package.json +3 -2
  52. package/queries/base-query-format.d.ts +6 -0
  53. package/queries/catalog/call-context-query/call-context-query-executor.d.ts +1 -1
  54. package/queries/catalog/call-context-query/call-context-query-executor.js +27 -81
  55. package/queries/catalog/call-context-query/call-context-query-format.d.ts +14 -13
  56. package/queries/catalog/call-context-query/call-context-query-format.js +32 -14
  57. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.d.ts +17 -0
  58. package/queries/catalog/call-context-query/identify-link-to-last-call-relation.js +99 -0
  59. package/queries/catalog/cluster-query/cluster-query-executor.d.ts +1 -1
  60. package/queries/catalog/cluster-query/cluster-query-format.d.ts +59 -0
  61. package/queries/catalog/cluster-query/cluster-query-format.js +29 -0
  62. package/queries/catalog/dataflow-query/dataflow-query-executor.d.ts +1 -1
  63. package/queries/catalog/dataflow-query/dataflow-query-format.d.ts +59 -0
  64. package/queries/catalog/dataflow-query/dataflow-query-format.js +21 -0
  65. package/queries/catalog/dependencies-query/dependencies-query-executor.d.ts +3 -0
  66. package/queries/catalog/dependencies-query/dependencies-query-executor.js +144 -0
  67. package/queries/catalog/dependencies-query/dependencies-query-format.d.ts +102 -0
  68. package/queries/catalog/dependencies-query/dependencies-query-format.js +187 -0
  69. package/queries/catalog/id-map-query/id-map-query-executor.d.ts +1 -1
  70. package/queries/catalog/id-map-query/id-map-query-format.d.ts +59 -0
  71. package/queries/catalog/id-map-query/id-map-query-format.js +21 -0
  72. package/queries/catalog/lineage-query/lineage-query-executor.d.ts +3 -0
  73. package/queries/catalog/lineage-query/lineage-query-executor.js +22 -0
  74. package/queries/catalog/lineage-query/lineage-query-format.d.ts +73 -0
  75. package/queries/catalog/lineage-query/lineage-query-format.js +27 -0
  76. package/queries/catalog/location-map-query/location-map-query-executor.d.ts +3 -0
  77. package/queries/catalog/location-map-query/location-map-query-executor.js +21 -0
  78. package/queries/catalog/location-map-query/location-map-query-format.d.ts +17 -0
  79. package/queries/catalog/location-map-query/location-map-query-format.js +24 -0
  80. package/queries/catalog/normalized-ast-query/normalized-ast-query-executor.d.ts +1 -1
  81. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.d.ts +59 -0
  82. package/queries/catalog/normalized-ast-query/normalized-ast-query-format.js +21 -0
  83. package/queries/catalog/static-slice-query/static-slice-query-executor.d.ts +1 -1
  84. package/queries/catalog/static-slice-query/static-slice-query-executor.js +8 -3
  85. package/queries/catalog/static-slice-query/static-slice-query-format.d.ts +59 -0
  86. package/queries/catalog/static-slice-query/static-slice-query-format.js +40 -0
  87. package/queries/query-print.d.ts +8 -0
  88. package/queries/query-print.js +94 -0
  89. package/queries/query.d.ts +431 -23
  90. package/queries/query.js +36 -16
  91. package/r-bridge/lang-4.x/ast/parser/json/parser.d.ts +2 -1
  92. package/r-bridge/lang-4.x/ast/parser/json/parser.js +2 -2
  93. package/r-bridge/lang-4.x/ast/parser/main/internal/functions/normalize-argument.js +2 -1
  94. package/r-bridge/retriever.js +1 -1
  95. package/r-bridge/shell-executor.js +1 -1
  96. package/r-bridge/shell.d.ts +1 -2
  97. package/r-bridge/shell.js +22 -18
  98. package/slicing/static/static-slicer.js +3 -1
  99. package/statistics/features/supported/used-functions/used-functions.js +1 -1
  100. package/{documentation/doc-util/doc-hover-over.js → util/html-hover-over.js} +1 -1
  101. package/util/json.d.ts +2 -1
  102. package/util/json.js +101 -3
  103. package/util/objects.d.ts +2 -1
  104. package/util/objects.js +3 -0
  105. package/util/version.js +1 -1
  106. package/queries/query-schema.d.ts +0 -12
  107. package/queries/query-schema.js +0 -50
  108. /package/{documentation/doc-util/doc-hover-over.d.ts → util/html-hover-over.d.ts} +0 -0
@@ -64,7 +64,7 @@ class BenchmarkSlicer {
64
64
  criterion: [],
65
65
  autoSelectIf
66
66
  });
67
- this.loadedXml = await this.measureCommonStep('parse', 'retrieve AST from R code');
67
+ this.loadedXml = (await this.measureCommonStep('parse', 'retrieve AST from R code')).parsed;
68
68
  this.normalizedAst = await this.measureCommonStep('normalize', 'normalize R AST');
69
69
  this.dataflow = await this.measureCommonStep('dataflow', 'produce dataflow information');
70
70
  this.pipeline.switchToRequestStage();
@@ -95,7 +95,7 @@ exports.parseCommand = {
95
95
  shell,
96
96
  request: (0, retriever_1.requestFromInput)((0, retriever_1.removeRQuotes)(remainingLine.trim()))
97
97
  }).allRemainingSteps();
98
- const object = (0, format_1.convertPreparedParsedData)((0, format_1.prepareParsedData)(result.parse));
98
+ const object = (0, format_1.convertPreparedParsedData)((0, format_1.prepareParsedData)(result.parse.parsed));
99
99
  output.stdout(depthListToTextTree(toDepthMap(object), output.formatter));
100
100
  }
101
101
  };
@@ -1,8 +1,3 @@
1
- import { DEFAULT_DATAFLOW_PIPELINE } from '../../../core/steps/pipeline/default-pipelines';
2
1
  import type { ReplCommand } from './repl-main';
3
- import type { OutputFormatter } from '../../../util/ansi';
4
- import type { QueryResults, SupportedQueryTypes } from '../../../queries/query';
5
- import type { PipelineOutput } from '../../../core/steps/pipeline/pipeline';
6
- export declare function asciiSummaryOfQueryResult(formatter: OutputFormatter, totalInMs: number, results: QueryResults<SupportedQueryTypes>, processed: PipelineOutput<typeof DEFAULT_DATAFLOW_PIPELINE>): string;
7
2
  export declare const queryCommand: ReplCommand;
8
3
  export declare const queryStarCommand: ReplCommand;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.queryStarCommand = exports.queryCommand = void 0;
4
- exports.asciiSummaryOfQueryResult = asciiSummaryOfQueryResult;
5
4
  const pipeline_executor_1 = require("../../../core/pipeline-executor");
6
5
  const default_pipelines_1 = require("../../../core/steps/pipeline/default-pipelines");
7
6
  const retriever_1 = require("../../../r-bridge/retriever");
@@ -10,12 +9,7 @@ const ansi_1 = require("../../../util/ansi");
10
9
  const schema_1 = require("../../../util/schema");
11
10
  const query_1 = require("../../../queries/query");
12
11
  const json_1 = require("../../../util/json");
13
- const query_schema_1 = require("../../../queries/query-schema");
14
- const built_in_1 = require("../../../dataflow/environments/built-in");
15
- const dfg_1 = require("../../../util/mermaid/dfg");
16
- const ast_1 = require("../../../util/mermaid/ast");
17
- const time_1 = require("../../../util/time");
18
- const doc_hover_over_1 = require("../../../documentation/doc-util/doc-hover-over");
12
+ const query_print_1 = require("../../../queries/query-print");
19
13
  async function getDataflow(shell, remainingLine) {
20
14
  return await new pipeline_executor_1.PipelineExecutor(default_pipelines_1.DEFAULT_DATAFLOW_PIPELINE, {
21
15
  shell,
@@ -25,7 +19,7 @@ async function getDataflow(shell, remainingLine) {
25
19
  function printHelp(output) {
26
20
  output.stderr(`Format: ${(0, ansi_1.italic)(':query "<query>" <code>', output.formatter)}`);
27
21
  output.stdout('The query is an array of query objects to represent multiple queries. Each query object may have the following properties:');
28
- output.stdout((0, schema_1.describeSchema)(query_schema_1.AnyQuerySchema, output.formatter));
22
+ output.stdout((0, schema_1.describeSchema)(query_1.AnyQuerySchema, output.formatter));
29
23
  output.stdout(`\n\nThe example ${(0, ansi_1.italic)(':query "[{\\"type\\": \\"call-context\\", \\"callName\\": \\"mean\\" }]" mean(1:10)', output.formatter)} would return the call context of the mean function.`);
30
24
  output.stdout('As a convenience, we interpret any (non-help) string not starting with \'[\' as a regex for the simple call-context query.');
31
25
  output.stdout(`Hence, ${(0, ansi_1.italic)(':query "mean" mean(1:10)', output.formatter)} is equivalent to the above example.`);
@@ -44,7 +38,7 @@ async function processQueryArgs(line, shell, output) {
44
38
  let parsedQuery = [];
45
39
  if (query.startsWith('[')) {
46
40
  parsedQuery = JSON.parse(query);
47
- const validationResult = query_schema_1.QueriesSchema.validate(parsedQuery);
41
+ const validationResult = query_1.QueriesSchema.validate(parsedQuery);
48
42
  if (validationResult.error) {
49
43
  output.stderr(`Invalid query: ${validationResult.error.message}`);
50
44
  printHelp(output);
@@ -60,141 +54,6 @@ async function processQueryArgs(line, shell, output) {
60
54
  processed
61
55
  };
62
56
  }
63
- function nodeString(id, formatter, processed) {
64
- if (id === built_in_1.BuiltIn) {
65
- return (0, ansi_1.italic)('built-in', formatter);
66
- }
67
- const node = processed.normalize.idMap.get(id);
68
- if (node === undefined) {
69
- return `UNKNOWN: ${id}`;
70
- }
71
- return `${(0, ansi_1.italic)('`' + (node.lexeme ?? node.info.fullLexeme ?? 'UNKNOWN') + '`', formatter)} (L.${node.location?.[0]})`;
72
- }
73
- function asciiCallContextSubHit(formatter, results, processed) {
74
- const result = [];
75
- for (const { id, calls = [], linkedIds = [], aliasRoots = [] } of results) {
76
- const node = processed.normalize.idMap.get(id);
77
- if (node === undefined) {
78
- result.push(` ${(0, ansi_1.bold)('UNKNOWN: ' + JSON.stringify({ calls, linkedIds }))}`);
79
- continue;
80
- }
81
- let line = nodeString(id, formatter, processed);
82
- if (calls.length > 0) {
83
- line += ` with ${calls.length} call${calls.length > 1 ? 's' : ''} (${calls.map(c => nodeString(c, formatter, processed)).join(', ')})`;
84
- }
85
- if (linkedIds.length > 0) {
86
- line += ` with ${linkedIds.length} link${linkedIds.length > 1 ? 's' : ''} (${linkedIds.map(c => nodeString(c, formatter, processed)).join(', ')})`;
87
- }
88
- if (aliasRoots.length > 0) {
89
- line += ` with ${aliasRoots.length} alias root${aliasRoots.length > 1 ? 's' : ''} (${aliasRoots.map(c => nodeString(c, formatter, processed)).join(', ')})`;
90
- }
91
- result.push(line);
92
- }
93
- return result.join(', ');
94
- }
95
- function asciiCallContext(formatter, results, processed) {
96
- /* traverse over 'kinds' and within them 'subkinds' */
97
- const result = [];
98
- for (const [kind, { subkinds }] of Object.entries(results['kinds'])) {
99
- result.push(` ╰ ${(0, ansi_1.bold)(kind, formatter)}`);
100
- for (const [subkind, values] of Object.entries(subkinds)) {
101
- result.push(` ╰ ${(0, ansi_1.bold)(subkind, formatter)}: ${asciiCallContextSubHit(formatter, values, processed)}`);
102
- }
103
- }
104
- return result.join('\n');
105
- }
106
- function summarizeIdsIfTooLong(ids) {
107
- const naive = ids.join(', ');
108
- if (naive.length <= 20) {
109
- return naive;
110
- }
111
- let acc = '';
112
- let i = 0;
113
- while (acc.length <= 20) {
114
- acc += ids[i++] + ', ';
115
- }
116
- if (i < ids.length) {
117
- acc += '... (see JSON below)';
118
- }
119
- return (0, doc_hover_over_1.textWithTooltip)(acc, JSON.stringify(ids));
120
- }
121
- function asciiSummaryOfQueryResult(formatter, totalInMs, results, processed) {
122
- const result = [];
123
- for (const [query, queryResults] of Object.entries(results)) {
124
- if (query === '.meta') {
125
- continue;
126
- }
127
- if (query === 'call-context') {
128
- const out = queryResults;
129
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
130
- result.push(asciiCallContext(formatter, out, processed));
131
- continue;
132
- }
133
- else if (query === 'dataflow') {
134
- const out = queryResults;
135
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
136
- result.push(` ╰ [Dataflow Graph](${(0, dfg_1.graphToMermaidUrl)(out.graph)})`);
137
- continue;
138
- }
139
- else if (query === 'id-map') {
140
- const out = queryResults;
141
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
142
- result.push(` ╰ Id List: {${summarizeIdsIfTooLong([...out.idMap.keys()])}}`);
143
- continue;
144
- }
145
- else if (query === 'normalized-ast') {
146
- const out = queryResults;
147
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
148
- result.push(` ╰ [Normalized AST](${(0, ast_1.normalizedAstToMermaidUrl)(out.normalized.ast)})`);
149
- continue;
150
- }
151
- else if (query === 'static-slice') {
152
- const out = queryResults;
153
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${(0, time_1.printAsMs)(out['.meta'].timing, 0)})`);
154
- for (const [fingerprint, obj] of Object.entries(out.results)) {
155
- const { criteria, noMagicComments, noReconstruction } = JSON.parse(fingerprint);
156
- const addons = [];
157
- if (noReconstruction) {
158
- addons.push('no reconstruction');
159
- }
160
- if (noMagicComments) {
161
- addons.push('no magic comments');
162
- }
163
- result.push(` ╰ Slice for {${criteria.join(', ')}} ${addons.join(', ')}`);
164
- if ('reconstruct' in obj) {
165
- result.push(' ╰ Code (newline as <code>&#92;n</code>): <code>' + obj.reconstruct.code.split('\n').join('\\n') + '</code>');
166
- }
167
- else {
168
- result.push(` ╰ Id List: {${summarizeIdsIfTooLong([...obj.slice.result])}}`);
169
- }
170
- }
171
- continue;
172
- }
173
- else if (query === 'dataflow-cluster') {
174
- const out = queryResults;
175
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)} (${out['.meta'].timing.toFixed(0)}ms)`);
176
- result.push(` ╰ Found ${out.clusters.length} cluster${out.clusters.length === 1 ? '' : 's'}`);
177
- for (const cluster of out.clusters) {
178
- const unknownSideEffects = cluster.hasUnknownSideEffects ? '(has unknown side effect)' : '';
179
- result.push(` ╰ ${unknownSideEffects} {${summarizeIdsIfTooLong(cluster.members)}} ([marked](${(0, dfg_1.graphToMermaidUrl)(processed.dataflow.graph, false, new Set(cluster.members))}))`);
180
- }
181
- continue;
182
- }
183
- result.push(`Query: ${(0, ansi_1.bold)(query, formatter)}`);
184
- let timing = -1;
185
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
186
- for (const [key, value] of Object.entries(queryResults)) {
187
- if (key === '.meta') {
188
- timing = value.timing;
189
- continue;
190
- }
191
- result.push(` ╰ ${key}: ${JSON.stringify(value)}`);
192
- }
193
- result.push(` - Took ${(0, time_1.printAsMs)(timing, 0)}`);
194
- }
195
- result.push((0, ansi_1.italic)(`All queries together required ≈${(0, time_1.printAsMs)(results['.meta'].timing, 0)} (1ms accuracy, total ${(0, time_1.printAsMs)(totalInMs, 0)})`, formatter));
196
- return formatter.format(result.join('\n'));
197
- }
198
57
  exports.queryCommand = {
199
58
  description: `Query the given R code, start with '${retriever_1.fileProtocol}' to indicate a file. The query is to be a valid query in json format (use 'help' to get more information).`,
200
59
  usageExample: ':query "<query>" <code>',
@@ -205,7 +64,7 @@ exports.queryCommand = {
205
64
  const results = await processQueryArgs(remainingLine, shell, output);
206
65
  const totalEnd = Date.now();
207
66
  if (results) {
208
- output.stdout(asciiSummaryOfQueryResult(output.formatter, totalEnd - totalStart, results.query, results.processed));
67
+ output.stdout((0, query_print_1.asciiSummaryOfQueryResult)(ansi_1.ansiFormatter, totalEnd - totalStart, results.query, results.processed));
209
68
  }
210
69
  }
211
70
  };
@@ -74,6 +74,9 @@ class FlowRServerConnection {
74
74
  this.logger = server_1.serverLog.getSubLogger({ name });
75
75
  this.socket.on('data', data => this.handleData(String(data)));
76
76
  this.socket.on('error', e => this.logger.error(`[${this.name}] Error while handling connection: ${String(e)}`));
77
+ this.socket.on('close', () => {
78
+ this.fileMap.clear();
79
+ });
77
80
  this.allowRSessionAccess = allowRSessionAccess;
78
81
  }
79
82
  currentMessageBuffer = '';
@@ -129,6 +132,8 @@ class FlowRServerConnection {
129
132
  this.logger.info(`[${this.name}] Received file analysis request for ${message.filename ?? 'unknown file'}${message.filetoken ? ' with token: ' + message.filetoken : ''}`);
130
133
  if (message.filetoken && this.fileMap.has(message.filetoken)) {
131
134
  this.logger.warn(`File token ${message.filetoken} already exists. Overwriting.`);
135
+ // explicitly delete the previous store
136
+ this.fileMap.delete(message.filetoken);
132
137
  }
133
138
  const tempFile = tmp.fileSync({ postfix: '.R' });
134
139
  const slicer = this.createPipelineExecutorForRequest(message, tempFile.name);
@@ -307,7 +312,7 @@ class FlowRServerConnection {
307
312
  return;
308
313
  }
309
314
  const request = requestResult.message;
310
- this.logger.info(`[${this.name}] Received query request for query ${JSON.stringify(request.query)}`);
315
+ this.logger.info(`[${this.name}] Received query request`);
311
316
  const fileInformation = this.fileMap.get(request.filetoken);
312
317
  if (!fileInformation) {
313
318
  (0, send_1.sendMessage)(this.socket, {
@@ -5,14 +5,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.responseQueryMessage = exports.requestQueryMessage = void 0;
7
7
  const joi_1 = __importDefault(require("joi"));
8
- const query_schema_1 = require("../../../../queries/query-schema");
8
+ const query_1 = require("../../../../queries/query");
9
9
  exports.requestQueryMessage = {
10
10
  type: 'request-query',
11
11
  schema: joi_1.default.object({
12
12
  type: joi_1.default.string().valid('request-query').required().description('The type of the message.'),
13
13
  id: joi_1.default.string().optional().description('If you give the id, the response will be sent to the client with the same id.'),
14
14
  filetoken: joi_1.default.string().required().description('The filetoken of the file/data retrieved from the analysis request.'),
15
- query: query_schema_1.QueriesSchema.required().description('The query to run on the file analysis information.')
15
+ query: query_1.QueriesSchema.required().description('The query to run on the file analysis information.')
16
16
  }).description('Request a query to be run on the file analysis information.')
17
17
  };
18
18
  exports.responseQueryMessage = {
@@ -17,7 +17,7 @@ class WebSocketServerWrapper {
17
17
  this.connectHandler = handler;
18
18
  }
19
19
  start(port) {
20
- this.server = new ws_1.WebSocketServer({ port });
20
+ this.server = new ws_1.WebSocketServer({ port, maxPayload: 1024 * 1024 * 1024 * 1024 });
21
21
  server_1.serverLog.info('WebSocket-Server wrapper is active!');
22
22
  this.server.on('connection', c => this.connectHandler?.(new WebSocketWrapper(c)));
23
23
  }
@@ -2,16 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getUnnamedSocketName = getUnnamedSocketName;
4
4
  exports.sendMessage = sendMessage;
5
- const server_1 = require("./server");
6
5
  const json_1 = require("../../../util/json");
7
6
  function getUnnamedSocketName(c) {
8
7
  return `${c.remoteAddress ?? '?'}@${c.remotePort ?? '?'}`;
9
8
  }
10
9
  function sendMessage(c, message) {
11
- const msg = JSON.stringify(message, json_1.jsonReplacer);
12
- if (server_1.serverLog.settings.minLevel >= 2 /* LogLevel.Debug */) {
13
- server_1.serverLog.debug(`[${getUnnamedSocketName(c)}] sending message: ${msg}`);
14
- }
15
- c.write(`${msg}\n`);
10
+ return (0, json_1.superBigJsonStringify)(message, '\n', msg => {
11
+ c.write(msg);
12
+ });
16
13
  }
17
14
  //# sourceMappingURL=send.js.map
@@ -11,9 +11,9 @@ export declare class FlowRServer {
11
11
  private readonly server;
12
12
  private readonly shell;
13
13
  private versionInformation;
14
- private allowRSessionAccess;
14
+ private readonly allowRSessionAccess;
15
15
  /** maps names to the respective connection */
16
- private connections;
16
+ private readonly connections;
17
17
  private nameCounter;
18
18
  constructor(shell: RShell, allowRSessionAccess: boolean, server?: Server);
19
19
  start(port: number): Promise<void>;
@@ -17,7 +17,7 @@ class FlowRServer {
17
17
  server;
18
18
  shell;
19
19
  versionInformation;
20
- allowRSessionAccess = false;
20
+ allowRSessionAccess;
21
21
  /** maps names to the respective connection */
22
22
  connections = new Map();
23
23
  nameCounter = 0;
package/config.js CHANGED
@@ -41,7 +41,7 @@ exports.flowrConfigFileSchema = joi_1.default.object({
41
41
  // we don't load from a config file at all by default unless setConfigFile is called
42
42
  let configFile = undefined;
43
43
  let configWorkingDirectory = process.cwd();
44
- let currentConfig;
44
+ let currentConfig = undefined;
45
45
  function setConfigFile(file, workingDirectory = process.cwd(), forceLoad = false) {
46
46
  configFile = file;
47
47
  configWorkingDirectory = workingDirectory;
@@ -169,9 +169,10 @@ class PipelineExecutor {
169
169
  * _Without `expectedStepName`, please refrain from accessing the result, as you have no safeguards if the pipeline changes._
170
170
  */
171
171
  async nextStep(expectedStepName) {
172
+ const start = Date.now();
172
173
  const [step, result] = this._doNextStep(expectedStepName);
173
174
  const awaitedResult = await result;
174
- this.output[step] = awaitedResult;
175
+ this.output[step] = { ...awaitedResult, '.meta': { timing: Date.now() - start } };
175
176
  this.stepCounter++;
176
177
  return { name: step, result: awaitedResult };
177
178
  }
@@ -1,16 +1,20 @@
1
1
  import { internalPrinter } from '../../../print/print';
2
- import { parseToQuads } from '../../../print/parse-printer';
3
2
  import { PipelineStepStage } from '../../pipeline-step';
4
3
  import type { RShellExecutor } from '../../../../r-bridge/shell-executor';
5
4
  import type { RShell } from '../../../../r-bridge/shell';
6
5
  import type { RParseRequests } from '../../../../r-bridge/retriever';
6
+ import type { QuadSerializationConfiguration } from '../../../../util/quads';
7
7
  export interface ParseRequiredInput {
8
8
  /** This is the {@link RShell} or {@link RShellExecutor} connection to be used to obtain the original parses AST of the R code */
9
9
  readonly shell: RShell | RShellExecutor;
10
10
  /** The request which essentially indicates the input to extract the AST from */
11
11
  readonly request: RParseRequests;
12
12
  }
13
- declare function processor(_results: unknown, input: Partial<ParseRequiredInput>): Promise<string>;
13
+ export interface ParseStepOutput {
14
+ /** The parsed AST of the R code as given by the R parse side */
15
+ readonly parsed: string;
16
+ }
17
+ declare function processor(_results: unknown, input: Partial<ParseRequiredInput>): Promise<ParseStepOutput>;
14
18
  export declare const PARSE_WITH_R_SHELL_STEP: {
15
19
  readonly name: "parse";
16
20
  readonly humanReadableName: "parse with R shell";
@@ -19,8 +23,11 @@ export declare const PARSE_WITH_R_SHELL_STEP: {
19
23
  readonly executed: PipelineStepStage.OncePerFile;
20
24
  readonly printer: {
21
25
  readonly 0: typeof internalPrinter;
22
- readonly 2: (text: string) => string;
23
- readonly 5: typeof parseToQuads;
26
+ readonly 2: {
27
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
28
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
29
+ };
30
+ readonly 5: ({ parsed }: ParseStepOutput, config: QuadSerializationConfiguration) => string;
24
31
  };
25
32
  readonly dependencies: readonly [];
26
33
  readonly requiredInput: ParseRequiredInput;
@@ -4,13 +4,13 @@ exports.PARSE_WITH_R_SHELL_STEP = void 0;
4
4
  const print_1 = require("../../../print/print");
5
5
  const parse_printer_1 = require("../../../print/parse-printer");
6
6
  const retriever_1 = require("../../../../r-bridge/retriever");
7
- function processor(_results, input) {
7
+ async function processor(_results, input) {
8
8
  /* in the future, we want to expose all cases */
9
9
  if (Array.isArray(input.request)) {
10
- return (0, retriever_1.retrieveParseDataFromRCode)(input.request[0], input.shell);
10
+ return { parsed: await (0, retriever_1.retrieveParseDataFromRCode)(input.request[0], input.shell) };
11
11
  }
12
12
  else {
13
- return (0, retriever_1.retrieveParseDataFromRCode)(input.request, input.shell);
13
+ return { parsed: await (0, retriever_1.retrieveParseDataFromRCode)(input.request, input.shell) };
14
14
  }
15
15
  }
16
16
  exports.PARSE_WITH_R_SHELL_STEP = {
@@ -21,8 +21,8 @@ exports.PARSE_WITH_R_SHELL_STEP = {
21
21
  executed: 0 /* PipelineStepStage.OncePerFile */,
22
22
  printer: {
23
23
  [0 /* StepOutputFormat.Internal */]: print_1.internalPrinter,
24
- [2 /* StepOutputFormat.Json */]: text => text,
25
- [5 /* StepOutputFormat.RdfQuads */]: parse_printer_1.parseToQuads
24
+ [2 /* StepOutputFormat.Json */]: JSON.stringify,
25
+ [5 /* StepOutputFormat.RdfQuads */]: ({ parsed }, config) => (0, parse_printer_1.parseToQuads)(parsed, config)
26
26
  },
27
27
  dependencies: [],
28
28
  requiredInput: undefined
@@ -3,12 +3,13 @@ import { normalizedAstToJson, normalizedAstToQuads, printNormalizedAstToMermaid,
3
3
  import { PipelineStepStage } from '../../pipeline-step';
4
4
  import type { IdGenerator } from '../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
5
5
  import type { NoInfo } from '../../../../r-bridge/lang-4.x/ast/model/model';
6
+ import type { ParseStepOutput } from './00-parse';
6
7
  export interface NormalizeRequiredInput {
7
8
  /** This id generator is only necessary if you want to retrieve a dataflow from the parsed R AST, it determines the id generator to use and by default uses the {@link deterministicCountingIdGenerator}*/
8
9
  readonly getId?: IdGenerator<NoInfo>;
9
10
  }
10
11
  declare function processor(results: {
11
- parse?: string;
12
+ parse?: ParseStepOutput;
12
13
  }, input: Partial<NormalizeRequiredInput>): import("../../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../../../r-bridge/lang-4.x/ast/model/model").RNode<import("../../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
13
14
  export declare const NORMALIZE: {
14
15
  readonly name: "normalize";
@@ -3,14 +3,14 @@ import { PipelineStepStage } from '../../pipeline-step';
3
3
  import { dataflowGraphToJson, dataflowGraphToMermaid, dataflowGraphToMermaidUrl, dataflowGraphToQuads } from '../../../print/dataflow-printer';
4
4
  import type { NormalizedAst } from '../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
5
5
  import type { RParseRequests } from '../../../../r-bridge/retriever';
6
- declare function legacyProcessor(results: {
6
+ declare function processor(results: {
7
7
  normalize?: NormalizedAst;
8
8
  }, input: {
9
9
  request?: RParseRequests;
10
10
  }): import("../../../../dataflow/info").DataflowInformation;
11
11
  export declare const STATIC_DATAFLOW: {
12
12
  readonly humanReadableName: "dataflow";
13
- readonly processor: typeof legacyProcessor;
13
+ readonly processor: typeof processor;
14
14
  readonly requiredInput: {};
15
15
  readonly name: "dataflow";
16
16
  readonly description: "Construct the dataflow graph";
@@ -17,13 +17,13 @@ const staticDataflowCommon = {
17
17
  },
18
18
  dependencies: ['normalize'],
19
19
  };
20
- function legacyProcessor(results, input) {
20
+ function processor(results, input) {
21
21
  return (0, extractor_1.produceDataFlowGraph)(input.request, results.normalize);
22
22
  }
23
23
  exports.STATIC_DATAFLOW = {
24
24
  ...staticDataflowCommon,
25
25
  humanReadableName: 'dataflow',
26
- processor: legacyProcessor,
26
+ processor,
27
27
  requiredInput: {}
28
28
  };
29
29
  //# sourceMappingURL=20-dataflow.js.map
@@ -2,12 +2,15 @@ export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
2
2
  readonly name: "parse";
3
3
  readonly humanReadableName: "parse with R shell";
4
4
  readonly description: "Parse the given R code into an AST";
5
- readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<string>;
5
+ readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<import("../all/core/00-parse").ParseStepOutput>;
6
6
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
7
7
  readonly printer: {
8
8
  readonly 0: typeof import("../../print/print").internalPrinter;
9
- readonly 2: (text: string) => string;
10
- readonly 5: typeof import("../../print/parse-printer").parseToQuads;
9
+ readonly 2: {
10
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
11
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
12
+ };
13
+ readonly 5: ({ parsed }: import("../all/core/00-parse").ParseStepOutput, config: import("../../../util/quads").QuadSerializationConfiguration) => string;
11
14
  };
12
15
  readonly dependencies: readonly [];
13
16
  readonly requiredInput: import("../all/core/00-parse").ParseRequiredInput;
@@ -16,7 +19,7 @@ export declare const DEFAULT_SLICING_PIPELINE: import("./pipeline").Pipeline<{
16
19
  readonly humanReadableName: "normalize";
17
20
  readonly description: "Normalize the AST to flowR's AST";
18
21
  readonly processor: (results: {
19
- parse?: string;
22
+ parse?: import("../all/core/00-parse").ParseStepOutput;
20
23
  }, input: Partial<import("../all/core/10-normalize").NormalizeRequiredInput>) => import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../../r-bridge/lang-4.x/ast/model/model").RNode<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
21
24
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
22
25
  readonly printer: {
@@ -80,12 +83,15 @@ export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline"
80
83
  readonly name: "parse";
81
84
  readonly humanReadableName: "parse with R shell";
82
85
  readonly description: "Parse the given R code into an AST";
83
- readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<string>;
86
+ readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<import("../all/core/00-parse").ParseStepOutput>;
84
87
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
85
88
  readonly printer: {
86
89
  readonly 0: typeof import("../../print/print").internalPrinter;
87
- readonly 2: (text: string) => string;
88
- readonly 5: typeof import("../../print/parse-printer").parseToQuads;
90
+ readonly 2: {
91
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
92
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
93
+ };
94
+ readonly 5: ({ parsed }: import("../all/core/00-parse").ParseStepOutput, config: import("../../../util/quads").QuadSerializationConfiguration) => string;
89
95
  };
90
96
  readonly dependencies: readonly [];
91
97
  readonly requiredInput: import("../all/core/00-parse").ParseRequiredInput;
@@ -94,7 +100,7 @@ export declare const DEFAULT_SLICE_AND_RECONSTRUCT_PIPELINE: import("./pipeline"
94
100
  readonly humanReadableName: "normalize";
95
101
  readonly description: "Normalize the AST to flowR's AST";
96
102
  readonly processor: (results: {
97
- parse?: string;
103
+ parse?: import("../all/core/00-parse").ParseStepOutput;
98
104
  }, input: Partial<import("../all/core/10-normalize").NormalizeRequiredInput>) => import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../../r-bridge/lang-4.x/ast/model/model").RNode<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
99
105
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
100
106
  readonly printer: {
@@ -158,12 +164,15 @@ export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipel
158
164
  readonly name: "parse";
159
165
  readonly humanReadableName: "parse with R shell";
160
166
  readonly description: "Parse the given R code into an AST";
161
- readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<string>;
167
+ readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<import("../all/core/00-parse").ParseStepOutput>;
162
168
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
163
169
  readonly printer: {
164
170
  readonly 0: typeof import("../../print/print").internalPrinter;
165
- readonly 2: (text: string) => string;
166
- readonly 5: typeof import("../../print/parse-printer").parseToQuads;
171
+ readonly 2: {
172
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
173
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
174
+ };
175
+ readonly 5: ({ parsed }: import("../all/core/00-parse").ParseStepOutput, config: import("../../../util/quads").QuadSerializationConfiguration) => string;
167
176
  };
168
177
  readonly dependencies: readonly [];
169
178
  readonly requiredInput: import("../all/core/00-parse").ParseRequiredInput;
@@ -172,7 +181,7 @@ export declare const DEFAULT_SLICE_WITHOUT_RECONSTRUCT_PIPELINE: import("./pipel
172
181
  readonly humanReadableName: "normalize";
173
182
  readonly description: "Normalize the AST to flowR's AST";
174
183
  readonly processor: (results: {
175
- parse?: string;
184
+ parse?: import("../all/core/00-parse").ParseStepOutput;
176
185
  }, input: Partial<import("../all/core/10-normalize").NormalizeRequiredInput>) => import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../../r-bridge/lang-4.x/ast/model/model").RNode<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
177
186
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
178
187
  readonly printer: {
@@ -222,12 +231,15 @@ export declare const DEFAULT_DATAFLOW_PIPELINE: import("./pipeline").Pipeline<{
222
231
  readonly name: "parse";
223
232
  readonly humanReadableName: "parse with R shell";
224
233
  readonly description: "Parse the given R code into an AST";
225
- readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<string>;
234
+ readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<import("../all/core/00-parse").ParseStepOutput>;
226
235
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
227
236
  readonly printer: {
228
237
  readonly 0: typeof import("../../print/print").internalPrinter;
229
- readonly 2: (text: string) => string;
230
- readonly 5: typeof import("../../print/parse-printer").parseToQuads;
238
+ readonly 2: {
239
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
240
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
241
+ };
242
+ readonly 5: ({ parsed }: import("../all/core/00-parse").ParseStepOutput, config: import("../../../util/quads").QuadSerializationConfiguration) => string;
231
243
  };
232
244
  readonly dependencies: readonly [];
233
245
  readonly requiredInput: import("../all/core/00-parse").ParseRequiredInput;
@@ -236,7 +248,7 @@ export declare const DEFAULT_DATAFLOW_PIPELINE: import("./pipeline").Pipeline<{
236
248
  readonly humanReadableName: "normalize";
237
249
  readonly description: "Normalize the AST to flowR's AST";
238
250
  readonly processor: (results: {
239
- parse?: string;
251
+ parse?: import("../all/core/00-parse").ParseStepOutput;
240
252
  }, input: Partial<import("../all/core/10-normalize").NormalizeRequiredInput>) => import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../../r-bridge/lang-4.x/ast/model/model").RNode<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
241
253
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
242
254
  readonly printer: {
@@ -272,12 +284,15 @@ export declare const DEFAULT_NORMALIZE_PIPELINE: import("./pipeline").Pipeline<{
272
284
  readonly name: "parse";
273
285
  readonly humanReadableName: "parse with R shell";
274
286
  readonly description: "Parse the given R code into an AST";
275
- readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<string>;
287
+ readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<import("../all/core/00-parse").ParseStepOutput>;
276
288
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
277
289
  readonly printer: {
278
290
  readonly 0: typeof import("../../print/print").internalPrinter;
279
- readonly 2: (text: string) => string;
280
- readonly 5: typeof import("../../print/parse-printer").parseToQuads;
291
+ readonly 2: {
292
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
293
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
294
+ };
295
+ readonly 5: ({ parsed }: import("../all/core/00-parse").ParseStepOutput, config: import("../../../util/quads").QuadSerializationConfiguration) => string;
281
296
  };
282
297
  readonly dependencies: readonly [];
283
298
  readonly requiredInput: import("../all/core/00-parse").ParseRequiredInput;
@@ -286,7 +301,7 @@ export declare const DEFAULT_NORMALIZE_PIPELINE: import("./pipeline").Pipeline<{
286
301
  readonly humanReadableName: "normalize";
287
302
  readonly description: "Normalize the AST to flowR's AST";
288
303
  readonly processor: (results: {
289
- parse?: string;
304
+ parse?: import("../all/core/00-parse").ParseStepOutput;
290
305
  }, input: Partial<import("../all/core/10-normalize").NormalizeRequiredInput>) => import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").NormalizedAst<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation, import("../../../r-bridge/lang-4.x/ast/model/model").RNode<import("../../../r-bridge/lang-4.x/ast/model/processing/decorate").ParentInformation>>;
291
306
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
292
307
  readonly printer: {
@@ -303,12 +318,15 @@ export declare const DEFAULT_PARSE_PIPELINE: import("./pipeline").Pipeline<{
303
318
  readonly name: "parse";
304
319
  readonly humanReadableName: "parse with R shell";
305
320
  readonly description: "Parse the given R code into an AST";
306
- readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<string>;
321
+ readonly processor: (_results: unknown, input: Partial<import("../all/core/00-parse").ParseRequiredInput>) => Promise<import("../all/core/00-parse").ParseStepOutput>;
307
322
  readonly executed: import("../pipeline-step").PipelineStepStage.OncePerFile;
308
323
  readonly printer: {
309
324
  readonly 0: typeof import("../../print/print").internalPrinter;
310
- readonly 2: (text: string) => string;
311
- readonly 5: typeof import("../../print/parse-printer").parseToQuads;
325
+ readonly 2: {
326
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
327
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): string;
328
+ };
329
+ readonly 5: ({ parsed }: import("../all/core/00-parse").ParseStepOutput, config: import("../../../util/quads").QuadSerializationConfiguration) => string;
312
330
  };
313
331
  readonly dependencies: readonly [];
314
332
  readonly requiredInput: import("../all/core/00-parse").ParseRequiredInput;