theprogrammablemind 8.0.0 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.js +576 -928
- package/index.js +3 -2
- package/package.json +13 -13
- package/src/config.js +285 -259
- package/src/configHelpers.js +455 -0
- package/src/generators.js +8 -8
- package/src/helpers.js +34 -1
- package/src/project.js +1 -1
- package/src/semantics.js +63 -69
@@ -0,0 +1,455 @@
|
|
1
|
+
const { InitCalls } = require('./helpers')
|
2
|
+
const DigraphInternal = require('./digraph_internal')
|
3
|
+
|
4
|
+
const gs = (g) => async (contexts, separator, lastSeparator) => {
|
5
|
+
if (!Array.isArray(contexts)) {
|
6
|
+
throw new Error('Expected a list')
|
7
|
+
}
|
8
|
+
|
9
|
+
let s = ''
|
10
|
+
if (!separator) {
|
11
|
+
separator = ' '
|
12
|
+
}
|
13
|
+
if (!lastSeparator) {
|
14
|
+
lastSeparator = separator
|
15
|
+
}
|
16
|
+
let nextSeparator = ''
|
17
|
+
for (let i = 0; i < contexts.length; ++i) {
|
18
|
+
const context = contexts[i]
|
19
|
+
const value = await g(context)
|
20
|
+
if (i > 0) {
|
21
|
+
if (i === contexts.length - 1) {
|
22
|
+
nextSeparator = lastSeparator
|
23
|
+
} else {
|
24
|
+
nextSeparator = separator
|
25
|
+
}
|
26
|
+
}
|
27
|
+
s += nextSeparator + value
|
28
|
+
}
|
29
|
+
return s
|
30
|
+
}
|
31
|
+
|
32
|
+
const asList = (context) => {
|
33
|
+
if (context.marker === 'list') {
|
34
|
+
return context
|
35
|
+
}
|
36
|
+
return {
|
37
|
+
marker: 'list',
|
38
|
+
types: [context.marker],
|
39
|
+
value: [context]
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
const isA = (hierarchy) => (child, parent) => {
|
44
|
+
if (!child || !parent) {
|
45
|
+
return false
|
46
|
+
}
|
47
|
+
if (child.marker) {
|
48
|
+
child = child.marker
|
49
|
+
}
|
50
|
+
if (parent.marker) {
|
51
|
+
parent = parent.marker
|
52
|
+
}
|
53
|
+
return hierarchy.isA(child, parent)
|
54
|
+
}
|
55
|
+
|
56
|
+
class ErrorReason extends Error {
|
57
|
+
constructor (context) {
|
58
|
+
super(JSON.stringify(context))
|
59
|
+
this.reason = context
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
const listable = (hierarchy) => (c, type) => {
|
64
|
+
if (!c) {
|
65
|
+
return false
|
66
|
+
}
|
67
|
+
if (hierarchy.isA(c.marker, type)) {
|
68
|
+
return true
|
69
|
+
}
|
70
|
+
if (c.marker === 'list') {
|
71
|
+
for (const t of c.types) {
|
72
|
+
if (hierarchy.isA(t, type)) {
|
73
|
+
return true
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
return false
|
78
|
+
}
|
79
|
+
|
80
|
+
const cleanAssign = (dest, ...srcs) => {
|
81
|
+
for (const key in dest) {
|
82
|
+
let found = false
|
83
|
+
for (const src of srcs) {
|
84
|
+
if (src[key]) {
|
85
|
+
found = true
|
86
|
+
break
|
87
|
+
}
|
88
|
+
}
|
89
|
+
if (!found) {
|
90
|
+
delete dest[key]
|
91
|
+
}
|
92
|
+
}
|
93
|
+
Object.assign(dest, ...srcs)
|
94
|
+
}
|
95
|
+
|
96
|
+
const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
97
|
+
|
98
|
+
// callId
|
99
|
+
args.calls = new InitCalls(args.isInstance ? `${args.isInstance}#${config.name}` : config.name)
|
100
|
+
if (global.theprogrammablemind && global.theprogrammablemind.loadForTesting) {
|
101
|
+
args.calls = new InitCalls(Object.keys(global.theprogrammablemind.loadForTesting)[0])
|
102
|
+
}
|
103
|
+
args.cleanAssign = cleanAssign
|
104
|
+
args.km = (name) => config.getConfig(name)
|
105
|
+
args.api = (name) => config.getConfig(name).api
|
106
|
+
args.error = (context) => {
|
107
|
+
throw new ErrorReason(context)
|
108
|
+
}
|
109
|
+
args.kms = config.getConfigs()
|
110
|
+
args.config = config
|
111
|
+
args.hierarchy = hierarchy
|
112
|
+
args.isA = isA(hierarchy)
|
113
|
+
args.listable = listable(hierarchy)
|
114
|
+
args.asList = asList
|
115
|
+
args.retry = () => { throw new RetryError() }
|
116
|
+
args.fragments = (query) => {
|
117
|
+
return config.fragment(args, query)
|
118
|
+
}
|
119
|
+
args.breakOnSemantics = false
|
120
|
+
args.theDebugger = {
|
121
|
+
breakOnSemantics: (value) => args.breakOnSemantics = value
|
122
|
+
}
|
123
|
+
if (!logs) {
|
124
|
+
}
|
125
|
+
args.log = (message) => logs.push(message)
|
126
|
+
|
127
|
+
args.addAssumedScoped = (args, assumed) => {
|
128
|
+
const addAssumed = (args, ...moreAssumed) => {
|
129
|
+
return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
|
130
|
+
}
|
131
|
+
|
132
|
+
args.s = (c) => config.getSemantics(logs).apply(args, c)
|
133
|
+
args.g = (c, a = {}) => {
|
134
|
+
return config.getGenerators(logs).apply(addAssumed(args, a), c, a)
|
135
|
+
}
|
136
|
+
args.gp = (c, a = {}) => {
|
137
|
+
return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: true, isResponse: false, response: false }), c, { paraphrase: true, isResponse: false, response: false })
|
138
|
+
}
|
139
|
+
args.gr = (c, a = {}) => {
|
140
|
+
return config.getGenerators(logs).apply(addAssumed(args, a, { paraphrase: false, isResponse: true }), { ...c, paraphrase: false, isResponse: true })
|
141
|
+
}
|
142
|
+
args.e = (c) => {
|
143
|
+
return config.getEvaluator(args.s, args.calls, logs, c)
|
144
|
+
}
|
145
|
+
args.gs = gs(args.g)
|
146
|
+
args.gsp = gs(args.gp)
|
147
|
+
args.gsr = gs(args.gr)
|
148
|
+
}
|
149
|
+
// for semantics
|
150
|
+
args.addAssumedScoped(args, {})
|
151
|
+
|
152
|
+
const getAPI = (uuid) => {
|
153
|
+
if (config && config.getAPI) {
|
154
|
+
return config.getAPI(uuid)
|
155
|
+
}
|
156
|
+
}
|
157
|
+
const getAPIs = (uuid) => {
|
158
|
+
if (config && config.getAPIs) {
|
159
|
+
return config.getAPIs(uuid)
|
160
|
+
}
|
161
|
+
}
|
162
|
+
args.getUUIDScoped = (uuid) => {
|
163
|
+
return {
|
164
|
+
api: getAPI(uuid),
|
165
|
+
apis: getAPIs(uuid)
|
166
|
+
}
|
167
|
+
}
|
168
|
+
config.getAddedArgs(args)
|
169
|
+
|
170
|
+
Object.assign(args, args.getUUIDScoped(uuidForScoping || config.uuid))
|
171
|
+
/*
|
172
|
+
if (uuidForScoping) {
|
173
|
+
Object.assign(args, args.getUUIDScoped(uuidForScoping))
|
174
|
+
}
|
175
|
+
*/
|
176
|
+
// sets args for all the API. that make a copy so the args must be fully setup by here except for scoped
|
177
|
+
config.setArgs(args)
|
178
|
+
}
|
179
|
+
|
180
|
+
const getObjects = (objects) => {
|
181
|
+
return (uuid) => {
|
182
|
+
if (objects && objects.namespaced) {
|
183
|
+
return objects.namespaced[uuid]
|
184
|
+
}
|
185
|
+
return objects
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
const processContext = async (context, { objects = {}, config, logs = [] }) => {
|
190
|
+
const generators = config.getGenerators(logs)
|
191
|
+
const semantics = config.getSemantics(logs)
|
192
|
+
|
193
|
+
// map to hash
|
194
|
+
config = config || {}
|
195
|
+
if (config.config) {
|
196
|
+
config = config
|
197
|
+
}
|
198
|
+
|
199
|
+
const response = {} // NA but passed in
|
200
|
+
// generators = new Generators(generators.map((g) => new Generator(normalizeGenerator(g))))
|
201
|
+
// semantics = new Semantics(semantics.map((g) => new Semantic(normalizeSemantic(g))))
|
202
|
+
const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
|
203
|
+
|
204
|
+
const args = { objects, response, getObjects: getObjects(objects) }
|
205
|
+
setupArgs(args, config, logs, hierarchy)
|
206
|
+
|
207
|
+
context = await semantics.apply(args, context)
|
208
|
+
const generated = await generators.apply(args, context)
|
209
|
+
const assumed = { paraphrase: true, response: false, isResponse: false }
|
210
|
+
const paraphrases = await generators.apply({ ...args, assumed }, context, { paraphrase: true, response: false, isResponse: false })
|
211
|
+
let responses = []
|
212
|
+
if (context.isResponse) {
|
213
|
+
responses = generated
|
214
|
+
}
|
215
|
+
return { context, generated, paraphrases, responses }
|
216
|
+
}
|
217
|
+
|
218
|
+
const setupProcessB = ({ config, initializer, allowDelta = false } = {}) => {
|
219
|
+
const key = config._key
|
220
|
+
|
221
|
+
const data = Object.assign({ key, version: '3' }, { uuid: config._uuid })
|
222
|
+
if (allowDelta && config.allowDelta && config.hasDelta()) {
|
223
|
+
// console.log('config', config)
|
224
|
+
data.delta = config.delta()
|
225
|
+
} else {
|
226
|
+
config.toData(data)
|
227
|
+
// Object.assign(data, config.config)
|
228
|
+
}
|
229
|
+
|
230
|
+
// config.toServer(data)
|
231
|
+
|
232
|
+
if (data.namespaces) {
|
233
|
+
for (const uuid of Object.keys(data.namespaces)) {
|
234
|
+
const km = config.configs.find((km) => km.uuid === uuid)
|
235
|
+
data.namespaces[uuid].name = km.name
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
// const generators = new Generators((data.generators || []).map((g) => new Generator(normalizeGenerator(g))))
|
240
|
+
delete data.generators
|
241
|
+
// const semantics = new Semantics((data.semantics || []).map((g) => new Semantic(normalizeSemantic(g))))
|
242
|
+
delete data.semantics
|
243
|
+
const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
|
244
|
+
|
245
|
+
return {
|
246
|
+
data,
|
247
|
+
// generators,
|
248
|
+
// semantics,
|
249
|
+
hierarchy
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
const setupContexts = (rawContexts) => {
|
254
|
+
let first = true
|
255
|
+
const contexts = []
|
256
|
+
contexts.push({ marker: 'controlStart', controlRemove: true })
|
257
|
+
for (const context of rawContexts) {
|
258
|
+
if (first) {
|
259
|
+
first = false
|
260
|
+
} else {
|
261
|
+
contexts.push({ marker: 'controlBetween', controlRemove: true })
|
262
|
+
}
|
263
|
+
contexts.push(context)
|
264
|
+
}
|
265
|
+
contexts.push({ marker: 'controlEnd', controlRemove: true })
|
266
|
+
return contexts
|
267
|
+
}
|
268
|
+
|
269
|
+
const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs }) => {
|
270
|
+
// TODO fix this name to contextsPrime
|
271
|
+
const contextsPrime = []
|
272
|
+
const generatedPrime = []
|
273
|
+
const paraphrasesPrime = []
|
274
|
+
const paraphrasesParenthesizedPrime = []
|
275
|
+
const generatedParenthesizedPrime = []
|
276
|
+
const responsesPrime = []
|
277
|
+
const contexts = setupContexts(json.contexts)
|
278
|
+
|
279
|
+
const objects = config.get('objects')
|
280
|
+
const args = { objects, isResponse: true, response: json, isTest, isInstance, getObjects: getObjects(objects), instance }
|
281
|
+
if (!json.logs) {
|
282
|
+
json.logs = []
|
283
|
+
}
|
284
|
+
setupArgs(args, config, json.logs, hierarchy)
|
285
|
+
const toDo = [...contexts]
|
286
|
+
args.insert = (context) => toDo.unshift(context)
|
287
|
+
let overlap, lastRange
|
288
|
+
config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
|
289
|
+
while (toDo.length > 0) {
|
290
|
+
const context = toDo.shift()
|
291
|
+
args.calls.next()
|
292
|
+
let contextPrime = context
|
293
|
+
context.topLevel = true
|
294
|
+
try {
|
295
|
+
if (json.has_errors) {
|
296
|
+
throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
|
297
|
+
}
|
298
|
+
const generateParenthesized = isTest || (commandLineArgs && commandLineArgs.save)
|
299
|
+
if (!config.get('skipSemantics')) {
|
300
|
+
const semantics = config.getSemantics(json.logs)
|
301
|
+
try {
|
302
|
+
contextPrime = await semantics.apply(args, context)
|
303
|
+
} catch (e) {
|
304
|
+
if (e.message == 'Maximum call stack size exceeded') {
|
305
|
+
const mostCalled = semantics.getMostCalled()
|
306
|
+
e.message += `\nThe most called semantic was:\nnotes: ${mostCalled.notes}\nmatch: ${mostCalled.matcher.toString()}\napply: ${mostCalled._apply.toString()}\n`
|
307
|
+
}
|
308
|
+
// contextPrime = semantics.apply(args, { marker: 'error', context, error: e })
|
309
|
+
if (isInstance) {
|
310
|
+
console.log('error', e.error)
|
311
|
+
}
|
312
|
+
let reason = e.reason
|
313
|
+
if (!reason) {
|
314
|
+
if (e.error) {
|
315
|
+
reason = e.error[0]
|
316
|
+
}
|
317
|
+
}
|
318
|
+
contextPrime = await semantics.apply(args, {
|
319
|
+
marker: 'error',
|
320
|
+
context,
|
321
|
+
text: e ? e.toString() : 'not available',
|
322
|
+
// reason: e.reason,
|
323
|
+
reason,
|
324
|
+
error: e.stack || e.error
|
325
|
+
})
|
326
|
+
if (rebuildingTemplate) {
|
327
|
+
throw e
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
if (contextPrime.controlRemove) {
|
332
|
+
continue
|
333
|
+
}
|
334
|
+
let assumed = { isResponse: true }
|
335
|
+
const generated = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
|
336
|
+
let generatedParenthesized = []
|
337
|
+
if (generateParenthesized) {
|
338
|
+
config.parenthesized = true
|
339
|
+
generatedParenthesized = contextPrime.isResponse ? await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed) : ''
|
340
|
+
config.parenthesized = false
|
341
|
+
}
|
342
|
+
// assumed = { paraphrase: true, response: false };
|
343
|
+
assumed = { paraphrase: true, isResponse: false, response: false }
|
344
|
+
if (generateParenthesized) {
|
345
|
+
config.parenthesized = false
|
346
|
+
}
|
347
|
+
const paraphrases = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
|
348
|
+
let paraphrasesParenthesized = []
|
349
|
+
if (generateParenthesized) {
|
350
|
+
config.parenthesized = true
|
351
|
+
paraphrasesParenthesized = await config.getGenerators(json.logs).apply({ ...args, assumed }, contextPrime, assumed)
|
352
|
+
config.parenthesized = false
|
353
|
+
}
|
354
|
+
contextsPrime.push(contextPrime)
|
355
|
+
generatedPrime.push(generated)
|
356
|
+
paraphrasesPrime.push(paraphrases)
|
357
|
+
if (generateParenthesized) {
|
358
|
+
paraphrasesParenthesizedPrime.push(paraphrasesParenthesized)
|
359
|
+
generatedParenthesizedPrime.push(generatedParenthesized)
|
360
|
+
}
|
361
|
+
if (contextPrime.isResponse) {
|
362
|
+
responsesPrime.push(generated)
|
363
|
+
} else {
|
364
|
+
responsesPrime.push('')
|
365
|
+
}
|
366
|
+
|
367
|
+
// add results to processed list
|
368
|
+
config.config.objects.processed = config.config.objects.processed || []
|
369
|
+
config.config.objects.processed = config.config.objects.processed.slice(0, 5)
|
370
|
+
config.config.objects.processed.unshift({ context: contextPrime, paraphrases: paraphrases, paraphrasesParenthesized, generatedParenthesized, responses: responsesPrime })
|
371
|
+
} catch (e) {
|
372
|
+
if (Array.isArray(e)) {
|
373
|
+
e = {
|
374
|
+
errors: e
|
375
|
+
}
|
376
|
+
}
|
377
|
+
e.context = contextPrime
|
378
|
+
if (e.logs) {
|
379
|
+
e.logs = e.logs.concat(json.logs)
|
380
|
+
} else {
|
381
|
+
e.logs = json.logs
|
382
|
+
}
|
383
|
+
e.metadata = json.metadata
|
384
|
+
if (json.trace) {
|
385
|
+
e.trace = json.trace
|
386
|
+
}
|
387
|
+
throw e
|
388
|
+
}
|
389
|
+
}
|
390
|
+
return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
|
391
|
+
}
|
392
|
+
|
393
|
+
// instance template loadTemplate
|
394
|
+
const loadInstance = async (config, instance) => {
|
395
|
+
const transitoryMode = global.transitoryMode
|
396
|
+
global.transitoryMode = false
|
397
|
+
|
398
|
+
if (instance && (instance.associations || instance.learned_contextual_priorities)) {
|
399
|
+
if (!config.config.retrain) {
|
400
|
+
if (instance.associations) {
|
401
|
+
config.addAssociations(instance.associations)
|
402
|
+
}
|
403
|
+
if (instance.learned_contextual_priorities && instance.learned_contextual_priorities.length > 0) {
|
404
|
+
config.addPriorities(instance.learned_contextual_priorities)
|
405
|
+
}
|
406
|
+
}
|
407
|
+
}
|
408
|
+
|
409
|
+
const { /* data, generators, semantics, */ hierarchy } = setupProcessB({ config })
|
410
|
+
for (const i in (instance.resultss || [])) {
|
411
|
+
const results = instance.resultss[i]
|
412
|
+
if (results.extraConfig) {
|
413
|
+
// config.addInternal(results, useOldVersion = true, skipObjects = false, includeNamespaces = true, allowNameToBeNull = false)
|
414
|
+
const uuid = config.nameToUUID(instance.name)
|
415
|
+
// used to do a CLONE
|
416
|
+
config.addInternal(instance.template.configs[i], { uuid, addFirst: true, handleCalculatedProps: true })
|
417
|
+
} else if (results.apply) {
|
418
|
+
const objects = getObjects(config.get('objects'))(config.uuid)
|
419
|
+
const args = { objects, getObjects: getObjects(objects) }
|
420
|
+
if (instance.configs) {
|
421
|
+
args.isInstance = `instance${i}`
|
422
|
+
args.instance = instance.configs[i]
|
423
|
+
}
|
424
|
+
|
425
|
+
const uuid = config.nameToUUID(instance.name)
|
426
|
+
setupArgs(args, config, config.logs, hierarchy, uuid)
|
427
|
+
await results.apply(args)
|
428
|
+
} else if (results.isFragment) {
|
429
|
+
} else {
|
430
|
+
if (results.skipSemantics) {
|
431
|
+
config.config.skipSemantics = results.skipSemantics
|
432
|
+
}
|
433
|
+
const args = { config, hierarchy, json: results, commandLineArgs: {} }
|
434
|
+
args.isInstance = `instance${i}`
|
435
|
+
args.instance = ''
|
436
|
+
await processContextsB(args)
|
437
|
+
if (results.skipSemantics) {
|
438
|
+
config.config.skipSemantics = null
|
439
|
+
}
|
440
|
+
}
|
441
|
+
}
|
442
|
+
global.transitoryMode = transitoryMode
|
443
|
+
}
|
444
|
+
|
445
|
+
module.exports = {
|
446
|
+
setupProcessB,
|
447
|
+
ErrorReason,
|
448
|
+
listable,
|
449
|
+
setupArgs,
|
450
|
+
processContext,
|
451
|
+
getObjects,
|
452
|
+
gs,
|
453
|
+
processContextsB,
|
454
|
+
loadInstance,
|
455
|
+
}
|
package/src/generators.js
CHANGED
@@ -44,7 +44,7 @@ class Generator {
|
|
44
44
|
return `Generator(${this.match}, ${this._applyWrapped || this._apply})${this.property ? `\nsee the ${this.property} property` : ''}`
|
45
45
|
}
|
46
46
|
|
47
|
-
matches (baseArgs, objects, context, hierarchy, config, options = {}) {
|
47
|
+
async matches (baseArgs, objects, context, hierarchy, config, options = {}) {
|
48
48
|
if (objects && objects.namespaced) {
|
49
49
|
objects = objects.namespaced[this.uuid]
|
50
50
|
}
|
@@ -63,17 +63,17 @@ class Generator {
|
|
63
63
|
}
|
64
64
|
const args = Object.assign({}, baseArgs, moreArgs, (baseArgs.getUUIDScoped || (() => { return {} }))(this.uuid))
|
65
65
|
// return this.match(args)
|
66
|
-
const matches = this.match(args)
|
66
|
+
const matches = await this.match(args)
|
67
67
|
if ((matches && (options.debug || {}).match) ||
|
68
68
|
callId == this.callId) {
|
69
69
|
debugger // next line is the matcher
|
70
|
-
this.match(args)
|
70
|
+
await this.match(args)
|
71
71
|
}
|
72
72
|
return matches
|
73
73
|
}
|
74
74
|
|
75
75
|
// apply (baseArgs, objects, g, gs, context, hierarchy, config, response, log, options = {}) {
|
76
|
-
apply (baseArgs, objects, context, hierarchy, config, response, log, options = {}) {
|
76
|
+
async apply (baseArgs, objects, context, hierarchy, config, response, log, options = {}) {
|
77
77
|
if (!log) {
|
78
78
|
throw new Error('generators.apply argument log is required')
|
79
79
|
}
|
@@ -129,7 +129,7 @@ class Generator {
|
|
129
129
|
callId == this.callId) {
|
130
130
|
debugger
|
131
131
|
}
|
132
|
-
return this._apply(args)
|
132
|
+
return await this._apply(args)
|
133
133
|
}
|
134
134
|
}
|
135
135
|
|
@@ -165,7 +165,7 @@ class Generators {
|
|
165
165
|
};
|
166
166
|
|
167
167
|
// assumed - properties added to context before the generators are called. For setting paraphrase property
|
168
|
-
apply (args, context, assumed = {}, options = {}) {
|
168
|
+
async apply (args, context, assumed = {}, options = {}) {
|
169
169
|
if (Array.isArray(context)) {
|
170
170
|
throw new Error('Expected a context not an array')
|
171
171
|
}
|
@@ -186,12 +186,12 @@ class Generators {
|
|
186
186
|
const stack = args.calls.push()
|
187
187
|
for (let igenerator = 0; igenerator < this.generators.length; ++igenerator) {
|
188
188
|
const generator = this.generators[igenerator]
|
189
|
-
if (generator.matches(args, objects, context, hierarchy, config, options)) {
|
189
|
+
if (await generator.matches(args, objects, context, hierarchy, config, options)) {
|
190
190
|
const log = (message) => { this.logs.push(message) }
|
191
191
|
// this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${JSON.stringify(context)}`)
|
192
192
|
let errorMessage = 'The apply function did not return a value'
|
193
193
|
try {
|
194
|
-
generated = generator.apply(args, objects, context, hierarchy, config, response, log)
|
194
|
+
generated = await generator.apply(args, objects, context, hierarchy, config, response, log)
|
195
195
|
} catch (e) {
|
196
196
|
// the next if handle this
|
197
197
|
generated = null
|
package/src/helpers.js
CHANGED
@@ -1,6 +1,37 @@
|
|
1
1
|
const deepEqual = require('deep-equal')
|
2
2
|
const stringify = require('json-stable-stringify')
|
3
3
|
|
4
|
+
function where (goUp = 2) {
|
5
|
+
const e = new Error()
|
6
|
+
const regexForm1 = /\((.*):(\d+):(\d+)\)$/
|
7
|
+
const regexForm2 = /at (.*):(\d+):(\d+)$/
|
8
|
+
const lines = e.stack.split('\n')
|
9
|
+
let line
|
10
|
+
let match
|
11
|
+
for (line of lines.slice(1)) {
|
12
|
+
// if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('<anonymous>'))) {
|
13
|
+
if (!(line.includes('config.js:') || line.includes('client.js:') || line.includes('helpers.js:'))) {
|
14
|
+
match = regexForm1.exec(line) || regexForm2.exec(line)
|
15
|
+
if (!match) {
|
16
|
+
continue
|
17
|
+
}
|
18
|
+
break
|
19
|
+
}
|
20
|
+
}
|
21
|
+
// const line = e.stack.split("\n")[goUp];
|
22
|
+
// const match = regexForm1.exec(line) || regexForm2.exec(line)
|
23
|
+
if (match) {
|
24
|
+
return `${match[1]}:${match[2]}`
|
25
|
+
} else {
|
26
|
+
return 'running in browser or in an async call so the stack is broken.'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
function w (func) {
|
31
|
+
func.where = where(3)
|
32
|
+
return func
|
33
|
+
}
|
34
|
+
|
4
35
|
// properties - the properties that correspond to types
|
5
36
|
// types - the expected types of the properties
|
6
37
|
// returns list of properties found matching order of types
|
@@ -403,5 +434,7 @@ module.exports = {
|
|
403
434
|
InitCalls,
|
404
435
|
hashCode,
|
405
436
|
sortJson,
|
406
|
-
subPriority
|
437
|
+
subPriority,
|
438
|
+
where,
|
439
|
+
w,
|
407
440
|
}
|
package/src/project.js
CHANGED
@@ -49,7 +49,7 @@ const project = (object, filter) => {
|
|
49
49
|
const property = properties.property
|
50
50
|
if (properties.isPropertyList) {
|
51
51
|
if (!Array.isArray(object[property])) {
|
52
|
-
|
52
|
+
continue
|
53
53
|
}
|
54
54
|
for (const propertyRef of object[property]) {
|
55
55
|
const old = object[propertyRef]
|