theprogrammablemind 7.5.4 → 7.5.5
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 +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
|
}
|