theprogrammablemind_4wp 7.12.4 → 7.12.5
Sign up to get free protection for your applications and to get access to all the features.
- package/client.js +226 -108
- package/package.json +1 -1
- package/src/config.js +36 -12
- package/src/helpers.js +8 -0
- package/src/semantics.js +11 -1
package/client.js
CHANGED
@@ -10,12 +10,47 @@ const _ = require('lodash')
|
|
10
10
|
const stringify = require('json-stable-stringify')
|
11
11
|
const Lines = require('./lines')
|
12
12
|
const flattens = require('./src/flatten')
|
13
|
-
const { appendNoDups, InitCalls, updateQueries, safeNoDups } = require('./src/helpers')
|
13
|
+
const { appendNoDups, InitCalls, updateQueries, safeNoDups, stableId } = require('./src/helpers')
|
14
14
|
const runtime = require('./runtime')
|
15
15
|
const sortJson = runtime.sortJson
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
function where (goUp = 2) {
|
18
|
+
const e = new Error()
|
19
|
+
const regexForm1 = /\((.*):(\d+):(\d+)\)$/
|
20
|
+
const regexForm2 = /at (.*):(\d+):(\d+)$/
|
21
|
+
const lines = e.stack.split('\n')
|
22
|
+
let line
|
23
|
+
let match
|
24
|
+
for (line of lines.slice(1)) {
|
25
|
+
// if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
|
26
|
+
if (!(line.includes('config.js:') || line.includes('client.js:'))) {
|
27
|
+
match = regexForm1.exec(line) || regexForm2.exec(line)
|
28
|
+
if (!match) {
|
29
|
+
continue
|
30
|
+
}
|
31
|
+
break
|
32
|
+
}
|
33
|
+
}
|
34
|
+
// const line = e.stack.split("\n")[goUp];
|
35
|
+
// const match = regexForm1.exec(line) || regexForm2.exec(line)
|
36
|
+
if (match) {
|
37
|
+
return `${match[1]}:${match[2]}`
|
38
|
+
} else {
|
39
|
+
return 'running in browser'
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
const getConfig_getObjectsCheck = (config, testConfig) => {
|
44
|
+
let testConfigName = config.name
|
45
|
+
if (testConfig.testModuleName) {
|
46
|
+
testConfigName = testConfig.testModuleName
|
47
|
+
}
|
48
|
+
const checks = (testConfig.checks && testConfig.checks.objects) || []
|
49
|
+
if (Array.isArray(checks)) {
|
50
|
+
return { [testConfigName]: checks }
|
51
|
+
} else {
|
52
|
+
return checks
|
53
|
+
}
|
19
54
|
}
|
20
55
|
|
21
56
|
const getConfig_getContextCheck = (testConfig) => {
|
@@ -26,61 +61,122 @@ const pickContext = (testConfig) => (context) => {
|
|
26
61
|
return project(context, getConfig_getContextCheck(testConfig))
|
27
62
|
}
|
28
63
|
|
29
|
-
const pickObjects = (testConfig,
|
30
|
-
|
64
|
+
const pickObjects = (config, testConfig, getObjects) => {
|
65
|
+
/*
|
66
|
+
let testConfigName = config.name
|
67
|
+
if (testConfig.testModuleName) {
|
68
|
+
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
69
|
+
testConfigName = testConfig.testModuleName
|
70
|
+
}
|
71
|
+
*/
|
72
|
+
const checks = getConfig_getObjectsCheck(config, testConfig)
|
73
|
+
const projection = {}
|
74
|
+
for (let km in checks) {
|
75
|
+
const objects = getObjects(km)
|
76
|
+
if (!objects) {
|
77
|
+
throw new Error(`In the checks for ${config.name} the KM ${km} does not exist`)
|
78
|
+
}
|
79
|
+
projection[km] = project(objects, checks[km])
|
80
|
+
}
|
81
|
+
return projection
|
31
82
|
}
|
32
83
|
|
33
|
-
// move ask to the KM's since verbatim is called
|
34
|
-
const getAsk = (config) => (uuid) =>
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
84
|
+
// move ask to the KM's since verbatim is called probably in dialogues?
|
85
|
+
const getAsk = (config) => (uuid) => {
|
86
|
+
// if (!uuid) {
|
87
|
+
// debugger
|
88
|
+
//}
|
89
|
+
return (asks) => {
|
90
|
+
const ask = (ask) => {
|
91
|
+
let oneShot = true // default
|
92
|
+
if (ask.oneShot === false) {
|
93
|
+
oneShot = false
|
94
|
+
}
|
95
|
+
|
96
|
+
const id_q = stableId('semantic')
|
97
|
+
const id_rs = []
|
98
|
+
let wasAsked = false
|
99
|
+
let wasApplied = false
|
100
|
+
const getWasAsked = () => {
|
101
|
+
return wasAsked
|
102
|
+
}
|
103
|
+
const setWasAsked = (value) => {
|
104
|
+
wasAsked = value
|
105
|
+
}
|
106
|
+
const getWasApplied = () => {
|
107
|
+
return wasApplied
|
108
|
+
}
|
109
|
+
const setWasApplied = (value) => {
|
110
|
+
wasApplied = value
|
111
|
+
}
|
112
|
+
|
113
|
+
const semanticsr = ask.semanticsr || []
|
114
|
+
if (semanticsr.length == 0) {
|
115
|
+
semanticsr.push({ match: ask.matchr, apply: ask.applyr })
|
116
|
+
}
|
117
|
+
for (const semantic of semanticsr) {
|
118
|
+
const id_r = stableId('semantic')
|
119
|
+
id_rs.push(id_r)
|
120
|
+
config.addSemantic({
|
121
|
+
uuid,
|
122
|
+
id: id_r,
|
123
|
+
tied_ids: [id_q],
|
124
|
+
oneShot,
|
125
|
+
where: semantic.where || ask.where || where(2),
|
126
|
+
source: 'response',
|
127
|
+
match: (args) => semantic.match(args),
|
128
|
+
apply: (args) => {
|
129
|
+
setWasApplied(true)
|
130
|
+
semantic.apply(args)
|
131
|
+
},
|
132
|
+
})
|
133
|
+
}
|
134
|
+
|
135
|
+
config.addSemantic({
|
136
|
+
uuid,
|
137
|
+
oneShot,
|
138
|
+
id: id_q,
|
139
|
+
tied_ids: id_rs,
|
140
|
+
where: ask.where,
|
141
|
+
isQuestion: true, // do one question at a time
|
142
|
+
getWasAsked,
|
143
|
+
getWasApplied,
|
144
|
+
onNevermind: ask.onNevermind,
|
145
|
+
source: 'question',
|
146
|
+
match: ({ context }) => context.marker == 'controlEnd' || context.marker == 'controlBetween',
|
147
|
+
apply: (args) => {
|
148
|
+
let matchq = ask.matchq
|
149
|
+
let applyq = ask.applyq
|
150
|
+
if (!matchq) {
|
151
|
+
let wasAsked = false
|
152
|
+
matchq = () => !wasAsked,
|
153
|
+
applyq = (args) => {
|
154
|
+
wasAsked = true
|
155
|
+
return ask.applyq(args)
|
156
|
+
}
|
67
157
|
}
|
158
|
+
if (matchq(args)) {
|
159
|
+
setWasAsked(true)
|
160
|
+
setWasApplied(false)
|
161
|
+
// args.context.motivationKeep = true
|
162
|
+
args.verbatim(applyq(args))
|
163
|
+
/*
|
164
|
+
args.context.verbatim = applyq(args)
|
165
|
+
args.context.isResponse = true;
|
166
|
+
delete args.context.controlRemove;
|
167
|
+
*/
|
168
|
+
args.context.controlKeepMotivation = true
|
169
|
+
}
|
170
|
+
args.context.cascade = true
|
68
171
|
}
|
69
|
-
|
70
|
-
// args.context.motivationKeep = true
|
71
|
-
args.verbatim(applyq(args))
|
72
|
-
/*
|
73
|
-
args.context.verbatim = applyq(args)
|
74
|
-
args.context.isResponse = true;
|
75
|
-
delete args.context.controlRemove;
|
76
|
-
*/
|
77
|
-
args.context.controlKeepMotivation = true
|
78
|
-
break
|
79
|
-
}
|
80
|
-
}
|
81
|
-
args.context.cascade = true
|
172
|
+
})
|
82
173
|
}
|
83
|
-
|
174
|
+
if (!Array.isArray(asks)) {
|
175
|
+
asks = [asks]
|
176
|
+
}
|
177
|
+
|
178
|
+
[...asks].reverse().forEach( (a) => ask(a) )
|
179
|
+
}
|
84
180
|
}
|
85
181
|
|
86
182
|
const sameJSON = (json1, json2) => {
|
@@ -105,6 +201,9 @@ const vimdiff = (actualJSON, expectedJSON, title) => {
|
|
105
201
|
}
|
106
202
|
|
107
203
|
const listable = (hierarchy) => (c, type) => {
|
204
|
+
if (!c) {
|
205
|
+
return false
|
206
|
+
}
|
108
207
|
if (hierarchy.isA(c.marker, type)) {
|
109
208
|
return true
|
110
209
|
}
|
@@ -119,6 +218,9 @@ const listable = (hierarchy) => (c, type) => {
|
|
119
218
|
}
|
120
219
|
|
121
220
|
const isA = (hierarchy) => (child, parent) => {
|
221
|
+
if (!child || !parent) {
|
222
|
+
return false
|
223
|
+
}
|
122
224
|
if (child.marker) {
|
123
225
|
child = child.marker
|
124
226
|
}
|
@@ -147,7 +249,8 @@ class ErrorReason extends Error {
|
|
147
249
|
}
|
148
250
|
|
149
251
|
const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
150
|
-
|
252
|
+
|
253
|
+
// callId
|
151
254
|
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
|
152
255
|
if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
|
153
256
|
args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
|
@@ -165,32 +268,11 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
165
268
|
args.asList = asList
|
166
269
|
args.retry = () => { throw new RetryError() }
|
167
270
|
args.fragments = (query) => config.fragment(query)
|
168
|
-
const scopedAsk = getAsk(config)
|
169
|
-
|
170
|
-
const getAPI = (uuid) => {
|
171
|
-
if (config && config.getAPI) {
|
172
|
-
return config.getAPI(uuid)
|
173
|
-
}
|
174
|
-
}
|
175
|
-
const getAPIs = (uuid) => {
|
176
|
-
if (config && config.getAPIs) {
|
177
|
-
return config.getAPIs(uuid)
|
178
|
-
}
|
179
|
-
}
|
180
|
-
args.getUUIDScoped = (uuid) => {
|
181
|
-
return {
|
182
|
-
ask: scopedAsk(uuid),
|
183
|
-
api: getAPI(uuid),
|
184
|
-
apis: getAPIs(uuid)
|
185
|
-
}
|
186
|
-
}
|
187
|
-
Object.assign(args, args.getUUIDScoped(uuidForScoping))
|
188
271
|
args.breakOnSemantics = false
|
189
272
|
args.theDebugger = {
|
190
273
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
191
274
|
}
|
192
275
|
if (!logs) {
|
193
|
-
debugger
|
194
276
|
}
|
195
277
|
args.log = (message) => logs.push(message)
|
196
278
|
|
@@ -219,6 +301,33 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
219
301
|
// for semantics
|
220
302
|
args.addAssumedScoped(args, {})
|
221
303
|
config.getAddedArgs(args)
|
304
|
+
|
305
|
+
const getAPI = (uuid) => {
|
306
|
+
if (config && config.getAPI) {
|
307
|
+
return config.getAPI(uuid)
|
308
|
+
}
|
309
|
+
}
|
310
|
+
const getAPIs = (uuid) => {
|
311
|
+
if (config && config.getAPIs) {
|
312
|
+
return config.getAPIs(uuid)
|
313
|
+
}
|
314
|
+
}
|
315
|
+
const scopedAsk = getAsk(config)
|
316
|
+
args.getUUIDScoped = (uuid) => {
|
317
|
+
return {
|
318
|
+
ask: scopedAsk(uuid),
|
319
|
+
api: getAPI(uuid),
|
320
|
+
apis: getAPIs(uuid)
|
321
|
+
}
|
322
|
+
}
|
323
|
+
Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
|
324
|
+
/*
|
325
|
+
if (uuidForScoping) {
|
326
|
+
Object.assign(args, args.getUUIDScoped(uuidForScoping))
|
327
|
+
}
|
328
|
+
*/
|
329
|
+
// sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
|
330
|
+
config.setArgs(args)
|
222
331
|
}
|
223
332
|
|
224
333
|
const gs = (g) => (contexts, separator, lastSeparator) => {
|
@@ -657,10 +766,8 @@ const loadInstance = (config, instance) => {
|
|
657
766
|
config.config.skipSemantics = results.skipSemantics
|
658
767
|
}
|
659
768
|
const args = { config, hierarchy, json: results, commandLineArgs: {} }
|
660
|
-
|
661
|
-
|
662
|
-
args.instance = instance.queries[i]
|
663
|
-
}
|
769
|
+
args.isInstance = `instance${i}`
|
770
|
+
args.instance = ''
|
664
771
|
processContextsB(args)
|
665
772
|
if (results.skipSemantics) {
|
666
773
|
config.config.skipSemantics = null
|
@@ -777,6 +884,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
777
884
|
response.trace = response.trace.concat(json.trace)
|
778
885
|
response.version = json.version
|
779
886
|
response.explain_priorities = json.explain_priorities
|
887
|
+
response.contextual_priorities_ambiguities = json.contextual_priorities_ambiguities
|
780
888
|
|
781
889
|
response.contexts = response.contexts.concat(contextsPrime)
|
782
890
|
response.generated = response.generated.concat(generatedPrime)
|
@@ -851,11 +959,6 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
851
959
|
}
|
852
960
|
|
853
961
|
let objects = getObjects(config.config.objects)(config.uuid)
|
854
|
-
let testConfigName = config.name
|
855
|
-
if (testConfig.testModuleName) {
|
856
|
-
objects = getObjects(config.config.objects)(config.getConfigs()[testConfig.testModuleName].uuid)
|
857
|
-
testConfigName = testConfig.testModuleName
|
858
|
-
}
|
859
962
|
try {
|
860
963
|
const result = await _process(config, test, { errorHandler, isTest: true })
|
861
964
|
result.query = test
|
@@ -895,7 +998,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
895
998
|
}
|
896
999
|
return expected.objects.namespaced[expected.objects.nameToUUID[name]] || {}
|
897
1000
|
}
|
898
|
-
const expected_checked = sortJson(pickObjects(testConfig, expectedGetObjects
|
1001
|
+
const expected_checked = sortJson(pickObjects(config, testConfig, expectedGetObjects), { depth: 25 })
|
899
1002
|
const actualGetObjects = (name) => {
|
900
1003
|
if (!name) {
|
901
1004
|
name = config.name
|
@@ -903,7 +1006,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug }) =
|
|
903
1006
|
const km = config.configs.find((km) => km.name == name)
|
904
1007
|
return config.config.objects.namespaced[km.uuid] || {}
|
905
1008
|
}
|
906
|
-
const actual_checked = sortJson(pickObjects(testConfig, actualGetObjects
|
1009
|
+
const actual_checked = sortJson(pickObjects(config, testConfig, actualGetObjects), { depth: 25 })
|
907
1010
|
const failed_checked = !matching(actual_objects, expected_objects)
|
908
1011
|
|
909
1012
|
const failed_checks = !matching(actual_objects, expected_objects)
|
@@ -1155,6 +1258,24 @@ const defaultErrorHandler = async (error) => {
|
|
1155
1258
|
throw error
|
1156
1259
|
}
|
1157
1260
|
|
1261
|
+
const printContextualPrioritiesAmbiguities = (cpa) => {
|
1262
|
+
console.log('Contextual Priorities Ambiguities')
|
1263
|
+
for (const counter in cpa) {
|
1264
|
+
console.log(` Counter ${counter}`)
|
1265
|
+
for (const choices of cpa[counter]) {
|
1266
|
+
console.log(' [')
|
1267
|
+
for (const choice of choices) {
|
1268
|
+
console.log(' [')
|
1269
|
+
for (const element of choice) {
|
1270
|
+
console.log(` ${JSON.stringify(element)},`)
|
1271
|
+
}
|
1272
|
+
console.log(' ],')
|
1273
|
+
}
|
1274
|
+
console.log(' ],')
|
1275
|
+
}
|
1276
|
+
}
|
1277
|
+
}
|
1278
|
+
|
1158
1279
|
const defaultInnerProcess = (config, errorHandler, responses) => {
|
1159
1280
|
if (responses.errors) {
|
1160
1281
|
console.log('Errors')
|
@@ -1173,6 +1294,9 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1173
1294
|
console.log('Logs')
|
1174
1295
|
responses.logs.forEach((log) => console.log(` ${log}`))
|
1175
1296
|
}
|
1297
|
+
if (responses.contextual_priorities_ambiguities) {
|
1298
|
+
printContextualPrioritiesAmbiguities(responses.contextual_priorities_ambiguities)
|
1299
|
+
}
|
1176
1300
|
console.log(responses.trace)
|
1177
1301
|
|
1178
1302
|
if (global.beforeObjects) {
|
@@ -1211,8 +1335,15 @@ const defaultInnerProcess = (config, errorHandler, responses) => {
|
|
1211
1335
|
console.log(` inputs: ${JSON.stringify(inputs)} output: ${JSON.stringify(output)} reason: ${reason}`)
|
1212
1336
|
}
|
1213
1337
|
}
|
1214
|
-
const objects = config.get('objects').namespaced[config.uuid]
|
1215
|
-
const
|
1338
|
+
// const objects = config.get('objects').namespaced[config.uuid]
|
1339
|
+
const actualGetObjects = (name) => {
|
1340
|
+
if (!name) {
|
1341
|
+
name = config.name
|
1342
|
+
}
|
1343
|
+
const km = config.configs.find((km) => km.name == name)
|
1344
|
+
return config.config.objects.namespaced[km.uuid] || {}
|
1345
|
+
}
|
1346
|
+
const picked = sortJson(pickObjects(config, config.testConfig, actualGetObjects), { depth: 25 })
|
1216
1347
|
if (!_.isEmpty(picked)) {
|
1217
1348
|
console.log('--- Object showing only the checked values ---')
|
1218
1349
|
console.log(JSON.stringify(picked, null, 2))
|
@@ -2024,6 +2155,13 @@ const knowledgeModuleImpl = async ({
|
|
2024
2155
|
})
|
2025
2156
|
f()
|
2026
2157
|
} else if (args.query) {
|
2158
|
+
let useTestConfig = testConfig
|
2159
|
+
if (args.testModuleName) {
|
2160
|
+
config.testConfig.testModuleName = args.testModuleName
|
2161
|
+
config.testConfig.checks = config.getConfigs()[args.testModuleName].getTestConfig().checks
|
2162
|
+
// useTestConfig = config.getConfigs()[args.testModuleName].getTestConfig()
|
2163
|
+
// useTestConfig.testModuleName = args.testModuleName
|
2164
|
+
}
|
2027
2165
|
const objects = getObjects(config.config.objects)(config.uuid)
|
2028
2166
|
// for the compare
|
2029
2167
|
if (args.objectDiff) {
|
@@ -2118,26 +2256,6 @@ const ensureTestFile = (module, name, type) => {
|
|
2118
2256
|
}
|
2119
2257
|
}
|
2120
2258
|
|
2121
|
-
function where (goUp = 2) {
|
2122
|
-
const e = new Error()
|
2123
|
-
const regexForm1 = /\((.*):(\d+):(\d+)\)$/
|
2124
|
-
const regexForm2 = /at (.*):(\d+):(\d+)$/
|
2125
|
-
const lines = e.stack.split('\n')
|
2126
|
-
let line
|
2127
|
-
for (line of lines.slice(1)) {
|
2128
|
-
if (!(line.includes('config.js:') || line.includes('client.js:'))) {
|
2129
|
-
break
|
2130
|
-
}
|
2131
|
-
}
|
2132
|
-
// const line = e.stack.split("\n")[goUp];
|
2133
|
-
const match = regexForm1.exec(line) || regexForm2.exec(line)
|
2134
|
-
if (match) {
|
2135
|
-
return `${match[1]}:${match[2]}`
|
2136
|
-
} else {
|
2137
|
-
return 'running in browser'
|
2138
|
-
}
|
2139
|
-
}
|
2140
|
-
|
2141
2259
|
function w (func) {
|
2142
2260
|
func.where = where(3)
|
2143
2261
|
return func
|
package/package.json
CHANGED
package/src/config.js
CHANGED
@@ -199,7 +199,7 @@ const priority_valid = (cp) => {
|
|
199
199
|
)
|
200
200
|
}
|
201
201
|
|
202
|
-
const handleBridgeProps = (config, bridge, addFirst) => {
|
202
|
+
const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
203
203
|
ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
|
204
204
|
() => {
|
205
205
|
if (!bridge.bridge) {
|
@@ -260,7 +260,8 @@ const handleBridgeProps = (config, bridge, addFirst) => {
|
|
260
260
|
}
|
261
261
|
*/
|
262
262
|
|
263
|
-
const addUUID = (obj) => { return { ...obj, uuid: config.uuid } }
|
263
|
+
const addUUID = (obj) => { return { ...obj, uuid: uuid || config.uuid } }
|
264
|
+
|
264
265
|
if (bridge.generators) {
|
265
266
|
const generators = [...bridge.generators]
|
266
267
|
generators.reverse()
|
@@ -343,14 +344,14 @@ const handleBridgeProps = (config, bridge, addFirst) => {
|
|
343
344
|
)
|
344
345
|
}
|
345
346
|
|
346
|
-
const handleCalculatedProps = (baseConfig, moreConfig, addFirst) => {
|
347
|
+
const handleCalculatedProps = (baseConfig, moreConfig, { addFirst, uuid } = {}) => {
|
347
348
|
if (moreConfig.bridges) {
|
348
349
|
moreConfig.bridges = moreConfig.bridges.map((bridge) => {
|
349
350
|
bridge = { ...bridge }
|
350
351
|
const valid = ['after', 'before', 'bridge', 'development', 'evaluator', 'generatorp', 'generatorr', 'generatorpr', 'generators', 'id', 'convolution', 'inverted', 'isA', 'children', 'parents',
|
351
352
|
'level', 'optional', 'selector', 'semantic', 'words', /Bridge$/, 'localHierarchy', 'levelSpecificHierarchy', 'where', 'uuid']
|
352
353
|
helpers.validProps(valid, bridge, 'bridge')
|
353
|
-
handleBridgeProps(baseConfig, bridge, addFirst)
|
354
|
+
handleBridgeProps(baseConfig, bridge, { addFirst, uuid })
|
354
355
|
return bridge
|
355
356
|
})
|
356
357
|
}
|
@@ -466,7 +467,7 @@ const normalizeConfig = (config) => {
|
|
466
467
|
if (config.semantics) {
|
467
468
|
for (const semantic of config.semantics) {
|
468
469
|
if (semantic.oneShot) {
|
469
|
-
semantic.id =
|
470
|
+
semantic.id = semantic.id || helpers.stableId('semantic')
|
470
471
|
}
|
471
472
|
}
|
472
473
|
}
|
@@ -901,6 +902,10 @@ class Config {
|
|
901
902
|
}
|
902
903
|
}
|
903
904
|
|
905
|
+
get semantics() {
|
906
|
+
return [...this.config.semantics]
|
907
|
+
}
|
908
|
+
|
904
909
|
getSemantics (logs = []) {
|
905
910
|
return new Semantics(this.config.semantics, logs, { km: this.name })
|
906
911
|
}
|
@@ -1314,7 +1319,7 @@ class Config {
|
|
1314
1319
|
if (global.transitoryMode) {
|
1315
1320
|
def.transitoryMode = true
|
1316
1321
|
}
|
1317
|
-
handleBridgeProps(this, def)
|
1322
|
+
handleBridgeProps(this, def, { uuid })
|
1318
1323
|
bridges.push(def)
|
1319
1324
|
this.checkBridges()
|
1320
1325
|
this._delta.json.bridges.push({ action: 'add', bridge: def })
|
@@ -1365,9 +1370,28 @@ class Config {
|
|
1365
1370
|
}
|
1366
1371
|
|
1367
1372
|
removeSemantic (deleteSemantic) {
|
1368
|
-
const
|
1369
|
-
|
1370
|
-
|
1373
|
+
const id = deleteSemantic.id || deleteSemantic
|
1374
|
+
const todo = [id]
|
1375
|
+
const seen = new Set()
|
1376
|
+
|
1377
|
+
while (todo.length > 0) {
|
1378
|
+
const id = todo.pop()
|
1379
|
+
if (seen.has(id)) {
|
1380
|
+
continue
|
1381
|
+
}
|
1382
|
+
seen.add(id)
|
1383
|
+
const index = this.config.semantics.findIndex((semantic) => semantic.id === id)
|
1384
|
+
if (index == -1) {
|
1385
|
+
continue
|
1386
|
+
}
|
1387
|
+
for (const tied_id of this.config.semantics[index].tied_ids || []) {
|
1388
|
+
if (!seen.has(tied_id)) {
|
1389
|
+
todo.push(tied_id)
|
1390
|
+
}
|
1391
|
+
}
|
1392
|
+
if (index >= 0) {
|
1393
|
+
this.config.semantics.splice(index, 1)
|
1394
|
+
}
|
1371
1395
|
}
|
1372
1396
|
}
|
1373
1397
|
|
@@ -1555,7 +1579,7 @@ class Config {
|
|
1555
1579
|
config._api.multiApi[api].args = args
|
1556
1580
|
}
|
1557
1581
|
} else {
|
1558
|
-
config._api.args = args
|
1582
|
+
config._api.args = { ...args, ...args.getUUIDScoped(config.uuid) }
|
1559
1583
|
}
|
1560
1584
|
}
|
1561
1585
|
|
@@ -2842,7 +2866,7 @@ class Config {
|
|
2842
2866
|
debugConfigProps(more)
|
2843
2867
|
|
2844
2868
|
if (hcps) {
|
2845
|
-
handleCalculatedProps(this, more, addFirst)
|
2869
|
+
handleCalculatedProps(this, more, { addFirst, uuid })
|
2846
2870
|
applyUUID(more, uuid || this._uuid)
|
2847
2871
|
}
|
2848
2872
|
for (const key of Object.keys(more)) {
|
@@ -3078,5 +3102,5 @@ module.exports = {
|
|
3078
3102
|
Config,
|
3079
3103
|
config_toServer,
|
3080
3104
|
operatorKey_valid,
|
3081
|
-
handleBridgeProps
|
3105
|
+
handleBridgeProps,
|
3082
3106
|
}
|
package/src/helpers.js
CHANGED
@@ -374,7 +374,15 @@ const subPriority = (sub, sup) => {
|
|
374
374
|
return true
|
375
375
|
}
|
376
376
|
|
377
|
+
const stableIds = {}
|
378
|
+
const stableId = (tag) => {
|
379
|
+
const id = stableIds[tag] || 1
|
380
|
+
stableIds[tag] = id + 1
|
381
|
+
return id
|
382
|
+
}
|
383
|
+
|
377
384
|
module.exports = {
|
385
|
+
stableId,
|
378
386
|
ecatch,
|
379
387
|
functionsToStrings,
|
380
388
|
updateQueries,
|
package/src/semantics.js
CHANGED
@@ -6,7 +6,7 @@ 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, applyWrapped, property, oneShot, id } = semantic
|
9
|
+
const { match, apply, uuid, index, km, notes, priority, debug, where, source, applyWrapped, property, oneShot, id, tied_ids, isQuestion } = semantic
|
10
10
|
this.matcher = match
|
11
11
|
this._apply = apply
|
12
12
|
this._applyWrapped = applyWrapped
|
@@ -18,8 +18,11 @@ class Semantic {
|
|
18
18
|
this.notes = notes
|
19
19
|
this.callId = debug
|
20
20
|
this.where = where
|
21
|
+
this.source = source
|
21
22
|
this.oneShot = oneShot
|
23
|
+
this.isQuestion = isQuestion
|
22
24
|
this.id = id
|
25
|
+
this.tied_ids = tied_ids || []
|
23
26
|
}
|
24
27
|
|
25
28
|
toLabel () {
|
@@ -184,11 +187,16 @@ class Semantics {
|
|
184
187
|
let applied = false
|
185
188
|
const stack = args.calls.push()
|
186
189
|
let counter = 0
|
190
|
+
let seenQuestion = false
|
187
191
|
for (const isemantic in this.semantics) {
|
188
192
|
const semantic = this.semantics[isemantic]
|
189
193
|
if (!semantic) {
|
190
194
|
debugger
|
191
195
|
}
|
196
|
+
// only one question at a time
|
197
|
+
if (semantic.isQuestion && seenQuestion) {
|
198
|
+
continue
|
199
|
+
}
|
192
200
|
if (semantic.matches(args, context, options)) {
|
193
201
|
if (!this.calls[counter]) {
|
194
202
|
this.calls[counter] = 0
|
@@ -198,6 +206,7 @@ class Semantics {
|
|
198
206
|
try {
|
199
207
|
contextPrime = semantic.apply(args, context, s, log, options)
|
200
208
|
if (!contextPrime.controlKeepMotivation && semantic.oneShot) {
|
209
|
+
// semantic.tied_ids.forEach((tied_id) => args.config.removeSemantic(tied_id))
|
201
210
|
args.config.removeSemantic(semantic)
|
202
211
|
}
|
203
212
|
} catch (e) {
|
@@ -274,6 +283,7 @@ class Semantics {
|
|
274
283
|
this.logs.push(lines.toString())
|
275
284
|
}
|
276
285
|
applied = true
|
286
|
+
seenQuestion = seenQuestion || semantic.isQuestion
|
277
287
|
if (contextPrime.cascade) {
|
278
288
|
contextPrime.cascade = false
|
279
289
|
} else {
|