theprogrammablemind_4wp 7.5.4 → 7.5.5
Sign up to get free protection for your applications and to get access to all the features.
- package/client.js +33 -12
- package/package.json +5 -4
- package/src/config.js +199 -124
- package/src/generators.js +8 -4
- package/src/helpers.js +74 -2
- package/src/semantics.js +8 -4
package/client.js
CHANGED
@@ -8,7 +8,7 @@ const _ = require('lodash')
|
|
8
8
|
const stringify = require('json-stable-stringify')
|
9
9
|
const Lines = require('./lines')
|
10
10
|
const flattens = require('./src/flatten')
|
11
|
-
const { appendNoDups, InitCalls } = require('./src/helpers')
|
11
|
+
const { appendNoDups, InitCalls, updateQueries } = require('./src/helpers')
|
12
12
|
const runtime = require('./runtime')
|
13
13
|
const sortJson = runtime.sortJson
|
14
14
|
|
@@ -478,7 +478,7 @@ const doWithRetries = async (n, url, queryParams, data) => {
|
|
478
478
|
}
|
479
479
|
}
|
480
480
|
|
481
|
-
const setupProcessB = ({ config, allowDelta=false } = {}) => {
|
481
|
+
const setupProcessB = ({ config, initializer, allowDelta=false } = {}) => {
|
482
482
|
const key = config._key
|
483
483
|
|
484
484
|
const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
|
@@ -515,10 +515,13 @@ const processInstance = (config, instance) => {
|
|
515
515
|
const transitoryMode = global.transitoryMode
|
516
516
|
global.transitoryMode = false
|
517
517
|
const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
|
518
|
-
for (const results of (instance.resultss || [])) {
|
518
|
+
// for (const results of (instance.resultss || [])) {
|
519
|
+
for (const i in (instance.resultss || [])) {
|
520
|
+
const results = instance.resultss[i]
|
519
521
|
if (results.extraConfig) {
|
520
522
|
// config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
|
521
|
-
config.addInternal(
|
523
|
+
// config.addInternal(config.template.queries[i], { handleCalculatedProps: true } )
|
524
|
+
config.addInternal(instance.template.queries[i], { handleCalculatedProps: true } )
|
522
525
|
} else {
|
523
526
|
processContextsB({ config, hierarchy, json: results/*, generators, semantics */ })
|
524
527
|
}
|
@@ -526,7 +529,7 @@ const processInstance = (config, instance) => {
|
|
526
529
|
global.transitoryMode = transitoryMode
|
527
530
|
}
|
528
531
|
|
529
|
-
const _process = async (config, query, { commandLineArgs, credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
|
532
|
+
const _process = async (config, query, { initializer, commandLineArgs, credentials, writeTests, isTest, saveDeveloper, testConfig, testsFN, errorHandler = defaultErrorHandler } = {}) => {
|
530
533
|
if (credentials) {
|
531
534
|
config.server(credentials.server, credentials.key)
|
532
535
|
}
|
@@ -546,7 +549,7 @@ const _process = async (config, query, { commandLineArgs, credentials, writeTest
|
|
546
549
|
throw error
|
547
550
|
}
|
548
551
|
|
549
|
-
let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, allowDelta: true })
|
552
|
+
let { data, /* generators, semantics, */ hierarchy } = setupProcessB({ config, initializer, allowDelta: true })
|
550
553
|
if (commandLineArgs && commandLineArgs.checkForLoop) {
|
551
554
|
data.checkForLoop = true
|
552
555
|
}
|
@@ -1057,7 +1060,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1057
1060
|
finish()
|
1058
1061
|
return
|
1059
1062
|
}
|
1060
|
-
const { property, hierarchy, query: queryOrExtraConfig, skipSemantics } = queries.shift()
|
1063
|
+
const { property, hierarchy, query: queryOrExtraConfig, initializer, skipSemantics } = queries.shift()
|
1061
1064
|
// queries are strings or { query: "blah", development: true/false }
|
1062
1065
|
if (typeof queryOrExtraConfig === 'string' || queryOrExtraConfig.query) {
|
1063
1066
|
let query = queryOrExtraConfig;
|
@@ -1082,7 +1085,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1082
1085
|
}
|
1083
1086
|
|
1084
1087
|
try {
|
1085
|
-
const results = await _process(config, query.query, {})
|
1088
|
+
const results = await _process(config, query.query, {initializer})
|
1086
1089
|
if (config.config.debug) {
|
1087
1090
|
// TODO pass in the error handler like the other ones
|
1088
1091
|
defaultInnerProcess(config, defaultErrorHandler, results)
|
@@ -1143,7 +1146,7 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1143
1146
|
return template
|
1144
1147
|
};
|
1145
1148
|
stabilizeOutput(accumulators)
|
1146
|
-
runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ queries: template.queries }, accumulators), 0, 2))
|
1149
|
+
runtime.fs.writeFileSync(instanceName, JSON.stringify(Object.assign({ queries: template.queries.map(updateQueries) }, accumulators), 0, 2))
|
1147
1150
|
|
1148
1151
|
// km tests file
|
1149
1152
|
const testsName = `./${target}.test.json`
|
@@ -1160,7 +1163,9 @@ const build = async ({ config, target, template, errorHandler = defaultErrorHand
|
|
1160
1163
|
return queryStringOrProperties
|
1161
1164
|
}
|
1162
1165
|
}
|
1163
|
-
let todo =
|
1166
|
+
let todo = []
|
1167
|
+
todo = todo.concat((template.initializers || []).map((query) => { return { initializer: true, property: 'resultss', query, skipSemantics: false } }))
|
1168
|
+
todo = todo.concat((template.queries || []).map((query) => { return { property: 'resultss', query, skipSemantics: false } }))
|
1164
1169
|
todo = todo.concat((template.fragments || []).map((query) => { return Object.assign({}, toProperties(query), { property: 'fragments', skipSemantics: false }) }))
|
1165
1170
|
todo = todo.concat((template.semantics || []).map((definition) => { return { property: 'semantics', query: `${definition.from}\n${definition.to}`, skipSemantics: true } }))
|
1166
1171
|
await looper(Object.assign([], todo))
|
@@ -1265,7 +1270,6 @@ const knowledgeModule = async ({
|
|
1265
1270
|
config.load(template.template, template.instance)
|
1266
1271
|
}
|
1267
1272
|
}
|
1268
|
-
|
1269
1273
|
if (isProcess) {
|
1270
1274
|
// setup();
|
1271
1275
|
const parser = new runtime.ArgumentParser({
|
@@ -1295,10 +1299,12 @@ const knowledgeModule = async ({
|
|
1295
1299
|
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' })
|
1296
1300
|
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.' })
|
1297
1301
|
parser.add_argument('-sd', '--saveDeveloper', { action: 'store_true', help: 'Same as -s but the query will not show up in the info command.' })
|
1302
|
+
parser.add_argument('-dic', '--debugIncludeConvolutions', { action: 'store_true', help: 'When running with the --debugIncludeConvolutions flag the logs will include convolutions which are somewhat annoying verbose. Default is false' })
|
1298
1303
|
parser.add_argument('-d', '--debug', { action: 'store_true', help: 'When running with the --debug flag this set the debug flag in the config' })
|
1299
1304
|
parser.add_argument('-da', '--debugAssociation', { help: 'When running with the --debugAssociation flag the debugging will break when the specified association is added to the config' })
|
1300
1305
|
parser.add_argument('-dh', '--debugHierarchy', { help: 'When running with the --debugHierarchy flag the debugging will break when the specified child-parent pair is added to the config for the main config. Set DEBUG_HIERARCHY to debug any config loaded. For example DEBUG_HIERARCHY=\'["cat", "mammel"]\'' })
|
1301
1306
|
parser.add_argument('-db', '--debugBridge', { help: 'When running with the --debugBridge flag the debugging will break when the specified bridge is added to the config for the main config. Set DEBUG_BRIDGE to debug any config loaded. For example DEBUG_BRIDGE=\'id/level\'' })
|
1307
|
+
parser.add_argument('-do', '--debugOperator', { help: 'When running with the --debugOperator flag the debugging will break when the specified operator is added to the config for the main config. Set DEBUG_OPERATOR to debug any config loaded. For example DEBUG_OPERATOR=\'([operator] ([arg]))\'' })
|
1302
1308
|
|
1303
1309
|
const args = parser.parse_args()
|
1304
1310
|
args.count = args.count || 1
|
@@ -1316,6 +1322,10 @@ const knowledgeModule = async ({
|
|
1316
1322
|
console.log('Expected DEBUG_BRIDGE to be of the form "id/level"');
|
1317
1323
|
}
|
1318
1324
|
}
|
1325
|
+
if (args.debugOperator) {
|
1326
|
+
// id/level
|
1327
|
+
global.entodictonDebugOperator = args.debugOperator
|
1328
|
+
}
|
1319
1329
|
|
1320
1330
|
if (args.clean) {
|
1321
1331
|
const tests = JSON.parse(runtime.fs.readFileSync(testConfig.name))
|
@@ -1353,6 +1363,7 @@ const knowledgeModule = async ({
|
|
1353
1363
|
if (args.debug) {
|
1354
1364
|
config.config.debug = true
|
1355
1365
|
}
|
1366
|
+
config.config.debugIncludeConvolutions = args.debugIncludeConvolutions
|
1356
1367
|
|
1357
1368
|
if (template) {
|
1358
1369
|
const needsRebuild = config.needsRebuild(template.template, template.instance, options)
|
@@ -1450,6 +1461,9 @@ const knowledgeModule = async ({
|
|
1450
1461
|
for (const semantic of easyToRead) {
|
1451
1462
|
semantic.match = semantic.match.toString()
|
1452
1463
|
semantic.apply = semantic.apply.toString()
|
1464
|
+
if (semantic.applyWrapped) {
|
1465
|
+
semantic.applyWrapped = semantic.applyWrapped.toString()
|
1466
|
+
}
|
1453
1467
|
}
|
1454
1468
|
console.dir(easyToRead)
|
1455
1469
|
}
|
@@ -1656,7 +1670,14 @@ function where(goUp = 2) {
|
|
1656
1670
|
const e = new Error();
|
1657
1671
|
const regexForm1 = /\((.*):(\d+):(\d+)\)$/
|
1658
1672
|
const regexForm2 = /at (.*):(\d+):(\d+)$/
|
1659
|
-
const
|
1673
|
+
const lines = e.stack.split("\n")
|
1674
|
+
let line
|
1675
|
+
for (line of lines.slice(1)) {
|
1676
|
+
if (!(line.includes("config.js:") || line.includes("client.js:"))) {
|
1677
|
+
break;
|
1678
|
+
}
|
1679
|
+
}
|
1680
|
+
// const line = e.stack.split("\n")[goUp];
|
1660
1681
|
const match = regexForm1.exec(line) || regexForm2.exec(line);
|
1661
1682
|
if (match) {
|
1662
1683
|
return `${match[1]}:${match[2]}`
|
package/package.json
CHANGED
@@ -10,12 +10,13 @@
|
|
10
10
|
"eslint": "^7.31.0"
|
11
11
|
},
|
12
12
|
"scripts": {
|
13
|
-
"to:debug": "node inspect node_modules/.bin/jest --runInBand -t
|
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
|
-
"tod": "node inspect node_modules/.bin/jest --runInBand -t
|
15
|
+
"tod": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
|
16
16
|
"lint:fix": "eslint \"**/*.js\" --fix",
|
17
17
|
"lint": "eslint \"**/*.js\"",
|
18
|
-
"to": "node node_modules/.bin/jest --runInBand -t
|
18
|
+
"to": "node node_modules/.bin/jest --runInBand -t NEO23",
|
19
|
+
"tos": "node node_modules/.bin/jest --runInBand -t NEOS23",
|
19
20
|
"test": "jest --config ./jest.config.json",
|
20
21
|
"test:watch": "npm run test -- --watch"
|
21
22
|
},
|
@@ -61,6 +62,6 @@
|
|
61
62
|
"json-stable-stringify": "^1.0.1",
|
62
63
|
"node-fetch": "^2.6.1"
|
63
64
|
},
|
64
|
-
"version": "7.5.
|
65
|
+
"version": "7.5.5",
|
65
66
|
"license": "ISC"
|
66
67
|
}
|
package/src/config.js
CHANGED
@@ -5,7 +5,6 @@ const { Generators } = require('./generators')
|
|
5
5
|
const client = require('../client')
|
6
6
|
const Digraph = require('./digraph')
|
7
7
|
const helpers = require('./helpers')
|
8
|
-
const deepEqual = require('deep-equal')
|
9
8
|
const runtime = require('../runtime')
|
10
9
|
const _ = require('lodash')
|
11
10
|
|
@@ -22,6 +21,118 @@ const indent = (string, indent) => {
|
|
22
21
|
return string.replace(/^/gm, ' '.repeat(indent));
|
23
22
|
}
|
24
23
|
|
24
|
+
const handleBridgeProps = (config, bridge) => {
|
25
|
+
if (!bridge.bridge) {
|
26
|
+
bridge.bridge = "{ ...next(operator) }"
|
27
|
+
}
|
28
|
+
if (!bridge.level) {
|
29
|
+
bridge.level = 0
|
30
|
+
}
|
31
|
+
if (bridge.children) {
|
32
|
+
for (let child of bridge.children) {
|
33
|
+
config.addHierarchy(child, bridge.id)
|
34
|
+
}
|
35
|
+
}
|
36
|
+
if (bridge.parents) {
|
37
|
+
for (let parent of bridge.parents) {
|
38
|
+
config.addHierarchy(bridge.id, parent)
|
39
|
+
}
|
40
|
+
}
|
41
|
+
if (bridge.isA) {
|
42
|
+
for (let parent of bridge.isA) {
|
43
|
+
config.addHierarchy(bridge.id, parent)
|
44
|
+
}
|
45
|
+
}
|
46
|
+
if (bridge.before) {
|
47
|
+
for (let after of bridge.before) {
|
48
|
+
if (typeof after == 'string') {
|
49
|
+
after = [after, 0]
|
50
|
+
}
|
51
|
+
config.addPriorities([after, [bridge.id, bridge.level]])
|
52
|
+
}
|
53
|
+
}
|
54
|
+
if (bridge.words) {
|
55
|
+
for (let def of bridge.words) {
|
56
|
+
if (typeof def == 'string') {
|
57
|
+
config.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
|
58
|
+
} else {
|
59
|
+
const word = def.word
|
60
|
+
def = { initial: JSON.stringify(def), id: bridge.id, word: undefined }
|
61
|
+
config.addWordInternal(word, def)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
if (bridge.generator) {
|
66
|
+
config.config.generators.unshift(bridge.generator)
|
67
|
+
}
|
68
|
+
if (bridge.generators) {
|
69
|
+
const generators = [...bridge.generators]
|
70
|
+
generators.reverse()
|
71
|
+
for (let generator of generators) {
|
72
|
+
config.config.generators.unshift(generator)
|
73
|
+
}
|
74
|
+
}
|
75
|
+
if (bridge.generatorpr) {
|
76
|
+
bridge.generatorp = bridge.generatorpr
|
77
|
+
bridge.generatorr = bridge.generatorpr
|
78
|
+
}
|
79
|
+
if (bridge.generatorp) {
|
80
|
+
config.config.generators.unshift({
|
81
|
+
where: bridge.generatorp.where || bridge.where || client.where(4),
|
82
|
+
match: ({context}) => bridge.id == context.marker && context.paraphrase,
|
83
|
+
apply: (args) => bridge.generatorp(args),
|
84
|
+
applyWrapped: bridge.generatorp,
|
85
|
+
property: 'generatorp',
|
86
|
+
})
|
87
|
+
}
|
88
|
+
if (bridge.generatorr) {
|
89
|
+
config.config.generators.unshift({
|
90
|
+
// TODO merge response and isResponse
|
91
|
+
where: bridge.generatorr.where || bridge.where || client.where(3),
|
92
|
+
match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
|
93
|
+
apply: (args) => bridge.generatorr(args),
|
94
|
+
applyWrapped: bridge.generatorr,
|
95
|
+
property: 'generatorr',
|
96
|
+
})
|
97
|
+
}
|
98
|
+
if (bridge.evaluator) {
|
99
|
+
config.config.semantics.unshift({
|
100
|
+
where: bridge.evaluator.where || bridge.where || client.where(3),
|
101
|
+
match: ({context}) => bridge.id == context.marker && context.evaluate,
|
102
|
+
apply: (args) => bridge.evaluator(args),
|
103
|
+
applyWrapped: bridge.evaluator,
|
104
|
+
property: 'evaluator',
|
105
|
+
})
|
106
|
+
}
|
107
|
+
if (bridge.semantic) {
|
108
|
+
config.config.semantics.unshift({
|
109
|
+
where: bridge.semantic.where || bridge.where || client.where(3),
|
110
|
+
match: ({context}) => bridge.id == context.marker,
|
111
|
+
apply: (args) => bridge.semantic(args),
|
112
|
+
applyWrapped: bridge.semantic,
|
113
|
+
property: 'semantic',
|
114
|
+
})
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
const handleCalculatedProps = (baseConfig, moreConfig) => {
|
119
|
+
for (let bridge of moreConfig.bridges) {
|
120
|
+
const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
|
121
|
+
'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where' ]
|
122
|
+
helpers.validProps(valid, bridge, 'bridge')
|
123
|
+
handleBridgeProps(baseConfig, bridge)
|
124
|
+
}
|
125
|
+
if (moreConfig.operators) {
|
126
|
+
moreConfig.operators = moreConfig.operators.map((operator) => {
|
127
|
+
if (typeof operator === 'string') {
|
128
|
+
return { pattern: operator }
|
129
|
+
} else {
|
130
|
+
return operator
|
131
|
+
}
|
132
|
+
})
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
25
136
|
if (runtime.process.env.DEBUG_HIERARCHY) {
|
26
137
|
global.entodictonDebugHierarchy = JSON.parse(runtime.process.env.DEBUG_HIERARCHY)
|
27
138
|
}
|
@@ -35,6 +146,11 @@ if (runtime.process.env.DEBUG_BRIDGE) {
|
|
35
146
|
global.entodictonDebugBridge[1] = int(global.entodictonDebugBridge[1])
|
36
147
|
}
|
37
148
|
|
149
|
+
if (runtime.process.env.DEBUG_OPERATOR) {
|
150
|
+
// id/level
|
151
|
+
global.entodictonDebugOperator = runtime.process.env.DEBUG_OPERATOR
|
152
|
+
}
|
153
|
+
|
38
154
|
const hierarchyCanonical = (element) => {
|
39
155
|
if (element.child && element.parent) {
|
40
156
|
return element
|
@@ -86,6 +202,17 @@ const normalizeConfig = (config) => {
|
|
86
202
|
config[bag][i].km = config.name
|
87
203
|
}
|
88
204
|
}
|
205
|
+
|
206
|
+
}
|
207
|
+
if (config['bridges']) {
|
208
|
+
for (let bridge of config['bridges']) {
|
209
|
+
if (!bridge.level) {
|
210
|
+
bridge.level = 0
|
211
|
+
}
|
212
|
+
if (!bridge.bridge) {
|
213
|
+
bridge.bridge = "{ ...next(operator) }"
|
214
|
+
}
|
215
|
+
}
|
89
216
|
}
|
90
217
|
}
|
91
218
|
}
|
@@ -324,6 +451,37 @@ const multiApiImpl = (initializer) => {
|
|
324
451
|
|
325
452
|
class Config {
|
326
453
|
|
454
|
+
inDevelopmentMode (call) {
|
455
|
+
config.developmentModeOn += 1
|
456
|
+
try {
|
457
|
+
call()
|
458
|
+
} finally {
|
459
|
+
config.developmentModeOn -= 1
|
460
|
+
}
|
461
|
+
}
|
462
|
+
|
463
|
+
// return the config with just the elements from the included KM's
|
464
|
+
baseConfig() {
|
465
|
+
const operators = this.config.operators.filter((operator) => {
|
466
|
+
return operator.uuid !== this.uuid
|
467
|
+
})
|
468
|
+
const bridges = this.config.bridges.filter((bridge) => {
|
469
|
+
return bridge.uuid !== this.uuid
|
470
|
+
})
|
471
|
+
const words = {}
|
472
|
+
for (let word in this.config.words) {
|
473
|
+
const defs = this.config.words[word].filter( (def) => def.uuid !== this.uuid )
|
474
|
+
if (defs.length > 0) {
|
475
|
+
words[word] = defs
|
476
|
+
}
|
477
|
+
}
|
478
|
+
return {
|
479
|
+
operators,
|
480
|
+
bridges,
|
481
|
+
words
|
482
|
+
}
|
483
|
+
}
|
484
|
+
|
327
485
|
getCounter (maybeName = '') {
|
328
486
|
const counter = this.configCounter
|
329
487
|
this.configCounter += 1
|
@@ -525,12 +683,26 @@ class Config {
|
|
525
683
|
}
|
526
684
|
const instanceFragments = (instance.fragments || []).map((fragment) => fragment.key || fragment.query).map( toCanonical )
|
527
685
|
const templateFragments = (template.fragments || []).concat(this.dynamicFragments).map( toCanonical )
|
528
|
-
const sameFragments =
|
529
|
-
const sameQueries =
|
686
|
+
const sameFragments = helpers.safeEquals(templateFragments, instanceFragments)
|
687
|
+
const sameQueries = helpers.safeEquals((template.queries || []).map(helpers.updateQueries), (instance.queries || []))
|
530
688
|
return !(instance && sameQueries && sameFragments)
|
531
689
|
}
|
532
690
|
|
691
|
+
validifyTemplate (template) {
|
692
|
+
if (!template.queries && !template.fragments) {
|
693
|
+
throw new Error(`Expected the template for ${this.name} to be an object that can have the properties: queries and fragments`)
|
694
|
+
}
|
695
|
+
for (let query of template.queries || []) {
|
696
|
+
if (typeof query == 'string') {
|
697
|
+
} else if (query instanceof Config) {
|
698
|
+
throw new Error(`For the template for ${this.name}, each element in queries should be either a string or a structure with a config (not a Config object).`)
|
699
|
+
}
|
700
|
+
}
|
701
|
+
}
|
702
|
+
|
533
703
|
load (template, instance, options = { rebuild: false } ) {
|
704
|
+
this.validifyTemplate(template)
|
705
|
+
instance.template = template
|
534
706
|
this.logs.push(`loading template for ${this.name}`)
|
535
707
|
if (instance && instance.associations && !options.rebuild) {
|
536
708
|
this.addAssociations(instance.associations)
|
@@ -592,7 +764,7 @@ class Config {
|
|
592
764
|
}
|
593
765
|
}
|
594
766
|
if (global.entodictonDebugAssociation) {
|
595
|
-
if (
|
767
|
+
if (helpers.safeEquals(global.entodictonDebugAssociation, association)) {
|
596
768
|
debugger; // debug association hit
|
597
769
|
}
|
598
770
|
}
|
@@ -627,7 +799,7 @@ class Config {
|
|
627
799
|
throw `addHierarchy expected parent property to be a string. got ${JSON.stringify(parent)}`
|
628
800
|
}
|
629
801
|
if (global.entodictonDebugHierarchy) {
|
630
|
-
if (
|
802
|
+
if ((helpers.safeEquals.entodictonDebugHierarchy, [child, parent])) {
|
631
803
|
debugger; // debug hierarchy hit
|
632
804
|
}
|
633
805
|
}
|
@@ -645,7 +817,7 @@ class Config {
|
|
645
817
|
}
|
646
818
|
|
647
819
|
if (global.entodictonDebugHierarchy) {
|
648
|
-
if (
|
820
|
+
if (helpers.safeEquals(global.entodictonDebugHierarchy, [child, parent])) {
|
649
821
|
debugger; // debug hierarchy hit
|
650
822
|
}
|
651
823
|
}
|
@@ -689,6 +861,7 @@ class Config {
|
|
689
861
|
if (global.transitoryMode) {
|
690
862
|
def.transitoryMode = true
|
691
863
|
}
|
864
|
+
handleBridgeProps(this, def)
|
692
865
|
bridges.push(def)
|
693
866
|
this.checkBridges();
|
694
867
|
this._delta.json.bridges.push({ action: 'add', bridge: def })
|
@@ -751,6 +924,7 @@ class Config {
|
|
751
924
|
if (!this.config.operators) {
|
752
925
|
this.config.operators = []
|
753
926
|
}
|
927
|
+
|
754
928
|
const operators = this.config.operators
|
755
929
|
|
756
930
|
let operator;
|
@@ -760,6 +934,12 @@ class Config {
|
|
760
934
|
operator = Object.assign({}, objectOrPattern, { uuid: this._uuid })
|
761
935
|
}
|
762
936
|
|
937
|
+
if (global.entodictonDebugOperator) {
|
938
|
+
if (operator.pattern === global.entodictonDebugOperator) {
|
939
|
+
debugger; // debug operator hit
|
940
|
+
}
|
941
|
+
}
|
942
|
+
|
763
943
|
if (operator.allowDups) {
|
764
944
|
if (operators.find( (o) => o.pattern == operator.pattern )) {
|
765
945
|
return;
|
@@ -1018,7 +1198,8 @@ class Config {
|
|
1018
1198
|
'debug',
|
1019
1199
|
|
1020
1200
|
// TODO Fix these from the test app
|
1021
|
-
'
|
1201
|
+
'implicits',
|
1202
|
+
'convolution',
|
1022
1203
|
'expected_generated',
|
1023
1204
|
'expected_results',
|
1024
1205
|
'skipSemantics',
|
@@ -1114,115 +1295,12 @@ class Config {
|
|
1114
1295
|
if (config) {
|
1115
1296
|
config = _.cloneDeep(config)
|
1116
1297
|
this.config = config
|
1117
|
-
|
1118
|
-
const valid = [ 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generators', 'id', 'implicit', 'inverted', 'isA', 'children', 'parents',
|
1119
|
-
'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy' ]
|
1120
|
-
helpers.validProps(valid, bridge, 'bridge')
|
1121
|
-
/*
|
1122
|
-
if (bridge.generator) {
|
1123
|
-
this.config.generators.push({
|
1124
|
-
match: ({context}) => bridge.id == context.marker,
|
1125
|
-
apply: (args) => bridge.generator(args),
|
1126
|
-
})
|
1127
|
-
}
|
1128
|
-
*/
|
1129
|
-
if (bridge.children) {
|
1130
|
-
for (let child of bridge.children) {
|
1131
|
-
this.addHierarchy(child, bridge.id)
|
1132
|
-
}
|
1133
|
-
}
|
1134
|
-
if (bridge.parents) {
|
1135
|
-
for (let parent of bridge.parents) {
|
1136
|
-
this.addHierarchy(bridge.id, parent)
|
1137
|
-
}
|
1138
|
-
}
|
1139
|
-
if (bridge.isA) {
|
1140
|
-
for (let parent of bridge.isA) {
|
1141
|
-
this.addHierarchy(bridge.id, parent)
|
1142
|
-
}
|
1143
|
-
}
|
1144
|
-
if (bridge.before) {
|
1145
|
-
for (let after of bridge.before) {
|
1146
|
-
if (typeof after == 'string') {
|
1147
|
-
after = [after, 0]
|
1148
|
-
}
|
1149
|
-
this.addPriorities([after, [bridge.id, bridge.level]])
|
1150
|
-
}
|
1151
|
-
}
|
1152
|
-
if (bridge.words) {
|
1153
|
-
for (let def of bridge.words) {
|
1154
|
-
if (typeof def == 'string') {
|
1155
|
-
this.addWordInternal(def, {"id": bridge.id, "initial": `{ value: "${def}"}` })
|
1156
|
-
} else {
|
1157
|
-
const word = def.word
|
1158
|
-
def = { initial: JSON.stringify(def), id: bridge.id, word: undefined }
|
1159
|
-
this.addWordInternal(word, def)
|
1160
|
-
}
|
1161
|
-
}
|
1162
|
-
}
|
1163
|
-
if (bridge.generator) {
|
1164
|
-
this.config.generators.unshift(bridge.generator)
|
1165
|
-
}
|
1166
|
-
if (bridge.generators) {
|
1167
|
-
const generators = [...bridge.generators]
|
1168
|
-
generators.reverse()
|
1169
|
-
for (let generator of generators) {
|
1170
|
-
this.config.generators.unshift(generator)
|
1171
|
-
}
|
1172
|
-
}
|
1173
|
-
if (bridge.generatorp) {
|
1174
|
-
this.config.generators.unshift({
|
1175
|
-
where: bridge.generatorp.where || client.where(3),
|
1176
|
-
match: ({context}) => bridge.id == context.marker && context.paraphrase,
|
1177
|
-
apply: (args) => bridge.generatorp(args),
|
1178
|
-
})
|
1179
|
-
}
|
1180
|
-
if (bridge.generatorr) {
|
1181
|
-
this.config.generators.unshift({
|
1182
|
-
// TODO merge response and isResponse
|
1183
|
-
where: bridge.generatorr.where || client.where(3),
|
1184
|
-
match: ({context}) => bridge.id == context.marker && !context.paraphrase && (context.response || context.isResponse),
|
1185
|
-
apply: (args) => bridge.generatorr(args),
|
1186
|
-
})
|
1187
|
-
}
|
1188
|
-
if (bridge.evaluator) {
|
1189
|
-
this.config.semantics.unshift({
|
1190
|
-
where: bridge.evaluator.where || client.where(3),
|
1191
|
-
match: ({context}) => bridge.id == context.marker && context.evaluate,
|
1192
|
-
apply: (args) => bridge.evaluator(args),
|
1193
|
-
})
|
1194
|
-
}
|
1195
|
-
if (bridge.semantic) {
|
1196
|
-
this.config.semantics.unshift({
|
1197
|
-
where: bridge.semantic.where || client.where(3),
|
1198
|
-
match: ({context}) => bridge.id == context.marker,
|
1199
|
-
apply: (args) => bridge.semantic(args),
|
1200
|
-
})
|
1201
|
-
}
|
1202
|
-
}
|
1203
|
-
if (config.operators) {
|
1204
|
-
config.operators = config.operators.map((operator) => {
|
1205
|
-
if (typeof operator === 'string') {
|
1206
|
-
return { pattern: operator }
|
1207
|
-
} else {
|
1208
|
-
return operator
|
1209
|
-
}
|
1210
|
-
})
|
1211
|
-
}
|
1298
|
+
handleCalculatedProps(this, config)
|
1212
1299
|
}
|
1213
1300
|
this.hierarchy = new Digraph(this.config.hierarchy)
|
1214
1301
|
this.initConfig = _.cloneDeep(this.config)
|
1215
1302
|
this.configs.push(new KM({ config: this.config, getCounter: (name) => this.config.getCounter(name), uuid: this._uuid }))
|
1216
1303
|
|
1217
|
-
/*
|
1218
|
-
if (config) {
|
1219
|
-
this.configs.push(new KM({config, isSelf: true}))
|
1220
|
-
this.addInternal(Object.assign({}, config), false)
|
1221
|
-
} else {
|
1222
|
-
this.configs.push( new KM({config: this.config, isSelf: true}) )
|
1223
|
-
}
|
1224
|
-
*/
|
1225
|
-
|
1226
1304
|
this.setUUIDs()
|
1227
1305
|
this.initDefaults()
|
1228
1306
|
if (!this.config.objects.namespaced) {
|
@@ -1311,6 +1389,7 @@ class Config {
|
|
1311
1389
|
this._api.config = () => this
|
1312
1390
|
this._api.uuid = this._uuid
|
1313
1391
|
}
|
1392
|
+
this.rebuild()
|
1314
1393
|
}
|
1315
1394
|
}
|
1316
1395
|
|
@@ -1613,7 +1692,8 @@ class Config {
|
|
1613
1692
|
|
1614
1693
|
if (currentConfig.api) {
|
1615
1694
|
currentConfig.api.objects = args.objects
|
1616
|
-
currentConfig.api.config = () => this
|
1695
|
+
// GREG42 currentConfig.api.config = () => this
|
1696
|
+
currentConfig.api.config = () => args.baseConfig
|
1617
1697
|
currentConfig.api.uuid = currentConfig._uuid
|
1618
1698
|
}
|
1619
1699
|
// this.instances.forEach( (instance) => client.processInstance(this, instance) )
|
@@ -1877,7 +1957,6 @@ class Config {
|
|
1877
1957
|
} else {
|
1878
1958
|
addInternals.unshift(config)
|
1879
1959
|
}
|
1880
|
-
// this.addInternal(config, true, false, false, true)
|
1881
1960
|
} else {
|
1882
1961
|
if (interleaved) {
|
1883
1962
|
addInternals.unshift(null)
|
@@ -1886,10 +1965,6 @@ class Config {
|
|
1886
1965
|
km.valid()
|
1887
1966
|
})
|
1888
1967
|
|
1889
|
-
if (addInternals.length !== inits.length || addInternals.length !== initAfterApis.length) {
|
1890
|
-
debugger // bug
|
1891
|
-
}
|
1892
|
-
|
1893
1968
|
const generators = this.config.generators
|
1894
1969
|
const semantics = this.config.semantics
|
1895
1970
|
if (reverseIt) {
|
@@ -1900,7 +1975,7 @@ class Config {
|
|
1900
1975
|
if (!interleaved) {
|
1901
1976
|
for (const config of addInternals) {
|
1902
1977
|
if (!reverseIt) {
|
1903
|
-
this.addInternal(config,
|
1978
|
+
this.addInternal(config, { includeNamespace: false, allowNameToBeNull: true })
|
1904
1979
|
} else {
|
1905
1980
|
this.addInternalR(config, true, false, false, true)
|
1906
1981
|
}
|
@@ -2052,7 +2127,7 @@ class Config {
|
|
2052
2127
|
|
2053
2128
|
this.applyNamespace(configPrime, km.namespace, km.uuid)
|
2054
2129
|
first = false
|
2055
|
-
this.addInternal(configPrime, false, true)
|
2130
|
+
this.addInternal(configPrime, { useOldVersion: false, skipObjects: true })
|
2056
2131
|
applyUUID(configPrime, km.uuid)
|
2057
2132
|
})
|
2058
2133
|
|
@@ -2342,7 +2417,7 @@ class Config {
|
|
2342
2417
|
}
|
2343
2418
|
|
2344
2419
|
// TODO get rid of useOldVersion arg
|
2345
|
-
addInternal (more, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false) {
|
2420
|
+
addInternal (more, { useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false, handleCalculatedProps : hcps = false } = {}) {
|
2346
2421
|
if (more instanceof Config) {
|
2347
2422
|
more.initialize({ force: false })
|
2348
2423
|
if (useOldVersion) {
|
@@ -2352,6 +2427,10 @@ class Config {
|
|
2352
2427
|
more = _.cloneDeep(more.initConfig)
|
2353
2428
|
}
|
2354
2429
|
}
|
2430
|
+
if (hcps) {
|
2431
|
+
handleCalculatedProps(this, more)
|
2432
|
+
applyUUID(more, this._uuid)
|
2433
|
+
}
|
2355
2434
|
for (const key of Object.keys(more)) {
|
2356
2435
|
const value = more[key]
|
2357
2436
|
// TODO remove name and description on the config bag
|
@@ -2533,7 +2612,6 @@ class Config {
|
|
2533
2612
|
if (isDup(newOne, oldOne)) {
|
2534
2613
|
if (oldOne.allowDups) {
|
2535
2614
|
// the old one takes precedence to match what would happen during the original load
|
2536
|
-
debugger
|
2537
2615
|
this.config[key].splice(iOldOne, 1)
|
2538
2616
|
break;
|
2539
2617
|
}
|
@@ -2560,9 +2638,6 @@ class Config {
|
|
2560
2638
|
// console.log('key', key, 'XXX')
|
2561
2639
|
// console.log('more', JSON.stringify(more, null, 2))
|
2562
2640
|
// this.config[key] = this.config[key].concat(more[key])
|
2563
|
-
if (key == '2enerators') {
|
2564
|
-
debugger
|
2565
|
-
}
|
2566
2641
|
// this.config[key] = this.config[key].concat(more[key])
|
2567
2642
|
this.config[key] = more[key].concat(this.config[key])
|
2568
2643
|
} else {
|
package/src/generators.js
CHANGED
@@ -6,9 +6,11 @@ class Generator {
|
|
6
6
|
// constructor ({ match, apply, uuid, index, km, priority, notes }) {
|
7
7
|
constructor (generator) {
|
8
8
|
generator = normalizeGenerator(generator)
|
9
|
-
const { match, apply, uuid, index, km, priority, where, notes, debug } = generator
|
9
|
+
const { match, apply, uuid, index, km, priority, where, notes, debug, applyWrapped, property } = generator
|
10
10
|
this.match = match
|
11
11
|
this._apply = apply
|
12
|
+
this._applyWrapped = applyWrapped
|
13
|
+
this.property = property
|
12
14
|
this.uuid = uuid
|
13
15
|
this.index = index
|
14
16
|
this.km = km
|
@@ -39,7 +41,7 @@ class Generator {
|
|
39
41
|
}
|
40
42
|
|
41
43
|
toString () {
|
42
|
-
return `Generator(${this.match}, ${this._apply})`
|
44
|
+
return `Generator(${this.match}, ${this._applyWrapped || this._apply})${this.property ? `\nsee the ${this.property} property` : ''}`
|
43
45
|
}
|
44
46
|
|
45
47
|
matches (baseArgs, objects, context, hierarchy, config, options = {}) {
|
@@ -198,9 +200,11 @@ class Generators {
|
|
198
200
|
e.retryCall = () => generator.apply(args, objects, g, args.gs, context, hierarchy, config, response, log)
|
199
201
|
const help = 'The error has a retryCall property that will recall the function that failed.'
|
200
202
|
if (e.stack && e.message) {
|
201
|
-
|
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}`
|
202
205
|
} else if (e.error) {
|
203
|
-
|
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}`
|
204
208
|
} else {
|
205
209
|
errorMessage = e.toString()
|
206
210
|
}
|
package/src/helpers.js
CHANGED
@@ -44,10 +44,23 @@ const appendNoDups = (l1, l2) => {
|
|
44
44
|
}
|
45
45
|
|
46
46
|
const safeEquals = (v1, v2) => {
|
47
|
-
if (
|
47
|
+
if (typeof v1 !== typeof v2) {
|
48
48
|
return false
|
49
49
|
}
|
50
|
-
|
50
|
+
|
51
|
+
const type = typeof v1
|
52
|
+
if (type == 'number' || type == 'string') {
|
53
|
+
return v1 == v2
|
54
|
+
} else if (type == 'function') {
|
55
|
+
return v1.toString() == v2.toString()
|
56
|
+
} else {
|
57
|
+
for (let key in v1) {
|
58
|
+
if (!safeEquals(v1[key], v2[key])) {
|
59
|
+
return false
|
60
|
+
}
|
61
|
+
}
|
62
|
+
return true
|
63
|
+
}
|
51
64
|
}
|
52
65
|
|
53
66
|
/*
|
@@ -238,7 +251,66 @@ const mapInPlace = (list, fn) => {
|
|
238
251
|
}
|
239
252
|
}
|
240
253
|
|
254
|
+
const updateQueries = (queryOrConfig) => {
|
255
|
+
if (typeof queryOrConfig == 'string' || queryOrConfig.query) {
|
256
|
+
return queryOrConfig
|
257
|
+
} else {
|
258
|
+
const config = queryOrConfig
|
259
|
+
return functionsToStrings(config)
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
const functionsToStrings = (config) => {
|
264
|
+
config = {...config}
|
265
|
+
const mapGenerator = (generator) => {
|
266
|
+
if (generator.apply) {
|
267
|
+
return { ...generator, match: generator.match.toString(), apply: generator.apply.toString() }
|
268
|
+
} else {
|
269
|
+
return [ generator[0].toString(), generator[1].toString() ]
|
270
|
+
}
|
271
|
+
}
|
272
|
+
if (config.generators) {
|
273
|
+
config.generators = config.generators.map( mapGenerator )
|
274
|
+
}
|
275
|
+
if (config.semantics) {
|
276
|
+
config.semantics = config.semantics.map( (semantic) => {
|
277
|
+
if (semantic.apply) {
|
278
|
+
return { ...semantic, match: semantic.match.toString(), apply: semantic.apply.toString() }
|
279
|
+
} else {
|
280
|
+
return [ semantic[0].toString(), semantic[1].toString() ]
|
281
|
+
}
|
282
|
+
})
|
283
|
+
}
|
284
|
+
if (config.bridges) {
|
285
|
+
config.bridges = config.bridges.map( (bridge) => {
|
286
|
+
bridge = {...bridge}
|
287
|
+
if (bridge.generator) {
|
288
|
+
bridge.generator = bridge.generator.toString()
|
289
|
+
}
|
290
|
+
if (bridge.generators) {
|
291
|
+
bridge.generators = bridge.generators.map( mapGenerator )
|
292
|
+
}
|
293
|
+
if (bridge.generatorp) {
|
294
|
+
bridge.generatorp = bridge.generatorp.toString()
|
295
|
+
}
|
296
|
+
if (bridge.generatorr) {
|
297
|
+
bridge.generatorr = bridge.generatorr.toString()
|
298
|
+
}
|
299
|
+
if (bridge.semantic) {
|
300
|
+
bridge.semantic = bridge.semantic.toString()
|
301
|
+
}
|
302
|
+
if (bridge.evaluator) {
|
303
|
+
bridge.evaluator = bridge.evaluator.toString()
|
304
|
+
}
|
305
|
+
return bridge
|
306
|
+
})
|
307
|
+
}
|
308
|
+
return config
|
309
|
+
}
|
310
|
+
|
241
311
|
module.exports = {
|
312
|
+
functionsToStrings,
|
313
|
+
updateQueries,
|
242
314
|
mapInPlace,
|
243
315
|
validProps,
|
244
316
|
args,
|
package/src/semantics.js
CHANGED
@@ -6,9 +6,11 @@ class Semantic {
|
|
6
6
|
// constructor ({match, apply, uuid, index, km, notes}) {
|
7
7
|
constructor (semantic) {
|
8
8
|
semantic = normalizeSemantic(semantic)
|
9
|
-
const { match, apply, uuid, index, km, notes, priority, debug, where } = semantic
|
9
|
+
const { match, apply, uuid, index, km, notes, priority, debug, where, applyWrapped, property } = semantic
|
10
10
|
this.matcher = match
|
11
11
|
this._apply = apply
|
12
|
+
this._applyWrapped = applyWrapped
|
13
|
+
this.property = property
|
12
14
|
this.uuid = uuid
|
13
15
|
this.index = index
|
14
16
|
this.km = km
|
@@ -27,7 +29,7 @@ class Semantic {
|
|
27
29
|
}
|
28
30
|
|
29
31
|
toString () {
|
30
|
-
return `Semantic(${this.matcher}, ${this._apply})`
|
32
|
+
return `Semantic(${this.matcher}, ${this._applyWrapped || this._apply})${this.property ? `\nsee the ${this.property} property` : ''}`
|
31
33
|
}
|
32
34
|
|
33
35
|
getAPI (config) {
|
@@ -192,9 +194,11 @@ class Semantics {
|
|
192
194
|
e.retryCall = () => semantic.apply(args, context, s, log, options)
|
193
195
|
const help = 'The error has a retryCall property that will recall the function that failed.'
|
194
196
|
if (e.stack && e.message) {
|
195
|
-
|
197
|
+
const info = `${semantic.notes ? semantic.notes : ''}${semantic.where ? semantic.where : ''}`
|
198
|
+
errorMessage = `Error applying semantics '${info}'. Error is ${e.toString()} stack is ${e.stack}. Semantic is ${semantic.toString()}. ${help}`
|
196
199
|
} else if (e.error) {
|
197
|
-
|
200
|
+
const info = `${semantic.notes ? semantic.notes : ''}${semantic.where ? semantic.where : ''}`
|
201
|
+
errorMessage = `Error applying semantics '${info}'. Error is ${e.error.join()}. Semantic is ${semantic.toString()}. ${help}`
|
198
202
|
} else {
|
199
203
|
errorMessage = e.toString();
|
200
204
|
}
|