theprogrammablemind 9.8.0 → 9.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.js +18 -30
- package/index.js +2 -1
- package/lines.js +1 -1
- package/package.json +3 -1
- package/src/config.js +41 -40
- package/src/configHelpers.js +52 -22
- package/src/fragments.js +17 -2
- package/src/generators.js +22 -13
- package/src/helpers.js +82 -9
- package/src/project2.js +24 -18
- package/src/semantics.js +25 -15
package/client.js
CHANGED
|
@@ -12,7 +12,7 @@ const _ = require('lodash')
|
|
|
12
12
|
const stringify = require('json-stable-stringify')
|
|
13
13
|
const Lines = require('./lines')
|
|
14
14
|
const flattens = require('./src/flatten')
|
|
15
|
-
const { helpDebugHierarchy, sortJson, appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps, OverrideCheck, } = require('./src/helpers')
|
|
15
|
+
const { helpDebugHierarchy, sortJson, appendNoDups, InitCalls, updateQueries, safeNoDups, stableId, where, suggestAssociationsFix, suggestAssociationsFixFromSummaries, validProps, OverrideCheck, removeProp, } = require('./src/helpers')
|
|
16
16
|
const runtime = require('./runtime')
|
|
17
17
|
const db = require('./src/debug')
|
|
18
18
|
|
|
@@ -59,20 +59,11 @@ const pickObjects = (config, testConfig, getObjects) => {
|
|
|
59
59
|
throw new Error(`In the checks for ${config.name} the KM ${km} does not exist`)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
} else {
|
|
66
|
-
projection[km] = project(objects, checks[km])
|
|
67
|
-
}
|
|
68
|
-
} else {
|
|
69
|
-
const lastIndex = contextChecks.length - 1
|
|
70
|
-
const last = contextChecks[lastIndex]
|
|
71
|
-
contextChecks[lastIndex] = { match: last.match, apply: () => [...new Set([...(checks[km] || []), ...last.apply()])] }
|
|
62
|
+
const lastIndex = contextChecks.length - 1
|
|
63
|
+
const last = contextChecks[lastIndex]
|
|
64
|
+
contextChecks[lastIndex] = { match: last.match, apply: () => [...new Set([...(checks[km] || []), ...last.apply()])] }
|
|
72
65
|
|
|
73
|
-
|
|
74
|
-
projection[km] = project2(objects, contextChecks)
|
|
75
|
-
}
|
|
66
|
+
projection[km] = project2(objects, contextChecks)
|
|
76
67
|
}
|
|
77
68
|
return projection
|
|
78
69
|
}
|
|
@@ -167,13 +158,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
|
|
|
167
158
|
if (runtime.fs.existsSync(fn)) {
|
|
168
159
|
tests = JSON.parse(runtime.fs.readFileSync(fn))
|
|
169
160
|
}
|
|
170
|
-
/*
|
|
171
|
-
for (const association of associations) {
|
|
172
|
-
association.sort()
|
|
173
|
-
}
|
|
174
|
-
associations.sort()
|
|
175
|
-
*/
|
|
176
|
-
// tests[query] = sortJson({ paraphrases, responses, contexts, objects: convertToStable(objects), associations, metadata, config, developerTest: saveDeveloper }, { depth: 25 })
|
|
177
161
|
const results = sortJson({
|
|
178
162
|
query,
|
|
179
163
|
summaries,
|
|
@@ -198,7 +182,6 @@ const writeTest = (fn, query, objects, generated, paraphrases, responses, contex
|
|
|
198
182
|
if (!wasSet) {
|
|
199
183
|
tests.push(results)
|
|
200
184
|
}
|
|
201
|
-
// fs.writeFileSync(fn, stringify(tests, { space: 2 }), { encoding: 'utf8', flag: 'w+' })
|
|
202
185
|
writeTestFile(fn, tests)
|
|
203
186
|
}
|
|
204
187
|
|
|
@@ -267,7 +250,7 @@ const throwErrorHandler = (error) => {
|
|
|
267
250
|
throw error
|
|
268
251
|
}
|
|
269
252
|
|
|
270
|
-
const _process = async (config, query, { queryNumber, initializer, commandLineArgs, credentials, writeTests, logs, isProcess, isModule, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = throwErrorHandler } = {}) => {
|
|
253
|
+
const _process = async (config, query, { isFragment, queryNumber, initializer, commandLineArgs, credentials, writeTests, logs, isProcess, isModule, isTest, saveDeveloper, rebuildingTemplate, testConfig, testsFN, errorHandler = throwErrorHandler } = {}) => {
|
|
271
254
|
if (credentials) {
|
|
272
255
|
config.server(credentials.server, credentials.key)
|
|
273
256
|
}
|
|
@@ -373,7 +356,7 @@ const _process = async (config, query, { queryNumber, initializer, commandLineAr
|
|
|
373
356
|
const summary = { summaries: json.summaries, length: json.contexts.length }
|
|
374
357
|
summaries.push(summary)
|
|
375
358
|
const { updatedContextIdCounter, contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
|
376
|
-
await processContextsB({ contextIdCounter, logs, calls, isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
|
359
|
+
await processContextsB({ skipSemantics: isFragment, isFragment, contextIdCounter, logs, calls, isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
|
377
360
|
contextIdCounter = updatedContextIdCounter
|
|
378
361
|
if (isTest) {
|
|
379
362
|
const end = runtime.performance.performance.now()
|
|
@@ -390,9 +373,9 @@ const _process = async (config, query, { queryNumber, initializer, commandLineAr
|
|
|
390
373
|
response.trace = response.trace.concat(json.trace)
|
|
391
374
|
response.version = json.version
|
|
392
375
|
response.explain_priorities = json.explain_priorities
|
|
393
|
-
response.
|
|
376
|
+
response.explain_associations_details = (response.explain_associations_details || []).concat(json.explain_associations_details)
|
|
377
|
+
response.explain_associations_trie = json.explain_associations_trie
|
|
394
378
|
response.contextual_priorities_ambiguities = json.contextual_priorities_ambiguities
|
|
395
|
-
// response.rtf_associations = json.rtf_associations
|
|
396
379
|
|
|
397
380
|
response.contexts = response.contexts.concat(contextsPrime)
|
|
398
381
|
response.generated = response.generated.concat(generatedPrime)
|
|
@@ -895,8 +878,11 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
|
895
878
|
}
|
|
896
879
|
}
|
|
897
880
|
|
|
898
|
-
if (responses.
|
|
899
|
-
console.log(responses.
|
|
881
|
+
if (responses.explain_associations_details) {
|
|
882
|
+
console.log(responses.explain_associations_trie)
|
|
883
|
+
for (const l of responses.explain_associations_details) {
|
|
884
|
+
console.log(l)
|
|
885
|
+
}
|
|
900
886
|
}
|
|
901
887
|
|
|
902
888
|
// const objects = config.get('objects').namespaced[config.uuid]
|
|
@@ -907,6 +893,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
|
907
893
|
const km = config.configs.find((km) => km.name === name)
|
|
908
894
|
return config.config.objects.namespaced[km.uuid] || {}
|
|
909
895
|
}
|
|
896
|
+
|
|
910
897
|
const picked = sortJson(pickObjects(config, config.testConfig, actualGetObjects), { depth: 25 })
|
|
911
898
|
if (!_.isEmpty(picked)) {
|
|
912
899
|
console.log('--- Object showing only the checked values ---')
|
|
@@ -1041,7 +1028,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
|
|
|
1041
1028
|
await loadInstance(config, { resultss: [results] })
|
|
1042
1029
|
} else {
|
|
1043
1030
|
try {
|
|
1044
|
-
results = await _process(config, query.query, { initializer, rebuildingTemplate: true })
|
|
1031
|
+
results = await _process(config, query.query, { initializer, rebuildingTemplate: true, isFragment })
|
|
1045
1032
|
} catch (e) {
|
|
1046
1033
|
if (e.summaries && e.summaries.length > 0) {
|
|
1047
1034
|
suggestFix(e.summaries)
|
|
@@ -1069,7 +1056,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
|
|
|
1069
1056
|
results.isFragment = isFragment
|
|
1070
1057
|
results.skipSemantics = skipSemantics
|
|
1071
1058
|
results.development = query.development
|
|
1072
|
-
results.key = { query: query.query, hierarchy }
|
|
1059
|
+
results.key = { query: query.query, hierarchy, preserve: query.preserve }
|
|
1073
1060
|
accumulators[property].push(results)
|
|
1074
1061
|
if (isFragment) {
|
|
1075
1062
|
config.fragmentsBeingBuilt.push({ query: query.query, contexts: results.contexts })
|
|
@@ -1135,6 +1122,7 @@ const rebuildTemplate = async ({ config, instance, target, previousResultss, reb
|
|
|
1135
1122
|
const stabilizeOutput = (template) => {
|
|
1136
1123
|
// stabilizeAssociations(template.associations)
|
|
1137
1124
|
const stabilize = (results) => {
|
|
1125
|
+
removeProp(results, (_, k) => k === "context_id")
|
|
1138
1126
|
for (let i = 0; i < results.length; ++i) {
|
|
1139
1127
|
const result = results[i]
|
|
1140
1128
|
if (result.apply) {
|
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Semantics, Semantic } = require('./src/semantics')
|
|
2
2
|
const { Generators, Generator } = require('./src/generators')
|
|
3
3
|
const { Config } = require('./src/config')
|
|
4
|
-
const { w, where, OverrideCheck, setByPath, getByPath } = require('./src/helpers')
|
|
4
|
+
const { w, where, OverrideCheck, setByPath, getByPath, removeProp } = require('./src/helpers')
|
|
5
5
|
const Digraph = require('./src/digraph')
|
|
6
6
|
const client = require('./client')
|
|
7
7
|
const flattens = require('./src/flatten')
|
|
@@ -32,4 +32,5 @@ module.exports = {
|
|
|
32
32
|
unflatten: unflatten.unflatten,
|
|
33
33
|
debug,
|
|
34
34
|
OverrideCheck,
|
|
35
|
+
removeProp,
|
|
35
36
|
}
|
package/lines.js
CHANGED
package/package.json
CHANGED
|
@@ -18,9 +18,11 @@
|
|
|
18
18
|
"test:debug": "node inspect node_modules/.bin/jest --runInBand --config ./jest.config.json",
|
|
19
19
|
"td": "node inspect node_modules/.bin/jest --runInBand --config ./jest.config.json",
|
|
20
20
|
"tod": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
|
|
21
|
+
"toda": "node inspect node_modules/.bin/jest --runInBand -t NEO23A",
|
|
21
22
|
"lint:fix": "eslint \"**/*.js\" --fix",
|
|
22
23
|
"lint": "eslint \"**/*.js\"",
|
|
23
24
|
"to": "node node_modules/.bin/jest --runInBand -t NEO23",
|
|
25
|
+
"toa": "node node_modules/.bin/jest --runInBand -t NEO23A",
|
|
24
26
|
"tos": "node node_modules/.bin/jest --runInBand -t NEOS23",
|
|
25
27
|
"test": "jest --config ./jest.config.json",
|
|
26
28
|
"test:python": "node node_modules/.bin/jest --runInBand -t PYTHON",
|
|
@@ -73,6 +75,6 @@
|
|
|
73
75
|
"scriptjs": "^2.5.9",
|
|
74
76
|
"uuid": "^8.3.2"
|
|
75
77
|
},
|
|
76
|
-
"version": "9.
|
|
78
|
+
"version": "9.9.0",
|
|
77
79
|
"license": "UNLICENSED"
|
|
78
80
|
}
|
package/src/config.js
CHANGED
|
@@ -295,9 +295,6 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
295
295
|
if (bridge.scope && config.isModule) {
|
|
296
296
|
return
|
|
297
297
|
}
|
|
298
|
-
if (false && !bridge.bridge) {
|
|
299
|
-
bridge.bridge = '{ ...next(operator) }'
|
|
300
|
-
}
|
|
301
298
|
if (!bridge.level) {
|
|
302
299
|
bridge.level = 0
|
|
303
300
|
}
|
|
@@ -391,6 +388,13 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
391
388
|
}
|
|
392
389
|
*/
|
|
393
390
|
|
|
391
|
+
if (!bridge.where) {
|
|
392
|
+
if (bridge.generator || bridge.generatorp || bridge.generatorr || bridge.generator ||
|
|
393
|
+
bridge.semantic || bridge.semantics) {
|
|
394
|
+
throw new Error(`In the KM "${config.name}", for the bridge ${bridge.id} the where property is missing. Use where: where().`)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
394
398
|
const addUUID = (obj) => { return { ...obj, uuid: uuid || config.uuid } }
|
|
395
399
|
|
|
396
400
|
if (bridge.generators) {
|
|
@@ -469,7 +473,7 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
469
473
|
}
|
|
470
474
|
}
|
|
471
475
|
|
|
472
|
-
const addSemantic = (semantic, evaluate) => {
|
|
476
|
+
const addSemantic = (semantic, evaluate, property) => {
|
|
473
477
|
const match = semantic.match || (() => true)
|
|
474
478
|
let apply = semantic
|
|
475
479
|
// if I do apply === semantic.apply or semantic there is one function that has apply defined for some reason even though not explicitly set
|
|
@@ -491,13 +495,13 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
491
495
|
}
|
|
492
496
|
} else {
|
|
493
497
|
semanticDef = {
|
|
494
|
-
match: (args) => bridge.id === args.context.marker &&
|
|
498
|
+
match: (args) => bridge.id === args.context.marker && match(args),
|
|
495
499
|
apply: (args) => apply(args),
|
|
496
500
|
applyWrapped: semantic,
|
|
497
501
|
}
|
|
498
502
|
}
|
|
499
503
|
semanticDef.where = semantic.where || bridge.where || helpers.where(4)
|
|
500
|
-
semanticDef.property =
|
|
504
|
+
semanticDef.property = property
|
|
501
505
|
if (semantic.priority) {
|
|
502
506
|
semanticDef.priority = semantic.priority
|
|
503
507
|
}
|
|
@@ -509,22 +513,8 @@ const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
|
509
513
|
}
|
|
510
514
|
}
|
|
511
515
|
|
|
512
|
-
if (bridge.evaluator) {
|
|
513
|
-
addSemantic(bridge.evaluator, true)
|
|
514
|
-
}
|
|
515
|
-
|
|
516
516
|
if (bridge.semantic) {
|
|
517
|
-
addSemantic(bridge.semantic, false)
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
if (bridge.evaluators) {
|
|
521
|
-
const evaluators = [...bridge.evaluators]
|
|
522
|
-
evaluators.reverse()
|
|
523
|
-
if (evaluators) {
|
|
524
|
-
for (const evaluator of evaluators) {
|
|
525
|
-
addSemantic(evaluator, true)
|
|
526
|
-
}
|
|
527
|
-
}
|
|
517
|
+
addSemantic(bridge.semantic, false, 'semantic')
|
|
528
518
|
}
|
|
529
519
|
|
|
530
520
|
if (bridge.semantics) {
|
|
@@ -556,8 +546,6 @@ const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {})
|
|
|
556
546
|
'convolution',
|
|
557
547
|
'disabled',
|
|
558
548
|
'enhanced_associations',
|
|
559
|
-
'evaluator',
|
|
560
|
-
'evaluators',
|
|
561
549
|
'generatorp',
|
|
562
550
|
'generatorpr',
|
|
563
551
|
'generatorr',
|
|
@@ -996,9 +984,10 @@ class Config {
|
|
|
996
984
|
|
|
997
985
|
async fixtures () {
|
|
998
986
|
if (this.testConfig?.fixtures) {
|
|
999
|
-
const args = {
|
|
987
|
+
const args = {
|
|
988
|
+
}
|
|
1000
989
|
args.uuid = this._uuid
|
|
1001
|
-
configHelpers.setupArgs(args, this)
|
|
990
|
+
configHelpers.setupArgs(args, this, this.logs)
|
|
1002
991
|
return this.testConfig.fixtures(args)
|
|
1003
992
|
}
|
|
1004
993
|
}
|
|
@@ -1029,6 +1018,7 @@ class Config {
|
|
|
1029
1018
|
return {
|
|
1030
1019
|
pseudo: true,
|
|
1031
1020
|
description: 'this is a pseudo config that has limited functionality due to being available in the initializer and fixtures function context',
|
|
1021
|
+
nextFragmentContextId: () => this.nextFragmentContextId(),
|
|
1032
1022
|
addAssociation: (...args) => this.addAssociation(...args),
|
|
1033
1023
|
addAssociations: (...args) => this.addAssociations(...args),
|
|
1034
1024
|
addBridge: (...args) => this.addBridge(...args, uuid),
|
|
@@ -1043,6 +1033,7 @@ class Config {
|
|
|
1043
1033
|
addPattern: (...args) => this.addPattern(...args, uuid),
|
|
1044
1034
|
updateBridge: (...args) => this.updateBridge(...args),
|
|
1045
1035
|
processContext: (...args) => this.processContext(...args),
|
|
1036
|
+
logs: this.logs,
|
|
1046
1037
|
|
|
1047
1038
|
semantics: () => this.config.semantics,
|
|
1048
1039
|
getConfigs: () => this.configs,
|
|
@@ -1242,7 +1233,7 @@ class Config {
|
|
|
1242
1233
|
|
|
1243
1234
|
warningNotEvaluated (log, value) {
|
|
1244
1235
|
const description = 'WARNING: for semantics, implement an evaluations handler, set "value" property of the operator to the value.'
|
|
1245
|
-
const match = `({context}) => context.marker === '${value.marker}' &&
|
|
1236
|
+
const match = `({context}) => context.marker === '${value.marker}' && <other conditions as you like>`
|
|
1246
1237
|
const apply = '({context}) => <do stuff...>; context.value = <value>'
|
|
1247
1238
|
const input = indent(JSON.stringify(value, null, 2), 2)
|
|
1248
1239
|
const message = `${description}\nThe semantic would be\n match: ${match}\n apply: ${apply}\nThe input context would be:\n${input}\n`
|
|
@@ -1251,18 +1242,15 @@ class Config {
|
|
|
1251
1242
|
|
|
1252
1243
|
// value is in response field
|
|
1253
1244
|
// TODO maybe generalize out query+evaluate along the lines of set value and set reference
|
|
1254
|
-
async
|
|
1255
|
-
const
|
|
1256
|
-
|
|
1257
|
-
if (
|
|
1258
|
-
|
|
1245
|
+
async evaluate (args, logs, context) {
|
|
1246
|
+
const apply = (c) => this.getSemantics(logs).apply(args, c)
|
|
1247
|
+
const instance = await apply(context)
|
|
1248
|
+
if (typeof instance !== 'string') {
|
|
1249
|
+
args.calls.touch(instance)
|
|
1259
1250
|
}
|
|
1260
|
-
if (instance.evalue == null) {
|
|
1261
|
-
|
|
1262
|
-
instance.edefault = true
|
|
1251
|
+
if (instance.evalue == null && !instance.verbatim && !instance.value) {
|
|
1252
|
+
this.warningNotEvaluated(logs, context)
|
|
1263
1253
|
}
|
|
1264
|
-
delete instance.evaluate
|
|
1265
|
-
instance.instance = true
|
|
1266
1254
|
return instance
|
|
1267
1255
|
}
|
|
1268
1256
|
|
|
@@ -1293,10 +1281,14 @@ class Config {
|
|
|
1293
1281
|
let fi = fragmentInstantiator(args, fragment.contexts)
|
|
1294
1282
|
if (mappings) {
|
|
1295
1283
|
fi = await fi
|
|
1296
|
-
|
|
1284
|
+
const instantiated = await fi.instantiate([{
|
|
1297
1285
|
match: ({context}) => !!mappings[context.value], // is the value in the mappings
|
|
1298
1286
|
apply: ({context}) => Object.assign(context, mappings[context.value]),
|
|
1299
|
-
}])
|
|
1287
|
+
}], fragment.key?.preserve)
|
|
1288
|
+
if (process.env.DEBUG_CONTEXT_ID && process.env.DEBUG_CONTEXT_ID == instantiated.context_id) {
|
|
1289
|
+
debugger
|
|
1290
|
+
}
|
|
1291
|
+
return instantiated
|
|
1300
1292
|
} else {
|
|
1301
1293
|
return fi
|
|
1302
1294
|
}
|
|
@@ -1305,6 +1297,7 @@ class Config {
|
|
|
1305
1297
|
}
|
|
1306
1298
|
}
|
|
1307
1299
|
|
|
1300
|
+
/*
|
|
1308
1301
|
fragmentMapper (args, values, fromModelQuery, toModelQuery) {
|
|
1309
1302
|
const fromModelFragment = this.getFragment(fromModelQuery)
|
|
1310
1303
|
console.dir(fromModelFragment)
|
|
@@ -1313,6 +1306,7 @@ class Config {
|
|
|
1313
1306
|
const mapper = fragmentMapperInstantiator(values, fromModelFragment.contexts, toModelFragment.contexts)
|
|
1314
1307
|
return mapper
|
|
1315
1308
|
}
|
|
1309
|
+
*/
|
|
1316
1310
|
|
|
1317
1311
|
// { rebuild: false, isModule: false }
|
|
1318
1312
|
needsRebuild (template, instance, options) {
|
|
@@ -1384,6 +1378,7 @@ class Config {
|
|
|
1384
1378
|
bridge = { ...bridge },
|
|
1385
1379
|
bridge.level = bridge.level || 0
|
|
1386
1380
|
delete bridge.uuid
|
|
1381
|
+
delete bridge.where
|
|
1387
1382
|
return bridge
|
|
1388
1383
|
})
|
|
1389
1384
|
if (options.isModule) {
|
|
@@ -1396,8 +1391,6 @@ class Config {
|
|
|
1396
1391
|
delete bridge.generatorp
|
|
1397
1392
|
delete bridge.generatorr
|
|
1398
1393
|
delete bridge.generatorpr
|
|
1399
|
-
delete bridge.evaluator
|
|
1400
|
-
delete bridge.evaluators
|
|
1401
1394
|
delete bridge.semantic
|
|
1402
1395
|
delete bridge.semantics
|
|
1403
1396
|
if (false && !bridge.bridge) {
|
|
@@ -2179,6 +2172,12 @@ class Config {
|
|
|
2179
2172
|
// await this.demoInitializer(this)
|
|
2180
2173
|
}
|
|
2181
2174
|
|
|
2175
|
+
nextFragmentContextId() {
|
|
2176
|
+
const id = this.fragmentNextContextId
|
|
2177
|
+
this.fragmentNextContextId = this.fragmentNextContextId + 1
|
|
2178
|
+
return id
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2182
2181
|
// configs = [ { config, namespace } ... ]
|
|
2183
2182
|
constructor (config, module, clientProcess, apiKMs, rootIsProcess, testingModuleName) {
|
|
2184
2183
|
if (config instanceof Config) {
|
|
@@ -2189,6 +2188,8 @@ class Config {
|
|
|
2189
2188
|
apiKMs = []
|
|
2190
2189
|
}
|
|
2191
2190
|
|
|
2191
|
+
this.fragmentNextContextId = 1000
|
|
2192
|
+
|
|
2192
2193
|
if (config) {
|
|
2193
2194
|
validConfigProps(config)
|
|
2194
2195
|
|
package/src/configHelpers.js
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
const { InitCalls } = require('./helpers')
|
|
1
|
+
const { InitCalls, where } = require('./helpers')
|
|
2
2
|
const DigraphInternal = require('./digraph_internal')
|
|
3
3
|
const debug = require('./debug')
|
|
4
4
|
|
|
5
|
+
class ErrorReason extends Error {
|
|
6
|
+
constructor (context, stack) {
|
|
7
|
+
super(JSON.stringify(context))
|
|
8
|
+
this.reason = context
|
|
9
|
+
this.stack = stack
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
toString() {
|
|
13
|
+
if (this.reason) {
|
|
14
|
+
return this.reason
|
|
15
|
+
} else {
|
|
16
|
+
return super.toString()
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
5
22
|
const gs = (g) => async (contexts, separator, lastSeparator) => {
|
|
6
23
|
if (!Array.isArray(contexts)) {
|
|
7
24
|
throw new Error('Expected a list')
|
|
@@ -63,13 +80,6 @@ const isA = (hierarchy) => (child, parent, { strict = false } = {}) => {
|
|
|
63
80
|
}
|
|
64
81
|
}
|
|
65
82
|
|
|
66
|
-
class ErrorReason extends Error {
|
|
67
|
-
constructor (context) {
|
|
68
|
-
super(JSON.stringify(context))
|
|
69
|
-
this.reason = context
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
83
|
const cleanAssign = (dest, ...srcs) => {
|
|
74
84
|
for (const key in dest) {
|
|
75
85
|
let found = false
|
|
@@ -93,13 +103,25 @@ class HandlerStack {
|
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
push(handler) {
|
|
96
|
-
this.handlers.push(handler)
|
|
106
|
+
this.handlers.push(handler.where || handler)
|
|
97
107
|
}
|
|
98
108
|
|
|
99
109
|
pop() {
|
|
100
110
|
this.handlers.pop()
|
|
101
111
|
}
|
|
102
112
|
|
|
113
|
+
async wrap(call, w) {
|
|
114
|
+
this.push(w)
|
|
115
|
+
const p = await call()
|
|
116
|
+
if (p && typeof p.finally === 'function') {
|
|
117
|
+
return p.finally(() => {
|
|
118
|
+
this.pop()
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
this.pop()
|
|
122
|
+
return p
|
|
123
|
+
}
|
|
124
|
+
|
|
103
125
|
toString() {
|
|
104
126
|
let str = ''
|
|
105
127
|
for (let i = this.handlers.length - 1; i >= 0; --i) {
|
|
@@ -185,7 +207,7 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
185
207
|
args.km = (name) => config.getConfig(name)
|
|
186
208
|
args.api = (name) => config.getConfig(name).api
|
|
187
209
|
args.error = (context) => {
|
|
188
|
-
throw new ErrorReason(context)
|
|
210
|
+
throw new ErrorReason(context, [...args.stack.handlers, where()])
|
|
189
211
|
}
|
|
190
212
|
args.kms = config.getConfigs()
|
|
191
213
|
args.config = config.getPseudoConfig(uuidForScoping, config)
|
|
@@ -198,15 +220,15 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
198
220
|
args.fragments = (query, mappings) => {
|
|
199
221
|
return config.fragment(args, query, mappings)
|
|
200
222
|
}
|
|
223
|
+
/*
|
|
201
224
|
args.fragmentMapper = (values, fromModelQuery, toModelQuery) => {
|
|
202
225
|
return config.fragmentMapper(args, values, fromModelQuery, toModelQuery)
|
|
203
226
|
}
|
|
227
|
+
*/
|
|
204
228
|
args.breakOnSemantics = false
|
|
205
229
|
args.theDebugger = {
|
|
206
230
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
|
207
231
|
}
|
|
208
|
-
if (!logs) {
|
|
209
|
-
}
|
|
210
232
|
args.log = (message) => logs.push(message)
|
|
211
233
|
|
|
212
234
|
args.addWord = (word, def) => config.addWord(word, def, args.uuid)
|
|
@@ -221,7 +243,6 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
221
243
|
return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
|
|
222
244
|
}
|
|
223
245
|
|
|
224
|
-
args.s = (c, options = {}) => config.getSemantics(logs).apply(args, c, options)
|
|
225
246
|
args.g = (c, rest = {}) => {
|
|
226
247
|
// if (JSON.stringify(rest) !== '{}' && !(rest.assumed || rest.options)) {
|
|
227
248
|
// debugger
|
|
@@ -256,12 +277,18 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
256
277
|
const { assumed = {}, options = {} } = rest
|
|
257
278
|
return config.getGenerators(logs).apply(addAssumed(args, assumed, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true }, options)
|
|
258
279
|
}
|
|
259
|
-
|
|
280
|
+
|
|
281
|
+
args.e = (c, where) => {
|
|
260
282
|
if (!c) {
|
|
261
283
|
return
|
|
262
284
|
}
|
|
263
|
-
|
|
285
|
+
if (where) {
|
|
286
|
+
return args.stack.wrap(() => config.evaluate(args, logs, c), where)
|
|
287
|
+
} else {
|
|
288
|
+
return config.evaluate(args, logs, c)
|
|
289
|
+
}
|
|
264
290
|
}
|
|
291
|
+
|
|
265
292
|
args.gs = gs(args.g)
|
|
266
293
|
args.gsp = gs(args.gp)
|
|
267
294
|
args.gsr = gs(args.gr)
|
|
@@ -346,7 +373,7 @@ const processContext = async (context, { objects = {}, config, logs = [] }) => {
|
|
|
346
373
|
return { context, generated, paraphrases, responses }
|
|
347
374
|
}
|
|
348
375
|
|
|
349
|
-
const setupProcessB = ({ config, initializer, allowDelta = false, rebuildingTemplate = false } = {}) => {
|
|
376
|
+
const setupProcessB = ({ config, initializer, isFragment, allowDelta = false, rebuildingTemplate = false } = {}) => {
|
|
350
377
|
const key = config._key
|
|
351
378
|
const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
|
|
352
379
|
/*
|
|
@@ -411,7 +438,7 @@ const setupContexts = (rawContexts) => {
|
|
|
411
438
|
return contexts
|
|
412
439
|
}
|
|
413
440
|
|
|
414
|
-
const processContextsB = async ({ config, calls, hierarchy, logs, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate, contextIdCounter }) => {
|
|
441
|
+
const processContextsB = async ({ skipSemantics, isFragment, config, calls, hierarchy, logs, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate, contextIdCounter }) => {
|
|
415
442
|
// TODO fix this name to contextsPrime
|
|
416
443
|
const contextsPrime = []
|
|
417
444
|
const generatedPrime = []
|
|
@@ -419,6 +446,7 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
|
|
|
419
446
|
const paraphrasesParenthesizedPrime = []
|
|
420
447
|
const generatedParenthesizedPrime = []
|
|
421
448
|
const responsesPrime = []
|
|
449
|
+
|
|
422
450
|
const contexts = setupContexts(json.contexts)
|
|
423
451
|
|
|
424
452
|
const objects = config.get('objects')
|
|
@@ -440,7 +468,7 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
|
|
|
440
468
|
throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
|
|
441
469
|
}
|
|
442
470
|
const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
|
|
443
|
-
if (!config.get('skipSemantics')) {
|
|
471
|
+
if (!config.get('skipSemantics') && !skipSemantics) {
|
|
444
472
|
const semantics = config.getSemantics(logs)
|
|
445
473
|
try {
|
|
446
474
|
contextPrime = await semantics.apply(args, context)
|
|
@@ -455,17 +483,18 @@ const processContextsB = async ({ config, calls, hierarchy, logs, semantics, gen
|
|
|
455
483
|
if (isInstance) {
|
|
456
484
|
console.log('error', e.error)
|
|
457
485
|
}
|
|
486
|
+
|
|
458
487
|
let reason = e.reason
|
|
459
488
|
if (!reason) {
|
|
460
489
|
if (e.error) {
|
|
461
490
|
reason = e.error[0]
|
|
462
491
|
}
|
|
463
492
|
}
|
|
493
|
+
|
|
464
494
|
contextPrime = await semantics.apply(args, {
|
|
465
495
|
marker: 'error',
|
|
466
496
|
context,
|
|
467
|
-
text: e
|
|
468
|
-
// reason: e.reason,
|
|
497
|
+
text: e.toString(),
|
|
469
498
|
reason,
|
|
470
499
|
error: e.stack || e.error
|
|
471
500
|
})
|
|
@@ -578,14 +607,14 @@ const loadInstance = async (config, instance) => {
|
|
|
578
607
|
// used to do a CLONE
|
|
579
608
|
config.addInternal(instance.template.configs[i], { uuid, km: instance.name, addFirst: true, handleCalculatedProps: true })
|
|
580
609
|
} else if (results.apply) {
|
|
581
|
-
const
|
|
610
|
+
const uuid = config.nameToUUID(instance.name)
|
|
611
|
+
const objects = getObjects(config.get('objects'))(uuid)
|
|
582
612
|
const args = { objects, getObjects: getObjects(objects) }
|
|
583
613
|
if (instance.configs) {
|
|
584
614
|
args.isInstance = `instance${i}`
|
|
585
615
|
args.instance = instance.configs[i]
|
|
586
616
|
}
|
|
587
617
|
|
|
588
|
-
const uuid = config.nameToUUID(instance.name)
|
|
589
618
|
setupArgs(args, config, config.logs, hierarchy, uuid)
|
|
590
619
|
if (config.name == instance.name) {
|
|
591
620
|
args.isModule = !!config.isModule
|
|
@@ -609,6 +638,7 @@ const loadInstance = async (config, instance) => {
|
|
|
609
638
|
args.instance = ''
|
|
610
639
|
args.isProcess = !config.isModule
|
|
611
640
|
args.isModule = !!config.isModule
|
|
641
|
+
args.logs = config.logs
|
|
612
642
|
if (instance.name == config.testConfig.testModuleName) {
|
|
613
643
|
args.isTesting = true
|
|
614
644
|
}
|
package/src/fragments.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const _ = require('lodash')
|
|
2
|
+
const debug = require('./debug')
|
|
2
3
|
const helpers = require('./helpers')
|
|
3
4
|
|
|
4
5
|
function createChangeTracker(obj) {
|
|
@@ -23,17 +24,28 @@ function createChangeTracker(obj) {
|
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
27
|
function fragmentInstantiator (args, contexts) {
|
|
28
28
|
return new Object({
|
|
29
29
|
contexts: () => {
|
|
30
30
|
return _.cloneDeep(contexts)
|
|
31
31
|
},
|
|
32
|
-
|
|
32
|
+
// preserve property not to be changed.
|
|
33
|
+
instantiate: async (mappings, preserve) => {
|
|
34
|
+
preserve = preserve || []
|
|
33
35
|
const instantiated = _.cloneDeep(contexts)
|
|
34
36
|
const todo = [{ context: instantiated, path: [] }]
|
|
35
37
|
args = { ...args }
|
|
36
38
|
args.pathEquals = helpers.pathEquals
|
|
39
|
+
const preserved = preserve.map((path) => {
|
|
40
|
+
if (contexts.length == 1) {
|
|
41
|
+
path = ['0', path]
|
|
42
|
+
}
|
|
43
|
+
const value = helpers.getByPath(contexts, path)
|
|
44
|
+
return { path, value }
|
|
45
|
+
})
|
|
46
|
+
for (const context of contexts) {
|
|
47
|
+
context.context_id = args.config.nextFragmentContextId()
|
|
48
|
+
}
|
|
37
49
|
while (todo.length > 0) {
|
|
38
50
|
const { context, path } = todo.pop()
|
|
39
51
|
const { proxy, getChanges } = createChangeTracker(context);
|
|
@@ -58,6 +70,9 @@ function fragmentInstantiator (args, contexts) {
|
|
|
58
70
|
}
|
|
59
71
|
}
|
|
60
72
|
}
|
|
73
|
+
for (const { path, value } of preserved) {
|
|
74
|
+
helpers.setByPath(instantiated, path, value)
|
|
75
|
+
}
|
|
61
76
|
if (contexts.length == 1 && instantiated.length == 1) {
|
|
62
77
|
return instantiated[0]
|
|
63
78
|
} else {
|
package/src/generators.js
CHANGED
|
@@ -125,7 +125,7 @@ class Generator {
|
|
|
125
125
|
args.g = args.gp
|
|
126
126
|
}
|
|
127
127
|
return await debug.hitScoped(args.callId, async () => {
|
|
128
|
-
if ((options.debug || {}).apply || process.env.
|
|
128
|
+
if ((options.debug || {}).apply || process.env.DEBUG_BREAKAT == args.callId || callId === this.callId) {
|
|
129
129
|
debugger // eslint-disable-line no-debugger
|
|
130
130
|
}
|
|
131
131
|
return await this._apply(args) // DEBUG: This is the line you want to step into
|
|
@@ -184,6 +184,9 @@ class Generators {
|
|
|
184
184
|
let generated = ''
|
|
185
185
|
let applied = false
|
|
186
186
|
const stack = args.calls.push()
|
|
187
|
+
const pOrRTag = assumed.isResponse ? "(RESPONSE)" : "(PARAPHRASE)"
|
|
188
|
+
const finallyList = []; // called after the generator is processed
|
|
189
|
+
args._finally = (call) => finallyList.unshift(call)
|
|
187
190
|
for (let igenerator = 0; igenerator < this.generators.length; ++igenerator) {
|
|
188
191
|
const generator = this.generators[igenerator]
|
|
189
192
|
if (await generator.matches(args, objects, context, hierarchy, config, options)) {
|
|
@@ -194,7 +197,7 @@ class Generators {
|
|
|
194
197
|
console.error("TPMKMS_TRACE", debug.counter("TPMKMS_TRACE"))
|
|
195
198
|
console.error(generator.toLabel())
|
|
196
199
|
console.error(generator.toString())
|
|
197
|
-
console.log(`To debug this use debug.breakAt('${args.calls.current()}') or
|
|
200
|
+
console.log(`To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_BREAKAT="${args.calls.current()}"`)
|
|
198
201
|
}
|
|
199
202
|
|
|
200
203
|
try {
|
|
@@ -218,21 +221,22 @@ class Generators {
|
|
|
218
221
|
const widths = Lines.addRemainder([10, 10])
|
|
219
222
|
const lines = new Lines(widths)
|
|
220
223
|
lines.setElement(0, 0, 'Generator')
|
|
224
|
+
lines.setElement(0, 1, `#${context.context_id || "?"}`)
|
|
221
225
|
const source = `${generator.km}/#${generator.index}`
|
|
222
226
|
lines.setElement(0, 2, `ERROR while applying (${source}) ${generator.toLabel()}`)
|
|
223
227
|
lines.newRow()
|
|
228
|
+
lines.setElement(0, 1, 'DEBUG')
|
|
229
|
+
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_BREAKAT="${args.calls.current()}"`)
|
|
230
|
+
lines.newRow()
|
|
231
|
+
lines.setElement(0, 1, 'STACK')
|
|
232
|
+
lines.setElement(0, 2, stack)
|
|
233
|
+
lines.newRow()
|
|
224
234
|
lines.setElement(0, 2, generator.toString())
|
|
225
235
|
lines.newRow()
|
|
226
236
|
lines.setElement(0, 1, 'TO')
|
|
227
237
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
228
238
|
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 10 }), null, 2))
|
|
229
239
|
lines.newRow()
|
|
230
|
-
lines.setElement(0, 1, 'STACK')
|
|
231
|
-
lines.setElement(0, 2, stack)
|
|
232
|
-
lines.newRow()
|
|
233
|
-
lines.setElement(0, 1, 'DEBUG')
|
|
234
|
-
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') or DEBUG_CALLID="${args.calls.current()}"`)
|
|
235
|
-
lines.newRow()
|
|
236
240
|
lines.setElement(0, 1, 'ERROR')
|
|
237
241
|
lines.setElement(0, 2, errorMessage)
|
|
238
242
|
this.logs.push(lines.toString())
|
|
@@ -246,24 +250,25 @@ class Generators {
|
|
|
246
250
|
const widths = Lines.addRemainder([10, 10])
|
|
247
251
|
const lines = new Lines(widths)
|
|
248
252
|
lines.setElement(0, 0, 'Generator')
|
|
253
|
+
lines.setElement(0, 1, `#${context.context_id || "?"}`)
|
|
249
254
|
if (generator.index > -1 && generator.km) {
|
|
250
255
|
// lines.setElement(0, 2, `KM '${generator.km}' ordinal: ${generator.index}`)
|
|
251
256
|
lines.setElement(0, 2, generator.toLabel())
|
|
252
257
|
}
|
|
253
258
|
lines.newRow()
|
|
259
|
+
lines.setElement(0, 1, 'DEBUG')
|
|
260
|
+
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}')`)
|
|
261
|
+
lines.newRow()
|
|
254
262
|
lines.setElement(0, 1, 'APPLIED')
|
|
255
263
|
lines.setElement(0, 2, generator.toLabel())
|
|
256
264
|
lines.newRow()
|
|
257
|
-
lines.setElement(0, 2, generator.toString())
|
|
258
|
-
lines.newRow()
|
|
259
265
|
lines.setElement(0, 1, 'RESULT')
|
|
260
|
-
lines.setElement(0, 2, generated)
|
|
266
|
+
lines.setElement(0, 2, generated + " " + pOrRTag)
|
|
261
267
|
lines.newRow()
|
|
262
268
|
lines.setElement(0, 1, 'STACK')
|
|
263
269
|
lines.setElement(0, 2, stack)
|
|
264
270
|
lines.newRow()
|
|
265
|
-
lines.setElement(0,
|
|
266
|
-
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}')`)
|
|
271
|
+
lines.setElement(0, 2, generator.toString())
|
|
267
272
|
lines.newRow()
|
|
268
273
|
lines.setElement(0, 1, 'TO')
|
|
269
274
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
@@ -274,11 +279,15 @@ class Generators {
|
|
|
274
279
|
break
|
|
275
280
|
}
|
|
276
281
|
}
|
|
282
|
+
for (const f of finallyList) {
|
|
283
|
+
await f()
|
|
284
|
+
}
|
|
277
285
|
args.calls.pop()
|
|
278
286
|
if (!applied && config.getDebug()) {
|
|
279
287
|
const widths = Lines.addRemainder([10, 10])
|
|
280
288
|
const lines = new Lines(widths)
|
|
281
289
|
lines.setElement(0, 0, 'Generator')
|
|
290
|
+
lines.setElement(0, 1, `#${context.context_id || "?"}`)
|
|
282
291
|
lines.setElement(0, 2, 'No generator applied')
|
|
283
292
|
lines.newRow()
|
|
284
293
|
lines.setElement(0, 1, 'STACK')
|
package/src/helpers.js
CHANGED
|
@@ -22,12 +22,30 @@ class OverrideCheck {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function pathEquals (p1, p2) {
|
|
25
|
+
function pathEquals (p1, p2, n) {
|
|
26
|
+
if (n !== undefined) {
|
|
27
|
+
if (n < 0) {
|
|
28
|
+
p1 = p1.slice(n)
|
|
29
|
+
p2 = p2.slice(n)
|
|
30
|
+
} else {
|
|
31
|
+
p1 = p1.slice(0, n)
|
|
32
|
+
p2 = p2.slice(0, n)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
if (p1.length !== p2.length) {
|
|
27
37
|
return false
|
|
28
38
|
}
|
|
29
39
|
for (let i = 0; i < p1.length; ++i) {
|
|
30
|
-
if (
|
|
40
|
+
if (p1[i].integer) {
|
|
41
|
+
if (!Number.isInteger(p2[i])) {
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
} else if (p2[i].integer) {
|
|
45
|
+
if (!Number.isInteger(p1[i])) {
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
} else if (typeof p2[i] == 'function') {
|
|
31
49
|
if (!p2[i](p1[i])) {
|
|
32
50
|
return false
|
|
33
51
|
}
|
|
@@ -72,7 +90,14 @@ function where (goUp = 2) {
|
|
|
72
90
|
let match
|
|
73
91
|
for (line of lines.slice(1)) {
|
|
74
92
|
// if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
|
|
75
|
-
|
|
93
|
+
const ignore = [
|
|
94
|
+
'config.js:',
|
|
95
|
+
'client.js:',
|
|
96
|
+
'helpers.js:',
|
|
97
|
+
'configHelpers.js:',
|
|
98
|
+
]
|
|
99
|
+
// if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('helpers.js:'))) {
|
|
100
|
+
if(!ignore.some(p => line.includes(p))) {
|
|
76
101
|
match = regexForm1.exec(line) || regexForm2.exec(line)
|
|
77
102
|
if (!match) {
|
|
78
103
|
continue
|
|
@@ -477,12 +502,6 @@ const functionsToStrings = (config) => {
|
|
|
477
502
|
if (bridge.semantics) {
|
|
478
503
|
bridge.semantics = bridge.semantics.toString()
|
|
479
504
|
}
|
|
480
|
-
if (bridge.evaluator) {
|
|
481
|
-
bridge.evaluator = bridge.evaluator.toString()
|
|
482
|
-
}
|
|
483
|
-
if (bridge.evaluators) {
|
|
484
|
-
bridge.evaluators = bridge.evaluators.toString()
|
|
485
|
-
}
|
|
486
505
|
return bridge
|
|
487
506
|
})
|
|
488
507
|
}
|
|
@@ -627,7 +646,60 @@ function setByPath(obj, path, value) {
|
|
|
627
646
|
|
|
628
647
|
const helpDebugHierarchy = 'In order to get a debug break when a specific hierarchy is created set the DEBUG_HIERARCHY environment variable to the JSON of the child-parent pair to break on. For example DEBUG_HIERARCHY=\'["cat", "mammel"]\''
|
|
629
648
|
|
|
649
|
+
// removeProp.js
|
|
650
|
+
function removeProp(obj, testFn, { maxDepth = Infinity, seen = new WeakSet() } = {}) {
|
|
651
|
+
if (!obj || typeof obj !== 'object' || maxDepth <= 0) return obj;
|
|
652
|
+
if (seen.has(obj)) return obj;
|
|
653
|
+
seen.add(obj);
|
|
654
|
+
|
|
655
|
+
if (Array.isArray(obj)) {
|
|
656
|
+
// ---- ARRAY: process each element (but don't remove elements unless testFn says so)
|
|
657
|
+
let writeIdx = 0;
|
|
658
|
+
for (let i = 0; i < obj.length; i++) {
|
|
659
|
+
const element = obj[i];
|
|
660
|
+
const shouldRemoveElement = testFn(element, i, obj);
|
|
661
|
+
|
|
662
|
+
if (shouldRemoveElement) {
|
|
663
|
+
// Remove the whole array element
|
|
664
|
+
if (element && typeof element === 'object') {
|
|
665
|
+
// Still walk inside it in case testFn wants side effects
|
|
666
|
+
removeProp(element, testFn, { maxDepth: maxDepth - 1, seen });
|
|
667
|
+
}
|
|
668
|
+
// Skip writing it back
|
|
669
|
+
} else {
|
|
670
|
+
// Keep element, but walk into it to remove inner props
|
|
671
|
+
removeProp(element, testFn, { maxDepth: maxDepth - 1, seen });
|
|
672
|
+
if (writeIdx !== i) {
|
|
673
|
+
obj[writeIdx] = element;
|
|
674
|
+
}
|
|
675
|
+
writeIdx++;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
obj.length = writeIdx;
|
|
679
|
+
return obj;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// ---- OBJECT: iterate over own keys
|
|
683
|
+
const keys = Reflect.ownKeys(obj);
|
|
684
|
+
for (const key of keys) {
|
|
685
|
+
const val = obj[key];
|
|
686
|
+
const shouldRemove = testFn(val, key, obj);
|
|
687
|
+
|
|
688
|
+
if (shouldRemove) {
|
|
689
|
+
delete obj[key];
|
|
690
|
+
if (val && typeof val === 'object') {
|
|
691
|
+
removeProp(val, testFn, { maxDepth: maxDepth - 1, seen });
|
|
692
|
+
}
|
|
693
|
+
} else {
|
|
694
|
+
removeProp(val, testFn, { maxDepth: maxDepth - 1, seen });
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return obj;
|
|
699
|
+
}
|
|
700
|
+
|
|
630
701
|
module.exports = {
|
|
702
|
+
removeProp,
|
|
631
703
|
helpDebugHierarchy,
|
|
632
704
|
|
|
633
705
|
stableId,
|
|
@@ -662,4 +734,5 @@ module.exports = {
|
|
|
662
734
|
watchProperty,
|
|
663
735
|
pathEquals,
|
|
664
736
|
OverrideCheck,
|
|
737
|
+
normalizePath,
|
|
665
738
|
}
|
package/src/project2.js
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
const debug = require('./debug')
|
|
2
2
|
const helpers = require('./helpers')
|
|
3
3
|
|
|
4
|
-
function areFirstNEqual(arr1, arr2, n) {
|
|
5
|
-
if (n <= 0) return true;
|
|
6
|
-
if (arr1.length < n || arr2.length < n) return false;
|
|
7
|
-
|
|
8
|
-
for (let i = 0; i < n; i++) {
|
|
9
|
-
if (arr1[i] !== arr2[i]) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
4
|
function project(source, filters, path=[]) {
|
|
17
5
|
if (['boolean', 'string', 'number'].includes(typeof source)) {
|
|
18
6
|
return source
|
|
@@ -49,12 +37,16 @@ function project(source, filters, path=[]) {
|
|
|
49
37
|
let properties = []
|
|
50
38
|
for (const filter of selectedFilters) {
|
|
51
39
|
for (const property of filter.apply(source)) {
|
|
52
|
-
properties.
|
|
40
|
+
if (!properties.includes(property)) {
|
|
41
|
+
properties.push(property)
|
|
42
|
+
}
|
|
53
43
|
}
|
|
54
44
|
}
|
|
55
45
|
if (source?.checks) {
|
|
56
46
|
for (const check of source.checks) {
|
|
57
|
-
properties.
|
|
47
|
+
if (!properties.includes(check)) {
|
|
48
|
+
properties.push(check)
|
|
49
|
+
}
|
|
58
50
|
}
|
|
59
51
|
}
|
|
60
52
|
|
|
@@ -64,10 +56,14 @@ function project(source, filters, path=[]) {
|
|
|
64
56
|
// property that contains a list of properties to be checked
|
|
65
57
|
if (property.properties) {
|
|
66
58
|
for (const moreProperty of source[property.properties] || []) {
|
|
67
|
-
updatedProperties.
|
|
59
|
+
if (!updatedProperties.includes(property)) {
|
|
60
|
+
updatedProperties.push(moreProperty)
|
|
61
|
+
}
|
|
68
62
|
}
|
|
69
63
|
} else {
|
|
70
|
-
updatedProperties.
|
|
64
|
+
if (!updatedProperties.includes(property)) {
|
|
65
|
+
updatedProperties.push(property)
|
|
66
|
+
}
|
|
71
67
|
}
|
|
72
68
|
}
|
|
73
69
|
properties = updatedProperties
|
|
@@ -75,7 +71,7 @@ function project(source, filters, path=[]) {
|
|
|
75
71
|
// Build the result object
|
|
76
72
|
const result = {};
|
|
77
73
|
properties.forEach(prop => {
|
|
78
|
-
if (prop.path && (prop.path.length === path.length + 1) &&
|
|
74
|
+
if (prop.path && (prop.path.length === path.length + 1) && helpers.pathEquals(path, prop.path, path.length) && source.hasOwnProperty(prop.path[path.length])) {
|
|
79
75
|
const endProp = prop.path[path.length]
|
|
80
76
|
if (['boolean', 'string', 'number'].includes(typeof source[endProp])) {
|
|
81
77
|
result[endProp] = source[endProp]
|
|
@@ -109,8 +105,18 @@ function project(source, filters, path=[]) {
|
|
|
109
105
|
const instantiatedCheck = []
|
|
110
106
|
for (const check of prop.check) {
|
|
111
107
|
if (typeof check.property == 'function') {
|
|
112
|
-
|
|
108
|
+
const keys = (value) => {
|
|
109
|
+
if (Array.isArray(value)) {
|
|
110
|
+
return value.keys()
|
|
111
|
+
} else {
|
|
112
|
+
return Object.keys(value)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
for (const sourceKey of keys(source[prop.property])) {
|
|
113
116
|
if (check.property(sourceKey)) {
|
|
117
|
+
if (!check.check) {
|
|
118
|
+
throw new Error(`For the property check of the property '${check.property.toString()}', the 'check' (singular) property is missing.`)
|
|
119
|
+
}
|
|
114
120
|
instantiatedCheck.push({ property: sourceKey, check: check.check })
|
|
115
121
|
}
|
|
116
122
|
}
|
package/src/semantics.js
CHANGED
|
@@ -78,7 +78,7 @@ class Semantic {
|
|
|
78
78
|
return await debug.hitScoped(args.callId, async () => {
|
|
79
79
|
const matches = await this.matcher(args)
|
|
80
80
|
if (matches) {
|
|
81
|
-
if ((options.debug || {}).match || args.callId === this.callId || process.env.
|
|
81
|
+
if ((options.debug || {}).match || args.callId === this.callId || process.env.DEBUG_BREAKAT == args.callId) {
|
|
82
82
|
debugger // eslint-disable-line no-debugger
|
|
83
83
|
await this.matcher(args) // DEBUG: This is the line you step into
|
|
84
84
|
}
|
|
@@ -101,7 +101,7 @@ class Semantic {
|
|
|
101
101
|
this.fixUpArgs(args, contextPrime)
|
|
102
102
|
|
|
103
103
|
return await debug.hitScoped(args.callId, async () => {
|
|
104
|
-
if ((options.debug || {}).apply || args.callId === this.callId || process.env.
|
|
104
|
+
if ((options.debug || {}).apply || args.callId === this.callId || process.env.DEBUG_BREAKAT == args.callId) {
|
|
105
105
|
debugger // eslint-disable-line no-debugger // STEP ABOUT THREE TIMES TO THE DEBUG LINE
|
|
106
106
|
}
|
|
107
107
|
if (args.breakOnSemantics) {
|
|
@@ -226,6 +226,7 @@ class Semantics {
|
|
|
226
226
|
}
|
|
227
227
|
contextPrime = await semantic.apply(args, context, s, options)
|
|
228
228
|
if (continueWasCalled) {
|
|
229
|
+
context = contextPrime
|
|
229
230
|
continue
|
|
230
231
|
}
|
|
231
232
|
if (deferWasCalled) {
|
|
@@ -255,27 +256,31 @@ class Semantics {
|
|
|
255
256
|
const widths = Lines.addRemainder([10, 10])
|
|
256
257
|
const lines = new Lines(widths)
|
|
257
258
|
lines.setElement(0, 0, 'Semantic')
|
|
259
|
+
lines.setElement(0, 1, `#${context.context_id || "?"}`)
|
|
258
260
|
const source = `${semantic.km}/#${semantic.index}`
|
|
259
261
|
lines.setElement(0, 2, `ERROR while applying (${source}) ${semantic.toLabel()}`)
|
|
260
262
|
lines.newRow()
|
|
261
|
-
lines.setElement(0, 2, semantic.toString())
|
|
262
|
-
lines.newRow()
|
|
263
263
|
lines.setElement(0, 1, 'DEBUG')
|
|
264
|
-
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or
|
|
264
|
+
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
|
|
265
|
+
lines.newRow()
|
|
266
|
+
lines.setElement(0, 1, 'STACK')
|
|
267
|
+
lines.setElement(0, 2, stack)
|
|
268
|
+
lines.newRow()
|
|
269
|
+
lines.setElement(0, 2, semantic.toString())
|
|
265
270
|
lines.newRow()
|
|
266
271
|
lines.setElement(0, 1, 'TO')
|
|
267
272
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
268
273
|
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
|
269
274
|
lines.newRow()
|
|
270
|
-
lines.setElement(0, 1, 'STACK')
|
|
271
|
-
lines.setElement(0, 2, stack)
|
|
272
|
-
lines.newRow()
|
|
273
275
|
lines.setElement(0, 1, 'ERROR')
|
|
274
276
|
lines.setElement(0, 2, errorMessage)
|
|
275
277
|
this.logs.push(lines.toString())
|
|
276
278
|
const message = `ERROR while applying (${source}) ${semantic.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
|
|
277
279
|
// this.logs.push(message)
|
|
278
280
|
// return [message]
|
|
281
|
+
if (e.reason) {
|
|
282
|
+
throw e
|
|
283
|
+
}
|
|
279
284
|
args.calls.pop()
|
|
280
285
|
throw { error: [message], logs: this.logs, reason: e.reason }
|
|
281
286
|
}
|
|
@@ -285,6 +290,7 @@ class Semantics {
|
|
|
285
290
|
const widths = Lines.addRemainder([10, 10])
|
|
286
291
|
const lines = new Lines(widths)
|
|
287
292
|
lines.setElement(0, 0, 'Semantic')
|
|
293
|
+
lines.setElement(0, 1, `#${context.context_id || "?"}`)
|
|
288
294
|
if (semantic.index > -1 && semantic.km) {
|
|
289
295
|
// lines.setElement(0, 2, `KM '${semantic.km}' ordinal: ${semantic.index} ${ semantic.notes ? semantic.nodes : '' }`)
|
|
290
296
|
lines.setElement(0, 2, semantic.toLabel())
|
|
@@ -293,18 +299,18 @@ class Semantics {
|
|
|
293
299
|
lines.setElement(0, 1, 'APPLIED')
|
|
294
300
|
lines.setElement(0, 2, semantic.toLabel())
|
|
295
301
|
lines.newRow()
|
|
296
|
-
lines.setElement(0, 2, semantic.toString())
|
|
297
|
-
lines.newRow()
|
|
298
302
|
lines.setElement(0, 1, 'DEBUG')
|
|
299
|
-
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or
|
|
303
|
+
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
|
|
304
|
+
lines.newRow()
|
|
305
|
+
lines.setElement(0, 1, 'STACK')
|
|
306
|
+
lines.setElement(0, 2, stack)
|
|
307
|
+
lines.newRow()
|
|
308
|
+
lines.setElement(0, 2, semantic.toString())
|
|
300
309
|
lines.newRow()
|
|
301
310
|
lines.setElement(0, 1, 'TO')
|
|
302
311
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
303
312
|
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
|
304
313
|
lines.newRow()
|
|
305
|
-
lines.setElement(0, 1, 'STACK')
|
|
306
|
-
lines.setElement(0, 2, stack)
|
|
307
|
-
lines.newRow()
|
|
308
314
|
lines.setElement(0, 1, 'RESULT')
|
|
309
315
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
310
316
|
lines.setElement(1, 2, JSON.stringify(contextPrime, null, 2))
|
|
@@ -330,13 +336,16 @@ class Semantics {
|
|
|
330
336
|
for (const f of finallyList) {
|
|
331
337
|
await f()
|
|
332
338
|
}
|
|
333
|
-
args.calls.pop()
|
|
334
339
|
if (!applied && debug) {
|
|
335
340
|
const widths = Lines.addRemainder([10, 10])
|
|
336
341
|
const lines = new Lines(widths)
|
|
337
342
|
lines.setElement(0, 0, 'Semantic')
|
|
343
|
+
lines.setElement(0, 1, `#${context.context_id || "?"}`)
|
|
338
344
|
lines.setElement(0, 2, 'No semantic applied')
|
|
339
345
|
lines.newRow()
|
|
346
|
+
lines.setElement(0, 1, 'DEBUG')
|
|
347
|
+
lines.setElement(0, 2, `To debug this use debug.breakAt('${args.calls.current()}') in the code or DEBUG_BREAKAT="${args.calls.current()}"`)
|
|
348
|
+
lines.newRow()
|
|
340
349
|
lines.setElement(0, 1, 'STACK')
|
|
341
350
|
lines.setElement(0, 2, stack)
|
|
342
351
|
lines.newRow()
|
|
@@ -345,6 +354,7 @@ class Semantics {
|
|
|
345
354
|
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
|
346
355
|
this.logs.push(lines.toString())
|
|
347
356
|
}
|
|
357
|
+
args.calls.pop()
|
|
348
358
|
return contextPrime
|
|
349
359
|
}
|
|
350
360
|
|