theprogrammablemind_4wp 7.6.0 → 7.7.0-beta.1
Sign up to get free protection for your applications and to get access to all the features.
- package/client.js +170 -80
- package/package.json +2 -1
- package/runtime.js +1 -0
- package/src/config.js +29 -17
- package/src/flatten.js +3 -0
- package/src/generators.js +112 -123
- package/src/helpers.js +41 -1
- package/src/project.js +3 -1
package/client.js
CHANGED
@@ -173,22 +173,44 @@ const setupArgs = (args, config, logs, hierarchy) => {
|
|
173
173
|
args.theDebugger = {
|
174
174
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
175
175
|
}
|
176
|
-
args.s = (c) => config.getSemantics(logs).apply(args, c)
|
177
|
-
args.g = (c) => config.getGenerators(logs).apply(args, c)
|
178
|
-
args.gp = (c) => config.getGenerators(logs).apply(args, { ...c, paraphrase: true, isResponse: false, response: false})
|
179
|
-
args.gr = (c) => config.getGenerators(logs).apply(args, { ...c, paraphrase: false, isResponse: true })
|
180
176
|
if (!logs) {
|
181
177
|
debugger
|
182
178
|
}
|
183
|
-
args.e = (c) => config.getEvaluator(args.s, args.calls, logs, c)
|
184
179
|
args.log = (message) => logs.push(message)
|
185
|
-
|
186
|
-
args.
|
187
|
-
|
180
|
+
|
181
|
+
args.addAssumedScoped = (args, assumed) => {
|
182
|
+
const addAssumed = (args, ...moreAssumed) => {
|
183
|
+
return { ...args, assumed: Object.assign({}, (args.assumed || {}), ...moreAssumed) }
|
184
|
+
}
|
185
|
+
|
186
|
+
args.s = (c) => config.getSemantics(logs).apply(args, c)
|
187
|
+
args.g = (c, a = {}) => {
|
188
|
+
return config.getGenerators(logs).apply(addAssumed(args, a), c, a)
|
189
|
+
}
|
190
|
+
args.gp = (c, a = {}) => {
|
191
|
+
return config.getGenerators(logs).apply(addAssumed(args, a, {paraphrase: true, isResponse: false, response: false}), c, {paraphrase: true, isResponse: false, response: false})
|
192
|
+
}
|
193
|
+
args.gr = (c, a = {}) => {
|
194
|
+
return config.getGenerators(logs).apply(addAssumed(args, a, {paraphrase: false, isResponse: true}), { ...c, paraphrase: false, isResponse: true })
|
195
|
+
}
|
196
|
+
args.e = (c) => {
|
197
|
+
return config.getEvaluator(args.s, args.calls, logs, c)
|
198
|
+
}
|
199
|
+
args.gs = gs(args.g)
|
200
|
+
args.gsp = gs(args.gp)
|
201
|
+
args.gsr = gs(args.gr)
|
202
|
+
}
|
203
|
+
// for semantics
|
204
|
+
args.addAssumedScoped(args, {})
|
188
205
|
config.getAddedArgs(args)
|
189
206
|
}
|
190
207
|
|
191
208
|
const gs = (g) => (contexts, separator, lastSeparator) => {
|
209
|
+
if (!Array.isArray(contexts)) {
|
210
|
+
debugger
|
211
|
+
throw new Error("Expected a list")
|
212
|
+
}
|
213
|
+
|
192
214
|
let s = ''
|
193
215
|
if (!separator) {
|
194
216
|
separator = ' '
|
@@ -276,8 +298,9 @@ const processContext = (context, { objects = {}, config, logs = [] }) => {
|
|
276
298
|
setupArgs(args, config, logs, hierarchy)
|
277
299
|
|
278
300
|
context = semantics.apply(args, context)
|
279
|
-
const generated = generators.apply(args, context)
|
280
|
-
const
|
301
|
+
const generated = generators.apply(args, context)
|
302
|
+
const assumed = { paraphrase: true, response: false, isResponse: false }
|
303
|
+
const paraphrases = generators.apply({...args, assumed}, context, { paraphrase: true, response: false, isResponse: false })
|
281
304
|
let responses = []
|
282
305
|
if (context.isResponse) {
|
283
306
|
responses = generated
|
@@ -447,37 +470,25 @@ const processContextsB = ({ config, hierarchy, semantics, generators, json, isTe
|
|
447
470
|
continue
|
448
471
|
}
|
449
472
|
let assumed = { isResponse: true };
|
450
|
-
const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
473
|
+
const generated = contextPrime.isResponse ? config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed) : ''
|
451
474
|
let generatedParenthesized = []
|
452
475
|
if (generateParenthesized) {
|
453
476
|
config.parenthesized = true
|
454
|
-
generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
477
|
+
generatedParenthesized = contextPrime.isResponse ? config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed) : ''
|
455
478
|
config.parenthesized = false
|
456
479
|
}
|
457
480
|
// assumed = { paraphrase: true, response: false };
|
458
|
-
assumed = { paraphrase: true };
|
459
|
-
args.g = (c) => config.getGenerators(json.logs).apply(args, c, assumed)
|
460
|
-
args.gp = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: true, isResponse: false, response: false }, assumed)
|
461
|
-
args.gr = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: false }, assumed)
|
462
|
-
args.gs = gs(args.g)
|
463
|
-
args.gsp = gs(args.gsp)
|
464
|
-
args.gsr = gs(args.gr)
|
481
|
+
assumed = { paraphrase: true, isResponse: false, response: false };
|
465
482
|
if (generateParenthesized) {
|
466
483
|
config.parenthesized = false
|
467
484
|
}
|
468
|
-
const paraphrases = config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
485
|
+
const paraphrases = config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed)
|
469
486
|
let paraphrasesParenthesized = []
|
470
487
|
if (generateParenthesized) {
|
471
488
|
config.parenthesized = true
|
472
|
-
paraphrasesParenthesized = config.getGenerators(json.logs).apply(args, contextPrime, assumed)
|
489
|
+
paraphrasesParenthesized = config.getGenerators(json.logs).apply({...args, assumed}, contextPrime, assumed)
|
473
490
|
config.parenthesized = false
|
474
491
|
}
|
475
|
-
args.g = (c) => config.getGenerators(json.logs).apply(args, c)
|
476
|
-
args.gp = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: true, isResponse: false, response: false })
|
477
|
-
args.gr = (c) => config.getGenerators(json.logs).apply(args, {...c, paraphrase: false })
|
478
|
-
args.gs = gs(args.g)
|
479
|
-
args.gsp = gs(args.gp)
|
480
|
-
args.gsr = gs(args.gr)
|
481
492
|
contextsPrime.push(contextPrime)
|
482
493
|
generatedPrime.push(generated)
|
483
494
|
paraphrasesPrime.push(paraphrases)
|
@@ -614,7 +625,12 @@ const loadInstance = (config, instance) => {
|
|
614
625
|
if (results.skipSemantics) {
|
615
626
|
config.config.skipSemantics = results.skipSemantics
|
616
627
|
}
|
617
|
-
|
628
|
+
const args = { config, hierarchy, json: results, commandLineArgs: {} }
|
629
|
+
if (instance.queries) {
|
630
|
+
args.isInstance = `instance${i}`
|
631
|
+
args.instance = instance.queries[i]
|
632
|
+
}
|
633
|
+
processContextsB(args)
|
618
634
|
if (results.skipSemantics) {
|
619
635
|
config.config.skipSemantics = null
|
620
636
|
}
|
@@ -660,6 +676,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
660
676
|
opChoices: []
|
661
677
|
},
|
662
678
|
times: 0.0,
|
679
|
+
clientSideTimes: 0.0,
|
663
680
|
trace: '',
|
664
681
|
contexts: [],
|
665
682
|
generated: [],
|
@@ -701,8 +718,16 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
701
718
|
if (json.status !== 200) {
|
702
719
|
throw json
|
703
720
|
} else {
|
721
|
+
let clientSideTime
|
722
|
+
if (isTest) {
|
723
|
+
start = runtime.performance.performance.now()
|
724
|
+
}
|
704
725
|
const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
705
726
|
processContextsB({ isTest, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
727
|
+
if (isTest) {
|
728
|
+
end = runtime.performance.performance.now()
|
729
|
+
clientSideTime = end - start
|
730
|
+
}
|
706
731
|
response.associations = json.associations
|
707
732
|
response.learned_contextual_priorities = json.learned_contextual_priorities
|
708
733
|
response.hierarchy = json.hierarchy
|
@@ -713,6 +738,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
713
738
|
// appendNoDups(response.metadata.priorities, json.metadata.priorities)
|
714
739
|
appendNoDups(response.metadata.opChoices, json.metadata.opChoices)
|
715
740
|
response.times += json.times
|
741
|
+
response.clientSideTimes += clientSideTime
|
716
742
|
response.trace = response.trace.concat(json.trace)
|
717
743
|
response.version = json.version
|
718
744
|
response.explain_priorities = json.explain_priorities
|
@@ -778,10 +804,6 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
778
804
|
const test = expected.query
|
779
805
|
// initialize in between test so state is not preserved since the test was adding without state
|
780
806
|
config.rebuild()
|
781
|
-
if (!args.dontAddAssociations) {
|
782
|
-
config.addAssociationsFromTests(config.tests)
|
783
|
-
}
|
784
|
-
// config.addAssocationsFromTests(
|
785
807
|
const errorHandler = (error) => {
|
786
808
|
if (error.metadata) {
|
787
809
|
const priorities = analyzeMetaData(expected.metadata, error.metadata)
|
@@ -806,10 +828,10 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
806
828
|
defaultInnerProcess(config, errorHandler, result)
|
807
829
|
}
|
808
830
|
if (verbose) {
|
809
|
-
const widths = [100,
|
831
|
+
const widths = [100, 60]
|
810
832
|
const lines = new Lines(widths)
|
811
833
|
lines.setElement(0, 0, test)
|
812
|
-
lines.setElement(0, 1, `time on server ${result.times.toFixed(2)}`)
|
834
|
+
lines.setElement(0, 1, `time on server: ${result.times.toFixed(2)} client: ${(result.clientSideTimes/1000).toFixed(2)}`)
|
813
835
|
lines.log()
|
814
836
|
}
|
815
837
|
const expected_objects = sortJson(convertToStable(expected.objects), { depth: 25 })
|
@@ -1173,7 +1195,7 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1173
1195
|
}
|
1174
1196
|
|
1175
1197
|
if (responses.explain_priorities) {
|
1176
|
-
console.log("Explain Priorities")
|
1198
|
+
console.log("Explain Priorities (listed from lower priority to higher priority)")
|
1177
1199
|
for ([inputss, outpus, reason] of responses.explain_priorities) {
|
1178
1200
|
console.log(` ${JSON.stringify(inputss)} reason: ${reason}`)
|
1179
1201
|
}
|
@@ -1232,7 +1254,7 @@ const defaultProcess = ({ config, errorHandler }) => async (promise) => {
|
|
1232
1254
|
}
|
1233
1255
|
|
1234
1256
|
// builtTemplate saveInstance
|
1235
|
-
const rebuildTemplate = async ({ config, target, template, errorHandler = defaultErrorHandler }) => {
|
1257
|
+
const rebuildTemplate = async ({ config, target, previousResultss, startOfChanges, template, errorHandler = defaultErrorHandler }) => {
|
1236
1258
|
const accumulators = {
|
1237
1259
|
resultss: [],
|
1238
1260
|
fragments: [],
|
@@ -1245,7 +1267,7 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1245
1267
|
finish()
|
1246
1268
|
return
|
1247
1269
|
}
|
1248
|
-
const { property, hierarchy, query: queryOrExtraConfig, initializer, skipSemantics } = queries.shift()
|
1270
|
+
const { property, hierarchy, query: queryOrExtraConfig, previousResults, initializer, skipSemantics } = queries.shift()
|
1249
1271
|
// queries are strings or { query: "blah", development: true/false }
|
1250
1272
|
if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
|
1251
1273
|
let query = queryOrExtraConfig;
|
@@ -1267,17 +1289,26 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1267
1289
|
}
|
1268
1290
|
}
|
1269
1291
|
try {
|
1270
|
-
|
1292
|
+
let results
|
1293
|
+
let prMessage = ''
|
1294
|
+
if (previousResults && previousResults.query == query.query) {
|
1295
|
+
results = previousResults
|
1296
|
+
prMessage = ' Using previous results. use -rtf for a hard rebuild of everything on the server side.'
|
1297
|
+
loadInstance(config, { resultss: [results] })
|
1298
|
+
} else {
|
1299
|
+
results = await _process(config, query.query, {initializer, rebuildingTemplate: true})
|
1300
|
+
}
|
1271
1301
|
if (config.config.debug) {
|
1272
1302
|
// TODO pass in the error handler like the other ones
|
1273
1303
|
defaultInnerProcess(config, defaultErrorHandler, results)
|
1274
1304
|
}
|
1275
1305
|
if (results.contexts.length > 1) {
|
1276
1306
|
console.log(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1307
|
+
throw new Error(`query "${query.query}". There is ${results.contexts.length} contexts in the results. Make sure its producing the results that you expect.`)
|
1277
1308
|
} else if (results.paraphrases[0] != query.query) {
|
1278
|
-
console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}"
|
1309
|
+
console.log(`query "${query.query}". The paraphrase is different from the query "${results.paraphrases[0]}".${prMessage}`)
|
1279
1310
|
} else {
|
1280
|
-
console.log(`query ${query.query}`)
|
1311
|
+
console.log(`query "${query.query}".${prMessage}`)
|
1281
1312
|
}
|
1282
1313
|
global.transitoryMode = transitoryMode
|
1283
1314
|
config.config.skipSemantics = null
|
@@ -1299,14 +1330,18 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1299
1330
|
// it will just get added to the config
|
1300
1331
|
const extraConfig = queryOrExtraConfig
|
1301
1332
|
console.log('config', extraConfig)
|
1302
|
-
|
1303
|
-
|
1304
|
-
}
|
1305
|
-
|
1306
|
-
|
1333
|
+
if (extraConfig.stop) {
|
1334
|
+
await looper([])
|
1335
|
+
} else {
|
1336
|
+
try {
|
1337
|
+
config.addInternal(_.cloneDeep(extraConfig), { handleCalculatedProps: true } )
|
1338
|
+
} catch ( e ) {
|
1339
|
+
const where = extraConfig.where ? ` ${extraConfig.where}` : ''
|
1340
|
+
throw new Error(`Error processing extra config${where}: ${e.stack}}`)
|
1341
|
+
}
|
1342
|
+
accumulators[property].push({ extraConfig: true, ...extraConfig })
|
1343
|
+
await looper(queries)
|
1307
1344
|
}
|
1308
|
-
accumulators[property].push({ extraConfig: true, ...extraConfig })
|
1309
|
-
await looper(queries)
|
1310
1345
|
}
|
1311
1346
|
}
|
1312
1347
|
|
@@ -1327,6 +1362,7 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1327
1362
|
} else {
|
1328
1363
|
delete result.load_cache_time
|
1329
1364
|
delete result.times
|
1365
|
+
delete result.clientSideTimes
|
1330
1366
|
delete result.memory_free_percent
|
1331
1367
|
delete result.logs
|
1332
1368
|
delete result.version
|
@@ -1360,13 +1396,41 @@ const rebuildTemplate = async ({ config, target, template, errorHandler = defaul
|
|
1360
1396
|
}
|
1361
1397
|
let todo = []
|
1362
1398
|
todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false || query.skipSemantics } }))
|
1363
|
-
todo = todo.concat((template.queries || []).map((query) => {
|
1399
|
+
todo = todo.concat((template.queries || []).map((query, index) => {
|
1400
|
+
let pr
|
1401
|
+
if (index < startOfChanges) {
|
1402
|
+
pr = previousResultss[index]
|
1403
|
+
}
|
1404
|
+
return { property: 'resultss', query, previousResults: pr, skipSemantics: false || query.skipSemantics}
|
1405
|
+
}))
|
1364
1406
|
todo = todo.concat((template.fragments || []).map((query) => { return Object.assign({}, toProperties(query), { property: 'fragments', skipSemantics: false }) }))
|
1365
1407
|
todo = todo.concat((template.semantics || []).map((definition) => { return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true } }))
|
1366
1408
|
await looper(Object.assign([], todo))
|
1367
1409
|
}
|
1368
1410
|
|
1369
|
-
const
|
1411
|
+
const checkTemplate = (template) => {
|
1412
|
+
return
|
1413
|
+
if (!template) {
|
1414
|
+
return
|
1415
|
+
}
|
1416
|
+
if (template.checks) {
|
1417
|
+
throw new Error("The 'checks' property should be in the 'test' property not the 'template' property")
|
1418
|
+
}
|
1419
|
+
}
|
1420
|
+
|
1421
|
+
const checkTest = (testConfig) => {
|
1422
|
+
if (!testConfig) {
|
1423
|
+
return
|
1424
|
+
}
|
1425
|
+
if (!testConfig.name) {
|
1426
|
+
throw new Error("The 'test' property is missing the 'name' property that contains the name of the '<km>.test.json' file")
|
1427
|
+
}
|
1428
|
+
if (!testConfig.contents) {
|
1429
|
+
throw new Error("The 'test' property is missing the 'contents' property that contains contents of the '<km>.test.json' file")
|
1430
|
+
}
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
const knowledgeModuleImpl = async ({
|
1370
1434
|
module: moduleFromJSFile,
|
1371
1435
|
description,
|
1372
1436
|
section,
|
@@ -1399,9 +1463,10 @@ const knowledgeModule = async ({
|
|
1399
1463
|
if (!description) {
|
1400
1464
|
throw new Error("'description' is a required parameter. The value should the description of the knowledge module.")
|
1401
1465
|
}
|
1402
|
-
if (!
|
1466
|
+
if (!testConfig) {
|
1403
1467
|
throw new Error("'test' is a required parameter. The value should the path to the file used to store the tests of the knowledge module and the contents of the file in the form { name: <filePath>, contexts: <json> }.")
|
1404
1468
|
}
|
1469
|
+
checkTest(testConfig)
|
1405
1470
|
|
1406
1471
|
const isProcess = require.main === moduleFromJSFile
|
1407
1472
|
|
@@ -1452,13 +1517,14 @@ const knowledgeModule = async ({
|
|
1452
1517
|
parser.add_argument('-tnp', '--testNoParenthesized', { action: 'store_true', help: 'Don\' check parenthesized differences for the tests' })
|
1453
1518
|
parser.add_argument('-n', '--count', { help: 'Number of times to run the tests. Default is one. Use this to check for flakey test. If possible the system will print out a message with the word "hint" suggesting how to fix the problem' })
|
1454
1519
|
// parser.add_argument('-b', '--build', { help: 'Specify the template file name of the form <kmName>. There should be a file called <baseKmName>.<kmName>.template.json with the queries to run. For example { queries: [...] }. The template file will be run and generate an instantiation called <baseKmName>.<kmName>.instance.json and a file called <kmName>.js that will load the template file (this is file generated only if not already existing) and a test file called <KmName>.tests.json. This can then be loaded into an instance of the current knowledge module to setup initial conditions.' })
|
1455
|
-
parser.add_argument('-rt', '--rebuildTemplate', { action: 'store_true', help: 'Force a template rebuild' })
|
1520
|
+
parser.add_argument('-rt', '--rebuildTemplate', { action: 'store_true', help: 'Force a template rebuild. Using optimization where if the query/config has not changed it will use the previous value. One there is a change all subsequence query/configs will be run.' })
|
1521
|
+
parser.add_argument('-rtf', '--rebuildTemplateFull', { action: 'store_true', help: 'Force a template rebuild. Skip the optimization' })
|
1456
1522
|
parser.add_argument('-l', '--loop', { action: 'store_true', help: 'Run a loop so that multiply queries may be run' })
|
1457
1523
|
parser.add_argument('-i', '--info', { action: 'store_true', help: 'Print meta-data for the module' })
|
1458
1524
|
parser.add_argument('-v', '--vimdiff', { action: 'store_true', help: 'For failures run vimdiff' })
|
1459
1525
|
parser.add_argument('-g', '--greg', { action: 'store_true', help: 'Set the server to be localhost so I can debug stuff' })
|
1460
1526
|
parser.add_argument('-cl', '--checkForLoop', { nargs: "?", help: 'Check for loops in the priorities, Optional argument is list of operator keys to consider. For example [["banana", 0], ["food", 1]]' })
|
1461
|
-
parser.add_argument('-r', '--
|
1527
|
+
parser.add_argument('-r', '--reset', { action: 'store_true', help: 'Get the server to bypass the cache and rebuild everything' })
|
1462
1528
|
parser.add_argument('-q', '--query', { help: 'Run the specified query' })
|
1463
1529
|
parser.add_argument('-ip ', '--server', { help: 'Server to run against' })
|
1464
1530
|
parser.add_argument('-qp ', '--queryParams', { help: 'Query params for the server call' })
|
@@ -1466,7 +1532,6 @@ const knowledgeModule = async ({
|
|
1466
1532
|
parser.add_argument('--parenthesized', { action: 'store_true', help: 'Show the generated phrases with parenthesis.' })
|
1467
1533
|
parser.add_argument('-c', '--clean', { help: 'Remove data from the test files. a === association' })
|
1468
1534
|
parser.add_argument('-od', '--objectDiff', { action: 'store_true', help: 'When showing the objects use a colour diff' })
|
1469
|
-
parser.add_argument('-daa', '--dontAddAssociations', { action: 'store_true', help: 'Do not add associations from the tests.' })
|
1470
1535
|
parser.add_argument('-p', '--print', { help: 'Print the specified elements c === config, w === words, b === bridges, o === operators d === objects (d for data), h === hierarchy, g === generators, s === semantics, l === load t=tests ordering p === priorities a == associations j == JSON sent to server. for example --print wb' })
|
1471
1536
|
parser.add_argument('-s', '--save', { action: 'store_true', help: 'When running with the --query flag this will save the current run to the test file. When running without the --query flag all tests will be run and resaved.' })
|
1472
1537
|
parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
|
@@ -1484,6 +1549,10 @@ const knowledgeModule = async ({
|
|
1484
1549
|
const args = parser.parse_args()
|
1485
1550
|
args.count = args.count || 1
|
1486
1551
|
|
1552
|
+
if (args.rebuildTemplateFull) {
|
1553
|
+
args.rebuildTemplate = true
|
1554
|
+
}
|
1555
|
+
|
1487
1556
|
if (args.parenthesized) {
|
1488
1557
|
config.parenthesized = true
|
1489
1558
|
}
|
@@ -1671,24 +1740,40 @@ const knowledgeModule = async ({
|
|
1671
1740
|
}
|
1672
1741
|
}
|
1673
1742
|
|
1743
|
+
checkTemplate(template)
|
1744
|
+
|
1674
1745
|
if (template) {
|
1675
|
-
|
1676
|
-
if (
|
1746
|
+
let needsRebuild
|
1747
|
+
if (args.rebuildTemplate && !args.rebuildTemplateFull) {
|
1748
|
+
// get the startOfChanges for the partial rebuild
|
1749
|
+
needsRebuild = config.needsRebuild(template.template, template.instance, { ...options, rebuild: false })
|
1750
|
+
} else {
|
1751
|
+
// do a check or full rebuild
|
1752
|
+
needsRebuild = config.needsRebuild(template.template, template.instance, options)
|
1753
|
+
}
|
1754
|
+
|
1755
|
+
if (needsRebuild.needsRebuild) {
|
1756
|
+
if (needsRebuild.previousResultss) {
|
1757
|
+
console.log("Rebuild using the optimization to use previous results until a change is hit. For a full rebuild use -rtf")
|
1758
|
+
}
|
1677
1759
|
console.log(`This module "${config.name}" needs rebuilding all other arguments will be ignored. Try again after the template is rebuilt.`)
|
1678
1760
|
options.rebuild = true
|
1679
1761
|
config.config.rebuild = true
|
1680
1762
|
}
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1763
|
+
try {
|
1764
|
+
config.load(template.template, template.instance, { rebuild: needsRebuild.needsRebuild || options.rebuild, previousResultss: needsRebuild.previousResultss, startOfChanges: needsRebuild.startOfChanges })
|
1765
|
+
} catch( e ) {
|
1766
|
+
console.error(`Error loading template for ${config.name}. ${e.error ? e.error : e}`)
|
1767
|
+
runtime.process.exit(-1)
|
1768
|
+
}
|
1769
|
+
if (!args.query) {
|
1770
|
+
printConfig()
|
1771
|
+
}
|
1772
|
+
if (needsRebuild.needsRebuild) {
|
1684
1773
|
return
|
1685
1774
|
}
|
1686
1775
|
}
|
1687
1776
|
|
1688
|
-
if (!args.save && !args.rebuildTemplate && !args.dontAddAssociations) {
|
1689
|
-
config.addAssociationsFromTests(config.tests);
|
1690
|
-
}
|
1691
|
-
|
1692
1777
|
if (args.retrain) {
|
1693
1778
|
config.config.retrain = true
|
1694
1779
|
}
|
@@ -1696,7 +1781,6 @@ const knowledgeModule = async ({
|
|
1696
1781
|
if (args.test || args.testVerbose || args.testAllVerbose || args.save) {
|
1697
1782
|
global.transitoryMode = true
|
1698
1783
|
}
|
1699
|
-
|
1700
1784
|
if (!args.query && !args.test && !args.info && (args.save || args.saveDeveloper)) {
|
1701
1785
|
global.transitoryMode = true
|
1702
1786
|
saveTests(config, test, testConfig, args.saveDeveloper)
|
@@ -1718,7 +1802,6 @@ const knowledgeModule = async ({
|
|
1718
1802
|
useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
1719
1803
|
useTestConfig.testModuleName = args.testModuleName
|
1720
1804
|
test = useTestConfig.name
|
1721
|
-
|
1722
1805
|
}
|
1723
1806
|
runTests(config, test, { args, debug: args.debug, testConfig: useTestConfig, verbose: args.testVerbose || args.testAllVerbose, stopAtFirstError: !args.testAllVerbose }).then((results) => {
|
1724
1807
|
let newError = false
|
@@ -1762,17 +1845,21 @@ const knowledgeModule = async ({
|
|
1762
1845
|
console.log(` actual ${label} `, actual)
|
1763
1846
|
newError = true
|
1764
1847
|
headerShown = true
|
1848
|
+
if (args.vimdiff) {
|
1849
|
+
vimdiff(result.actual.paraphrasesParenthesized, result.expected.paraphrasesParenthesized)
|
1850
|
+
}
|
1765
1851
|
}
|
1766
1852
|
}
|
1767
1853
|
show('paraphrases', result.expected.paraphrases, result.actual.paraphrases)
|
1768
1854
|
if (!args.testNoParenthesized) {
|
1769
1855
|
show('paraphrases parenthesized', result.expected.paraphrasesParenthesized, result.actual.paraphrasesParenthesized)
|
1770
1856
|
}
|
1857
|
+
/*
|
1858
|
+
}
|
1771
1859
|
show('responses', result.expected.responses, result.actual.responses)
|
1772
1860
|
if (!args.testNoParenthesized) {
|
1773
1861
|
show('responses parenthesized', result.expected.generatedParenthesized, result.actual.generatedParenthesized)
|
1774
1862
|
}
|
1775
|
-
/*
|
1776
1863
|
if (JSON.stringify(result.expected.paraphrases) !== JSON.stringify(result.actual.paraphrases)) {
|
1777
1864
|
if (!headerShown) {
|
1778
1865
|
console.log(' Failure')
|
@@ -1798,10 +1885,10 @@ const knowledgeModule = async ({
|
|
1798
1885
|
}
|
1799
1886
|
const widths = [4, 18, 72]
|
1800
1887
|
const lines = new Lines(widths)
|
1801
|
-
lines.setElement(1, 1, 'expected checked')
|
1888
|
+
lines.setElement(1, 1, 'expected checked objects')
|
1802
1889
|
lines.setElement(2, 2, JSON.stringify(result.expected.checked, null, 2))
|
1803
1890
|
lines.log()
|
1804
|
-
lines.setElement(1, 1, 'actual checked')
|
1891
|
+
lines.setElement(1, 1, 'actual checked objects')
|
1805
1892
|
lines.setElement(2, 2, JSON.stringify(result.actual.checked, null, 2))
|
1806
1893
|
lines.log()
|
1807
1894
|
if (args.vimdiff) {
|
@@ -1816,10 +1903,10 @@ const knowledgeModule = async ({
|
|
1816
1903
|
}
|
1817
1904
|
const widths = [4, 18, 72]
|
1818
1905
|
const lines = new Lines(widths)
|
1819
|
-
lines.setElement(1, 1, 'expected
|
1906
|
+
lines.setElement(1, 1, 'expected checked contexts', true)
|
1820
1907
|
lines.setElement(2, 2, JSON.stringify(result.expected.checkedContexts, null, 2))
|
1821
1908
|
lines.log()
|
1822
|
-
lines.setElement(1, 1, 'actual
|
1909
|
+
lines.setElement(1, 1, 'actual checked contexts', true)
|
1823
1910
|
lines.setElement(2, 2, JSON.stringify(result.actual.checkedContexts, null, 2))
|
1824
1911
|
lines.log()
|
1825
1912
|
if (args.vimdiff) {
|
@@ -1836,16 +1923,18 @@ const knowledgeModule = async ({
|
|
1836
1923
|
}
|
1837
1924
|
}
|
1838
1925
|
}
|
1839
|
-
if (
|
1926
|
+
if (hasError) {
|
1927
|
+
if (!headerShown) {
|
1928
|
+
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1929
|
+
console.log('There are failures due to things other than paraphrases, responses and checked properties being different. They are not shown because you ran -tv or -tva which only shows difference in paraphrase and results. Usually what I do is -s and do a diff to make sure there are no other problems. If the paraphrases or results were different they would have shown here.')
|
1930
|
+
}
|
1931
|
+
}
|
1840
1932
|
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1841
|
-
console.log('
|
1933
|
+
console.log('use -v arg to write files expected.json and actual.json in the current directory for detailed comparison. Or do -s and then git diff the changes.')
|
1934
|
+
// console.log(JSON.stringify(contexts))
|
1935
|
+
console.log('**************************** THERE WERE ERRORS ************************')
|
1842
1936
|
}
|
1843
1937
|
}
|
1844
|
-
if (!(useTestConfig.check && useTestConfig.check.length > 0)) {
|
1845
|
-
console.log('use -v arg to write files expected.json and actual.json in the current directory for detailed comparison. Or do -s and then git diff the changes.')
|
1846
|
-
// console.log(JSON.stringify(contexts))
|
1847
|
-
console.log('**************************** ERRORS ************************')
|
1848
|
-
}
|
1849
1938
|
}
|
1850
1939
|
// const contexts = { failures: results }
|
1851
1940
|
l(n - 1, hasError || newError)
|
@@ -1929,7 +2018,7 @@ const knowledgeModule = async ({
|
|
1929
2018
|
}
|
1930
2019
|
|
1931
2020
|
if (template) {
|
1932
|
-
if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess })) {
|
2021
|
+
if (config.needsRebuild(template.template, template.instance, { isModule: !isProcess }).needsRebuild) {
|
1933
2022
|
const error = `This module "${config.name}" cannot be used because the instance file needs rebuilding. Run on the command line with no arguments or the -rt argument to rebuild.`
|
1934
2023
|
throw new Error(error)
|
1935
2024
|
}
|
@@ -1939,8 +2028,6 @@ const knowledgeModule = async ({
|
|
1939
2028
|
errorHandler(e)
|
1940
2029
|
}
|
1941
2030
|
}
|
1942
|
-
|
1943
|
-
config.addAssociationsFromTests(config.tests);
|
1944
2031
|
}
|
1945
2032
|
|
1946
2033
|
createConfigExport = () => {
|
@@ -1951,7 +2038,6 @@ const knowledgeModule = async ({
|
|
1951
2038
|
}
|
1952
2039
|
moduleFromJSFile.exports = createConfigExport
|
1953
2040
|
}
|
1954
|
-
|
1955
2041
|
}
|
1956
2042
|
|
1957
2043
|
/*
|
@@ -1999,6 +2085,10 @@ function w(func) {
|
|
1999
2085
|
return func
|
2000
2086
|
}
|
2001
2087
|
|
2088
|
+
const knowledgeModule = async (...args) => {
|
2089
|
+
await knowledgeModuleImpl(...args).catch((e) => console.error(e))
|
2090
|
+
}
|
2091
|
+
|
2002
2092
|
module.exports = {
|
2003
2093
|
process: _process,
|
2004
2094
|
where,
|
package/package.json
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
"scripts": {
|
13
13
|
"to:debug": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
|
14
14
|
"test:debug": "node inspect node_modules/.bin/jest --runInBand --config ./jest.config.json",
|
15
|
+
"td": "node inspect node_modules/.bin/jest --runInBand --config ./jest.config.json",
|
15
16
|
"tod": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
|
16
17
|
"lint:fix": "eslint \"**/*.js\" --fix",
|
17
18
|
"lint": "eslint \"**/*.js\"",
|
@@ -64,6 +65,6 @@
|
|
64
65
|
"json-stable-stringify": "^1.0.1",
|
65
66
|
"node-fetch": "^2.6.1"
|
66
67
|
},
|
67
|
-
"version": "7.
|
68
|
+
"version": "7.7.0-beta.1",
|
68
69
|
"license": "ISC"
|
69
70
|
}
|
package/runtime.js
CHANGED
package/src/config.js
CHANGED
@@ -27,7 +27,7 @@ const config_toServer = (config) => {
|
|
27
27
|
|
28
28
|
const debugPriority = (priority) => {
|
29
29
|
if (global.entodictonDebugPriority) {
|
30
|
-
if (helpers.
|
30
|
+
if (helpers.subPriority(entodictonDebugPriority, priority)) {
|
31
31
|
debugger; // debug hierarchy hit
|
32
32
|
}
|
33
33
|
}
|
@@ -965,7 +965,7 @@ class Config {
|
|
965
965
|
}
|
966
966
|
|
967
967
|
// { rebuild: false, isModule: false }
|
968
|
-
needsRebuild(template, instance, options) {
|
968
|
+
needsRebuild (template, instance, options) {
|
969
969
|
if (options.rebuild) {
|
970
970
|
return true
|
971
971
|
}
|
@@ -1058,7 +1058,21 @@ class Config {
|
|
1058
1058
|
return elements.map( toCanonicalQuery )
|
1059
1059
|
}
|
1060
1060
|
|
1061
|
-
const
|
1061
|
+
const templateQueries = toCanonicalQueries(template.queries || []).map(helpers.updateQueries)
|
1062
|
+
const instanceQueries = toCanonicalQueries(instance.queries || [])
|
1063
|
+
let sameQueries = true
|
1064
|
+
let startOfChanges;
|
1065
|
+
for (let iq = 0; iq < templateQueries.length; ++iq) {
|
1066
|
+
if (!helpers.safeEquals(templateQueries[iq], instanceQueries[iq])) {
|
1067
|
+
sameQueries = false
|
1068
|
+
startOfChanges = iq
|
1069
|
+
}
|
1070
|
+
}
|
1071
|
+
// things were deleted case
|
1072
|
+
if (templateQueries.length < instanceQueries.length) {
|
1073
|
+
startOfChanges = instanceQueries.length
|
1074
|
+
}
|
1075
|
+
// const sameQueries = helpers.safeEquals(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), toCanonicalQueries(instance.queries || []))
|
1062
1076
|
|
1063
1077
|
const debug = false
|
1064
1078
|
if (debug) {
|
@@ -1067,16 +1081,20 @@ class Config {
|
|
1067
1081
|
debugger
|
1068
1082
|
debugger
|
1069
1083
|
}
|
1070
|
-
console.log("instance", instance)
|
1084
|
+
// console.log("instance", instance)
|
1071
1085
|
console.log("sameQueries", sameQueries)
|
1072
1086
|
console.log("sameFragments", sameFragments)
|
1073
|
-
console.log("templateFragments", templateFragments)
|
1074
|
-
console.log("instanceFragments", instanceFragments)
|
1075
|
-
console.log('template.queries', JSON.stringify(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), null, 2))
|
1076
|
-
console.log("instance.queries", JSON.stringify(toCanonicalQueries(instance.queries || []), null, 2))
|
1087
|
+
// console.log("templateFragments", templateFragments)
|
1088
|
+
// console.log("instanceFragments", instanceFragments)
|
1089
|
+
// console.log('template.queries', JSON.stringify(toCanonicalQueries(template.queries || []).map(helpers.updateQueries), null, 2))
|
1090
|
+
// console.log("instance.queries", JSON.stringify(toCanonicalQueries(instance.queries || []), null, 2))
|
1077
1091
|
}
|
1078
1092
|
}
|
1079
|
-
|
1093
|
+
if (startOfChanges || instance.resultss) {
|
1094
|
+
return { needsRebuild: !(instance && sameQueries && sameFragments), startOfChanges, previousResultss: instance.resultss }
|
1095
|
+
} else {
|
1096
|
+
return { needsRebuild: !(instance && sameQueries && sameFragments) }
|
1097
|
+
}
|
1080
1098
|
}
|
1081
1099
|
|
1082
1100
|
validifyTemplate (template) {
|
@@ -1097,7 +1115,7 @@ class Config {
|
|
1097
1115
|
}
|
1098
1116
|
|
1099
1117
|
// loadTemplate
|
1100
|
-
load (template, instance, options = { rebuild: false } ) {
|
1118
|
+
load (template, instance, options = { rebuild: false, previousResultss: undefined, startOfChanges: undefined } ) {
|
1101
1119
|
this.validifyTemplate(template)
|
1102
1120
|
instance.template = template
|
1103
1121
|
this.logs.push(`loading template for ${this.name}`)
|
@@ -1105,7 +1123,7 @@ class Config {
|
|
1105
1123
|
// TODO fix beforeQuery
|
1106
1124
|
template = { fragments: [], queries: [], ...template }
|
1107
1125
|
template.fragments = template.fragments.concat(this.dynamicFragments)
|
1108
|
-
client.rebuildTemplate({ config: this, target: this.name, beforeQuery: () => {}, template, ...options })
|
1126
|
+
client.rebuildTemplate({ config: this, target: this.name, previousResultss: options.previousResultss, startOfChanges: options.startOfChanges, beforeQuery: () => {}, template, ...options })
|
1109
1127
|
} else {
|
1110
1128
|
// no change
|
1111
1129
|
// this.initInstances.push({ ...instance, name: config.name })
|
@@ -1137,12 +1155,6 @@ class Config {
|
|
1137
1155
|
return this.config.objects.namespaced[this._uuid]
|
1138
1156
|
}
|
1139
1157
|
|
1140
|
-
addAssociationsFromTests(tests = []) {
|
1141
|
-
for (let test of tests) {
|
1142
|
-
this.addAssociations(test.associations || []);
|
1143
|
-
}
|
1144
|
-
}
|
1145
|
-
|
1146
1158
|
addAssociations (associations) {
|
1147
1159
|
for (let association of associations) {
|
1148
1160
|
this.addAssociation(association)
|
package/src/flatten.js
CHANGED
package/src/generators.js
CHANGED
@@ -73,7 +73,8 @@ class Generator {
|
|
73
73
|
return matches
|
74
74
|
}
|
75
75
|
|
76
|
-
apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
|
76
|
+
// apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
|
77
|
+
apply (baseArgs, objects, context, hierarchy, config, response, log, options = {}) {
|
77
78
|
if (!log) {
|
78
79
|
throw new Error('generators.apply argument log is required')
|
79
80
|
}
|
@@ -103,12 +104,12 @@ class Generator {
|
|
103
104
|
log,
|
104
105
|
global:
|
105
106
|
objects,
|
106
|
-
g,
|
107
|
+
// g,
|
107
108
|
n,
|
108
109
|
hierarchy,
|
109
110
|
context,
|
110
111
|
uuid: this.uuid,
|
111
|
-
gs,
|
112
|
+
// gs,
|
112
113
|
config,
|
113
114
|
response,
|
114
115
|
api: this.getAPI(config),
|
@@ -165,136 +166,124 @@ class Generators {
|
|
165
166
|
this.logs = logs
|
166
167
|
};
|
167
168
|
|
168
|
-
// assumed - properties added to
|
169
|
-
apply (args,
|
169
|
+
// assumed - properties added to context before the generators are called. For setting paraphrase property
|
170
|
+
apply (args, context, assumed = {}, options = {}) {
|
171
|
+
if (Array.isArray(context)) {
|
172
|
+
throw new Error("Expected a context not an array")
|
173
|
+
}
|
174
|
+
if (typeof context !== 'object') {
|
175
|
+
return String(context)
|
176
|
+
}
|
177
|
+
|
170
178
|
const config = args.config
|
171
179
|
const objects = args.objects
|
172
180
|
const hierarchy = args.hierarchy
|
173
181
|
const response = args.response
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
const
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
}
|
200
|
-
}
|
201
|
-
|
202
|
-
// this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${JSON.stringify(context)}`)
|
203
|
-
let errorMessage = 'The apply function did not return a value'
|
204
|
-
try {
|
205
|
-
generated= generator.apply(args, objects, g, args.gs, context, hierarchy, config, response, log)
|
206
|
-
} catch( e ) {
|
207
|
-
// the next if handle this
|
208
|
-
generated = null
|
209
|
-
e.retryCall = () => generator.apply(args, objects, g, args.gs, context, hierarchy, config, response, log)
|
210
|
-
const help = 'The error has a retryCall property that will recall the function that failed.'
|
211
|
-
if (e.stack && e.message) {
|
212
|
-
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
213
|
-
errorMessage = `Error applying generator '${info}. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}. ${help}`
|
214
|
-
} else if (e.error) {
|
215
|
-
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
216
|
-
errorMessage = `Error applying generator '${info}. Error is ${e.error.join()}. Generator is ${generator.toString()}. ${help}`
|
217
|
-
} else {
|
218
|
-
errorMessage = e.toString()
|
219
|
-
}
|
182
|
+
|
183
|
+
// args = { ...args, ...args.getAssumedScoped(assumed) }
|
184
|
+
args.addAssumedScoped(args, assumed)
|
185
|
+
context = Object.assign({}, context, args.assumed)
|
186
|
+
let generated = ''
|
187
|
+
let applied = false
|
188
|
+
const stack = args.calls.push()
|
189
|
+
for (let igenerator = 0; igenerator < this.generators.length; ++igenerator) {
|
190
|
+
const generator = this.generators[igenerator]
|
191
|
+
if (generator.matches(args, objects, context, hierarchy, config, options)) {
|
192
|
+
const log = (message) => { this.logs.push(message) }
|
193
|
+
// this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${JSON.stringify(context)}`)
|
194
|
+
let errorMessage = 'The apply function did not return a value'
|
195
|
+
try {
|
196
|
+
generated= generator.apply(args, objects, context, hierarchy, config, response, log)
|
197
|
+
} catch( e ) {
|
198
|
+
// the next if handle this
|
199
|
+
generated = null
|
200
|
+
e.retryCall = () => generator.apply(args, objects, context, hierarchy, config, response, log)
|
201
|
+
const help = 'The error has a retryCall property that will recall the function that failed.'
|
202
|
+
if (e.stack && e.message) {
|
203
|
+
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
204
|
+
errorMessage = `Error applying generator '${info}. Error is ${e.toString()} stack is ${e.stack}. Generator is ${generator.toString()}. ${help}`
|
205
|
+
} else if (e.error) {
|
206
|
+
const info = `${generator.notes ? generator.notes : ''}${generator.where ? generator.where : ''}`
|
207
|
+
errorMessage = `Error applying generator '${info}. Error is ${e.error.join()}. Generator is ${generator.toString()}. ${help}`
|
208
|
+
} else {
|
209
|
+
errorMessage = e.toString()
|
220
210
|
}
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
}
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
}
|
257
|
-
lines.newRow()
|
258
|
-
lines.setElement(0, 1, 'APPLIED')
|
211
|
+
}
|
212
|
+
if (!generated && generated !== '') {
|
213
|
+
const widths = [10, 10, 90]
|
214
|
+
const lines = new Lines(widths)
|
215
|
+
lines.setElement(0, 0, 'Generator')
|
216
|
+
const source = `${generator.km}/#${generator.index}`
|
217
|
+
lines.setElement(0, 2, `ERROR while applying (${source}) ${generator.toLabel()}`)
|
218
|
+
lines.newRow()
|
219
|
+
lines.setElement(0, 2, generator.toString())
|
220
|
+
lines.newRow()
|
221
|
+
lines.setElement(0, 1, 'TO')
|
222
|
+
lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
|
223
|
+
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
224
|
+
lines.newRow()
|
225
|
+
lines.setElement(0, 1, 'STACK')
|
226
|
+
lines.setElement(0, 2, stack)
|
227
|
+
lines.newRow()
|
228
|
+
lines.setElement(0, 1, 'DEBUG')
|
229
|
+
lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
|
230
|
+
lines.newRow()
|
231
|
+
lines.setElement(0, 1, 'ERROR')
|
232
|
+
lines.setElement(0, 2, errorMessage)
|
233
|
+
this.logs.push(lines.toString())
|
234
|
+
const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${JSON.stringify(context, null, 2)}.\n${errorMessage}'`
|
235
|
+
// this.logs.push(message)
|
236
|
+
// return [message]
|
237
|
+
args.calls.pop()
|
238
|
+
throw { error: [message], logs: this.logs }
|
239
|
+
}
|
240
|
+
if (((config || {}).config || {}).debug) {
|
241
|
+
const widths = [10, 10, 90]
|
242
|
+
const lines = new Lines(widths)
|
243
|
+
lines.setElement(0, 0, 'Generator')
|
244
|
+
if (generator.index > -1 && generator.km) {
|
245
|
+
// lines.setElement(0, 2, `KM '${generator.km}' ordinal: ${generator.index}`)
|
259
246
|
lines.setElement(0, 2, generator.toLabel())
|
260
|
-
lines.newRow()
|
261
|
-
lines.setElement(0, 2, generator.toString())
|
262
|
-
lines.newRow()
|
263
|
-
lines.setElement(0, 1, 'RESULT')
|
264
|
-
lines.setElement(0, 2, generated)
|
265
|
-
lines.newRow()
|
266
|
-
lines.setElement(0, 1, 'STACK')
|
267
|
-
lines.setElement(0, 2, stack)
|
268
|
-
lines.newRow()
|
269
|
-
lines.setElement(0, 1, 'DEBUG')
|
270
|
-
lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
|
271
|
-
lines.newRow()
|
272
|
-
lines.setElement(0, 1, 'TO')
|
273
|
-
lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
|
274
|
-
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
275
|
-
this.logs.push(lines.toString())
|
276
247
|
}
|
277
|
-
|
278
|
-
|
248
|
+
lines.newRow()
|
249
|
+
lines.setElement(0, 1, 'APPLIED')
|
250
|
+
lines.setElement(0, 2, generator.toLabel())
|
251
|
+
lines.newRow()
|
252
|
+
lines.setElement(0, 2, generator.toString())
|
253
|
+
lines.newRow()
|
254
|
+
lines.setElement(0, 1, 'RESULT')
|
255
|
+
lines.setElement(0, 2, generated)
|
256
|
+
lines.newRow()
|
257
|
+
lines.setElement(0, 1, 'STACK')
|
258
|
+
lines.setElement(0, 2, stack)
|
259
|
+
lines.newRow()
|
260
|
+
lines.setElement(0, 1, 'DEBUG')
|
261
|
+
lines.setElement(0, 2, `To debug this use args.callId == '${args.calls.current()}'`)
|
262
|
+
lines.newRow()
|
263
|
+
lines.setElement(0, 1, 'TO')
|
264
|
+
lines.setElement(0, 2, `(HASHCODE ${helpers.hashCode(JSON.stringify(helpers.sortJson(context, { depth: 25 })))})`)
|
265
|
+
lines.setElement(1, 2, JSON.stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
266
|
+
this.logs.push(lines.toString())
|
279
267
|
}
|
268
|
+
applied = true
|
269
|
+
break
|
280
270
|
}
|
281
|
-
args.calls.pop()
|
282
|
-
if (!applied && ((config || {}).config || {}).debug) {
|
283
|
-
const widths = [10, 10, 90]
|
284
|
-
const lines = new Lines(widths)
|
285
|
-
lines.setElement(0, 0, 'Generator')
|
286
|
-
lines.setElement(0, 2, 'No generator applied')
|
287
|
-
lines.newRow()
|
288
|
-
lines.setElement(0, 1, 'STACK')
|
289
|
-
lines.setElement(0, 2, stack)
|
290
|
-
lines.newRow()
|
291
|
-
lines.setElement(0, 1, 'TO')
|
292
|
-
lines.setElement(0, 2, JSON.stringify(context, null, 2))
|
293
|
-
this.logs.push(lines.toString())
|
294
|
-
}
|
295
|
-
contextsPrime.push((config || {}).parenthesized ? "(" + generated + ")" : generated)
|
296
271
|
}
|
297
|
-
|
272
|
+
args.calls.pop()
|
273
|
+
if (!applied && ((config || {}).config || {}).debug) {
|
274
|
+
const widths = [10, 10, 90]
|
275
|
+
const lines = new Lines(widths)
|
276
|
+
lines.setElement(0, 0, 'Generator')
|
277
|
+
lines.setElement(0, 2, 'No generator applied')
|
278
|
+
lines.newRow()
|
279
|
+
lines.setElement(0, 1, 'STACK')
|
280
|
+
lines.setElement(0, 2, stack)
|
281
|
+
lines.newRow()
|
282
|
+
lines.setElement(0, 1, 'TO')
|
283
|
+
lines.setElement(0, 2, JSON.stringify(context, null, 2))
|
284
|
+
this.logs.push(lines.toString())
|
285
|
+
}
|
286
|
+
return ((config || {}).parenthesized ? "(" + generated + ")" : generated)
|
298
287
|
}
|
299
288
|
}
|
300
289
|
|
package/src/helpers.js
CHANGED
@@ -334,6 +334,45 @@ const ecatch = (where, call) => {
|
|
334
334
|
}
|
335
335
|
}
|
336
336
|
|
337
|
+
const equalKey = (key1, key2) => {
|
338
|
+
return key1[0] == key2[0] && key1[1] == key2[1]
|
339
|
+
}
|
340
|
+
|
341
|
+
// matches for { context: ..., [ordered], choose: ... } exactely OR
|
342
|
+
// [ <id1>, <id2> ] - where id1 is chosen
|
343
|
+
const subPriority = (sub, sup) => {
|
344
|
+
if (Array.isArray(sub)) {
|
345
|
+
const subChoosen = sub[0]
|
346
|
+
const subOther = sub[1]
|
347
|
+
const hasChoosen = sup.choose.find( (index) => equalKey(sup.context[index], subChoosen)) != undefined
|
348
|
+
const hasOtherChosen = sup.choose.find( (index) => equalKey(sup.context[index], subOther)) != undefined
|
349
|
+
const hasOther = sup.context.find( (other) => equalKey(other, subOther) ) !== undefined
|
350
|
+
return !!(hasChoosen && hasOther) && !hasOtherChosen
|
351
|
+
}
|
352
|
+
|
353
|
+
if (!safeEquals([...sub.choose].sort(), [...sup.choose].sort())) {
|
354
|
+
return false
|
355
|
+
}
|
356
|
+
|
357
|
+
const choose = (priority) => {
|
358
|
+
const chosen = []
|
359
|
+
for (const i of priority.choose) {
|
360
|
+
chosen.push(priority.context[i])
|
361
|
+
}
|
362
|
+
return chosen
|
363
|
+
}
|
364
|
+
const chosen1 = choose(sub)
|
365
|
+
const chosen2 = choose(sup)
|
366
|
+
const sameId = (id1, id2) => id1[0] == id2[0] && id1[1] == id2[1]
|
367
|
+
// same length so only need one way
|
368
|
+
const missing1 = chosen1.find( (id1) => !chosen2.find( (id2) => sameId(id1, id2)) )
|
369
|
+
if (missing1) {
|
370
|
+
return false
|
371
|
+
}
|
372
|
+
|
373
|
+
return true
|
374
|
+
}
|
375
|
+
|
337
376
|
module.exports = {
|
338
377
|
ecatch,
|
339
378
|
functionsToStrings,
|
@@ -354,5 +393,6 @@ module.exports = {
|
|
354
393
|
isCompound,
|
355
394
|
InitCalls,
|
356
395
|
hashCode,
|
357
|
-
sortJson
|
396
|
+
sortJson,
|
397
|
+
subPriority,
|
358
398
|
}
|
package/src/project.js
CHANGED
@@ -16,6 +16,9 @@ const project = (object, filter) => {
|
|
16
16
|
return object.map( element => project(element, filter) )
|
17
17
|
} else {
|
18
18
|
for (let properties of filter) {
|
19
|
+
if (typeof properties == 'function') {
|
20
|
+
properties = properties(object)
|
21
|
+
}
|
19
22
|
if (typeof properties == 'object') {
|
20
23
|
if (properties.propertyLists) {
|
21
24
|
for (const propertyList in properties.propertyLists) {
|
@@ -45,7 +48,6 @@ const project = (object, filter) => {
|
|
45
48
|
if (properties.property) {
|
46
49
|
const property = properties.property
|
47
50
|
if (properties.isPropertyList) {
|
48
|
-
debugger
|
49
51
|
if (!Array.isArray(object[property])) {
|
50
52
|
return projection
|
51
53
|
}
|