theprogrammablemind 9.5.1-beta.1 → 9.5.1-beta.11
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 +13 -4
- package/lines.js +7 -0
- package/package.json +5 -3
- package/src/config.js +40 -41
- package/src/configHelpers.js +37 -5
- package/src/fragments.js +77 -0
- package/src/generators.js +9 -8
- package/src/helpers.js +59 -0
- package/src/semantics.js +3 -3
package/client.js
CHANGED
|
@@ -316,6 +316,7 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
|
316
316
|
}
|
|
317
317
|
|
|
318
318
|
let startCounter = 0
|
|
319
|
+
let contextIdCounter = 0
|
|
319
320
|
while (true) {
|
|
320
321
|
if (queries.length === 0) {
|
|
321
322
|
break
|
|
@@ -356,8 +357,9 @@ const _process = async (config, query, { initializer, commandLineArgs, credentia
|
|
|
356
357
|
}
|
|
357
358
|
const summary = { summaries: json.summaries, length: json.contexts.length }
|
|
358
359
|
summaries.push(summary)
|
|
359
|
-
const { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
|
360
|
-
await processContextsB({ isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
|
360
|
+
const { updatedContextIdCounter, contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime } =
|
|
361
|
+
await processContextsB({ contextIdCounter, isTest, isProcess, isModule, rebuildingTemplate, config, hierarchy, json, commandLineArgs /*, generators, semantics */ })
|
|
362
|
+
contextIdCounter = updatedContextIdCounter
|
|
361
363
|
if (isTest) {
|
|
362
364
|
const end = runtime.performance.performance.now()
|
|
363
365
|
clientSideTime = end - start
|
|
@@ -475,6 +477,7 @@ const runTest = async (config, expected, { args, verbose, testConfig, debug, tim
|
|
|
475
477
|
return
|
|
476
478
|
}
|
|
477
479
|
// initialize in between test so state is not preserved since the test was adding without state
|
|
480
|
+
config.testConfig.testModuleName = testConfig.testModuleName
|
|
478
481
|
await config.rebuild()
|
|
479
482
|
const errorHandler = (error) => {
|
|
480
483
|
if (error.metadata) {
|
|
@@ -2008,9 +2011,15 @@ const ensureTestFile = (module, name, type) => {
|
|
|
2008
2011
|
}
|
|
2009
2012
|
|
|
2010
2013
|
const knowledgeModule = async (...args) => {
|
|
2011
|
-
await knowledgeModuleImpl(...args).catch((e) => {
|
|
2014
|
+
await knowledgeModuleImpl(...args).catch(async (e) => {
|
|
2012
2015
|
console.error(e)
|
|
2013
|
-
|
|
2016
|
+
function sleep(ms) {
|
|
2017
|
+
return new Promise((resolve) => {
|
|
2018
|
+
setTimeout(resolve, ms);
|
|
2019
|
+
});
|
|
2020
|
+
}
|
|
2021
|
+
await sleep(1) // get the stderr to flush
|
|
2022
|
+
await process.exit(-1); // tiny trick: empty write forces flush of console.error buffer
|
|
2014
2023
|
})
|
|
2015
2024
|
}
|
|
2016
2025
|
|
package/lines.js
CHANGED
|
@@ -5,6 +5,13 @@ class Lines {
|
|
|
5
5
|
this.rows = []
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
static SCREEN_WIDTH = 132
|
|
9
|
+
|
|
10
|
+
static addRemainder(widths) {
|
|
11
|
+
const sum = widths.reduce((a, b) => a + b)
|
|
12
|
+
return [...widths, Lines.SCREEN_WIDTH - sum]
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
addLine () {
|
|
9
16
|
this.lines.push(this.widths.map((width) => ''.padEnd(width)))
|
|
10
17
|
}
|
package/package.json
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"@eslint/js": "^9.21.0",
|
|
4
4
|
"@typescript-eslint/eslint-plugin": "^4.28.4",
|
|
5
5
|
"@typescript-eslint/parser": "^4.28.4",
|
|
6
|
+
"argparse": "^2.0.1",
|
|
6
7
|
"eslint": "^7.32.0",
|
|
7
8
|
"eslint-config-standard": "^16.0.3",
|
|
8
9
|
"eslint-plugin-import": "^2.23.4",
|
|
9
10
|
"eslint-plugin-node": "^11.1.0",
|
|
10
11
|
"eslint-plugin-promise": "^5.1.0",
|
|
11
12
|
"globals": "^16.0.0",
|
|
12
|
-
"jest": "^
|
|
13
|
-
"argparse": "^2.0.1"
|
|
13
|
+
"jest": "^30.2.0"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"to:debug": "node inspect node_modules/.bin/jest --runInBand -t NEO23",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"runtime.js",
|
|
46
46
|
"src/helpers.js",
|
|
47
47
|
"src/flatten.js",
|
|
48
|
+
"src/fragments.js",
|
|
48
49
|
"src/unflatten.js",
|
|
49
50
|
"src/config.js",
|
|
50
51
|
"src/configHelpers.js",
|
|
@@ -61,6 +62,7 @@
|
|
|
61
62
|
"dependencies": {
|
|
62
63
|
"base-64": "^1.0.0",
|
|
63
64
|
"deep-equal": "^2.0.4",
|
|
65
|
+
"flatted": "^3.3.3",
|
|
64
66
|
"fs": "0.0.1-security",
|
|
65
67
|
"json-diff": "^1.0.3",
|
|
66
68
|
"json-stable-stringify": "^1.0.1",
|
|
@@ -71,6 +73,6 @@
|
|
|
71
73
|
"sort-json": "^2.0.0",
|
|
72
74
|
"uuid": "^8.3.2"
|
|
73
75
|
},
|
|
74
|
-
"version": "9.5.1-beta.
|
|
76
|
+
"version": "9.5.1-beta.11",
|
|
75
77
|
"license": "UNLICENSED"
|
|
76
78
|
}
|
package/src/config.js
CHANGED
|
@@ -10,6 +10,7 @@ const { ecatch } = require('./helpers')
|
|
|
10
10
|
const runtime = require('../runtime')
|
|
11
11
|
const _ = require('lodash')
|
|
12
12
|
const db = require('./debug')
|
|
13
|
+
const { fragmentInstantiator, fragmentMapperInstantiator } = require('./fragments')
|
|
13
14
|
|
|
14
15
|
const debugBreak = () => {
|
|
15
16
|
// debugger
|
|
@@ -289,11 +290,9 @@ const priority_valid = (cp) => {
|
|
|
289
290
|
const handleBridgeProps = (config, bridge, { addFirst, uuid } = {}) => {
|
|
290
291
|
ecatch(`While processing the bridge for ${bridge.id}#${bridge.level}`,
|
|
291
292
|
() => {
|
|
292
|
-
|
|
293
|
-
if (bridge.development && config.isModule) {
|
|
293
|
+
if (bridge.scope && config.isModule) {
|
|
294
294
|
return
|
|
295
295
|
}
|
|
296
|
-
*/
|
|
297
296
|
if (false && !bridge.bridge) {
|
|
298
297
|
bridge.bridge = '{ ...next(operator) }'
|
|
299
298
|
}
|
|
@@ -904,6 +903,10 @@ class Config {
|
|
|
904
903
|
return config_toServer(config)
|
|
905
904
|
}
|
|
906
905
|
|
|
906
|
+
async run(handler) {
|
|
907
|
+
return configHelpers.run(this, handler)
|
|
908
|
+
}
|
|
909
|
+
|
|
907
910
|
async fixtures () {
|
|
908
911
|
if (this.testConfig?.fixtures) {
|
|
909
912
|
const args = {}
|
|
@@ -1109,59 +1112,42 @@ class Config {
|
|
|
1109
1112
|
return instance
|
|
1110
1113
|
}
|
|
1111
1114
|
|
|
1112
|
-
|
|
1113
|
-
return new Object({
|
|
1114
|
-
contexts: () => contexts,
|
|
1115
|
-
instantiate: async (mappings) => {
|
|
1116
|
-
const instantiated = _.cloneDeep(contexts)
|
|
1117
|
-
// const todo = [...instantiated]
|
|
1118
|
-
// const todo = [...instantiated]
|
|
1119
|
-
const todo = _.clone(instantiated)
|
|
1120
|
-
args = { ...args }
|
|
1121
|
-
while (todo.length > 0) {
|
|
1122
|
-
const context = todo.pop()
|
|
1123
|
-
args.context = context
|
|
1124
|
-
for (const mapping of mappings) {
|
|
1125
|
-
if (await mapping.match(args)) {
|
|
1126
|
-
await mapping.apply(args)
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
for (const key of Object.keys(context)) {
|
|
1130
|
-
// if (['number', 'string', 'boolean'].includes(typeof (context[key]))) {
|
|
1131
|
-
if (!helpers.isCompound(context[key])) {
|
|
1132
|
-
continue
|
|
1133
|
-
}
|
|
1134
|
-
if (context[key].instantiated) {
|
|
1135
|
-
continue
|
|
1136
|
-
}
|
|
1137
|
-
todo.push(context[key])
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
return instantiated
|
|
1141
|
-
}
|
|
1142
|
-
})
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
fragment (args, query) {
|
|
1115
|
+
getFragment(query) {
|
|
1146
1116
|
for (const instance of (this.instances || [])) {
|
|
1147
1117
|
for (const fragment of (instance.fragments || [])) {
|
|
1148
1118
|
if (fragment.query === query) {
|
|
1149
|
-
return
|
|
1119
|
+
return fragment
|
|
1150
1120
|
}
|
|
1151
1121
|
}
|
|
1152
1122
|
for (const fragment of (instance.resultss || [])) {
|
|
1153
1123
|
if (fragment.isFragment && fragment.query === query) {
|
|
1154
|
-
return
|
|
1124
|
+
return fragment
|
|
1155
1125
|
}
|
|
1156
1126
|
}
|
|
1157
1127
|
for (const fragment of (this.fragmentsBeingBuilt || [])) {
|
|
1158
1128
|
if (fragment.query === query) {
|
|
1159
|
-
return
|
|
1129
|
+
return fragment
|
|
1160
1130
|
}
|
|
1161
1131
|
}
|
|
1162
1132
|
}
|
|
1163
1133
|
}
|
|
1164
1134
|
|
|
1135
|
+
fragment (args, query) {
|
|
1136
|
+
const fragment = this.getFragment(query)
|
|
1137
|
+
if (fragment) {
|
|
1138
|
+
return fragmentInstantiator(args, fragment.contexts)
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
fragmentMapper (args, values, fromModelQuery, toModelQuery) {
|
|
1143
|
+
const fromModelFragment = this.getFragment(fromModelQuery)
|
|
1144
|
+
console.dir(fromModelFragment)
|
|
1145
|
+
const toModelFragment = this.getFragment(toModelQuery)
|
|
1146
|
+
console.dir(toModelFragment)
|
|
1147
|
+
const mapper = fragmentMapperInstantiator(values, fromModelFragment.contexts, toModelFragment.contexts)
|
|
1148
|
+
return mapper
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1165
1151
|
// { rebuild: false, isModule: false }
|
|
1166
1152
|
needsRebuild (template, instance, options) {
|
|
1167
1153
|
if (options.rebuild) {
|
|
@@ -1866,6 +1852,16 @@ class Config {
|
|
|
1866
1852
|
}
|
|
1867
1853
|
}
|
|
1868
1854
|
|
|
1855
|
+
getObjects () {
|
|
1856
|
+
const configs = {}
|
|
1857
|
+
const ns = this.config.objects.namespaced
|
|
1858
|
+
configs[this.name] = this
|
|
1859
|
+
for (const config of this.configs) {
|
|
1860
|
+
configs[config._name] = ns[config._uuid]
|
|
1861
|
+
}
|
|
1862
|
+
return configs
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1869
1865
|
getConfig (name) {
|
|
1870
1866
|
if (this.name === name) {
|
|
1871
1867
|
return this
|
|
@@ -1913,12 +1909,15 @@ class Config {
|
|
|
1913
1909
|
} else if (this.scope == 'development') {
|
|
1914
1910
|
new_result = !(element.scope === 'testing')
|
|
1915
1911
|
}
|
|
1912
|
+
/*
|
|
1916
1913
|
if (global.GORDO && old_result !== new_result) {
|
|
1917
1914
|
global.GORDO = false
|
|
1918
1915
|
console.log("THERE WAS A DIFFERENCE ------------------------------------------------")
|
|
1919
1916
|
debugger // greg23old
|
|
1920
1917
|
}
|
|
1921
|
-
|
|
1918
|
+
*/
|
|
1919
|
+
// return old_result
|
|
1920
|
+
return new_result
|
|
1922
1921
|
}
|
|
1923
1922
|
|
|
1924
1923
|
config.operators = config.operators.filter((element) => keep(element))
|
package/src/configHelpers.js
CHANGED
|
@@ -121,6 +121,9 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
121
121
|
args.fragments = (query) => {
|
|
122
122
|
return config.fragment(args, query)
|
|
123
123
|
}
|
|
124
|
+
args.fragmentMapper = (values, fromModelQuery, toModelQuery) => {
|
|
125
|
+
return config.fragmentMapper(args, values, fromModelQuery, toModelQuery)
|
|
126
|
+
}
|
|
124
127
|
args.breakOnSemantics = false
|
|
125
128
|
args.theDebugger = {
|
|
126
129
|
breakOnSemantics: (value) => args.breakOnSemantics = value
|
|
@@ -133,6 +136,9 @@ const setupArgs = (args, config, logs, hierarchy, uuidForScoping) => {
|
|
|
133
136
|
args.addPattern = (pattern, def) => config.addPattern(pattern, args.uuid)
|
|
134
137
|
args.addGenerator = (generator) => config.addGenerator(generator, args.uuid, config.name)
|
|
135
138
|
|
|
139
|
+
if (config.testConfig?.testModuleName) {
|
|
140
|
+
args.testModuleName = config.testConfig.testModuleName
|
|
141
|
+
}
|
|
136
142
|
args.addAssumedScoped = (args, assumed) => {
|
|
137
143
|
const addAssumed = (args, ...moreAssumed) => {
|
|
138
144
|
return { ...args, assumed: Object.assign({}, assumed, (args.assumed || {}), ...moreAssumed) }
|
|
@@ -199,6 +205,23 @@ const getObjects = (objects) => {
|
|
|
199
205
|
}
|
|
200
206
|
}
|
|
201
207
|
|
|
208
|
+
const run = async (config, handler) => {
|
|
209
|
+
// map to hash
|
|
210
|
+
config = config || {}
|
|
211
|
+
if (config.config) {
|
|
212
|
+
config = config
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const hierarchy = new DigraphInternal((config.config || {}).hierarchy || [])
|
|
216
|
+
|
|
217
|
+
debugger
|
|
218
|
+
const objects = config.config.objects.namespaced[config.uuid]
|
|
219
|
+
const logs = []
|
|
220
|
+
const args = {}
|
|
221
|
+
setupArgs(args, config, logs, hierarchy)
|
|
222
|
+
return handler(args)
|
|
223
|
+
}
|
|
224
|
+
|
|
202
225
|
const processContext = async (context, { objects = {}, config, logs = [] }) => {
|
|
203
226
|
const generators = config.getGenerators(logs)
|
|
204
227
|
const semantics = config.getSemantics(logs)
|
|
@@ -291,7 +314,7 @@ const setupContexts = (rawContexts) => {
|
|
|
291
314
|
return contexts
|
|
292
315
|
}
|
|
293
316
|
|
|
294
|
-
const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate }) => {
|
|
317
|
+
const processContextsB = async ({ config, hierarchy, semantics, generators, json, isTest, isProcess, isModule, rebuildingTemplate, isInstance, instance, query, data, retries, url, commandLineArgs, forTemplate, contextIdCounter }) => {
|
|
295
318
|
// TODO fix this name to contextsPrime
|
|
296
319
|
const contextsPrime = []
|
|
297
320
|
const generatedPrime = []
|
|
@@ -311,14 +334,13 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
|
|
|
311
334
|
args.insert = (context) => toDo.unshift(context)
|
|
312
335
|
let overlap, lastRange
|
|
313
336
|
config.debugLoops = commandLineArgs && commandLineArgs.debugLoops
|
|
314
|
-
let context_id_counter = 0
|
|
315
337
|
while (toDo.length > 0) {
|
|
316
338
|
const context = toDo.shift()
|
|
317
339
|
args.calls.next()
|
|
318
340
|
let contextPrime = context
|
|
319
341
|
context.topLevel = true
|
|
320
|
-
|
|
321
|
-
context.context_id =
|
|
342
|
+
contextIdCounter += 1
|
|
343
|
+
context.context_id = contextIdCounter
|
|
322
344
|
try {
|
|
323
345
|
if (json.has_errors) {
|
|
324
346
|
throw new Error('There are errors in the logs. Run with the -d flag and grep for Error')
|
|
@@ -328,6 +350,9 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
|
|
|
328
350
|
const semantics = config.getSemantics(json.logs)
|
|
329
351
|
try {
|
|
330
352
|
contextPrime = await semantics.apply(args, context)
|
|
353
|
+
// contextPrime.greg = 'yes'
|
|
354
|
+
// console.log("context_id", context.context_id)
|
|
355
|
+
// console.log("semantics.apply", JSON.stringify(contextPrime, null, 2))
|
|
331
356
|
} catch (e) {
|
|
332
357
|
if (e.message == 'Maximum call stack size exceeded') {
|
|
333
358
|
const mostCalled = semantics.getMostCalled()
|
|
@@ -421,7 +446,7 @@ const processContextsB = async ({ config, hierarchy, semantics, generators, json
|
|
|
421
446
|
throw e
|
|
422
447
|
}
|
|
423
448
|
}
|
|
424
|
-
return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime }
|
|
449
|
+
return { contextsPrime, generatedPrime, paraphrasesPrime, paraphrasesParenthesizedPrime, generatedParenthesizedPrime, responsesPrime, updatedContextIdCounter: contextIdCounter }
|
|
425
450
|
}
|
|
426
451
|
|
|
427
452
|
// instance template loadTemplate
|
|
@@ -479,6 +504,9 @@ const loadInstance = async (config, instance) => {
|
|
|
479
504
|
args.isModule = true
|
|
480
505
|
args.isProcess = false
|
|
481
506
|
}
|
|
507
|
+
if (instance.name == config.testConfig.testModuleName) {
|
|
508
|
+
args.isTesting = true
|
|
509
|
+
}
|
|
482
510
|
await results.apply(args)
|
|
483
511
|
} else if (results.isFragment) {
|
|
484
512
|
} else {
|
|
@@ -490,6 +518,9 @@ const loadInstance = async (config, instance) => {
|
|
|
490
518
|
args.instance = ''
|
|
491
519
|
args.isProcess = !config.isModule
|
|
492
520
|
args.isModule = !!config.isModule
|
|
521
|
+
if (instance.name == config.testConfig.testModuleName) {
|
|
522
|
+
args.isTesting = true
|
|
523
|
+
}
|
|
493
524
|
await processContextsB(args)
|
|
494
525
|
if (results.skipSemantics) {
|
|
495
526
|
config.config.skipSemantics = null
|
|
@@ -505,6 +536,7 @@ module.exports = {
|
|
|
505
536
|
// listable,
|
|
506
537
|
setupArgs,
|
|
507
538
|
processContext,
|
|
539
|
+
run,
|
|
508
540
|
getObjects,
|
|
509
541
|
gs,
|
|
510
542
|
processContextsB,
|
package/src/fragments.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const _ = require('lodash')
|
|
2
|
+
const helpers = require('./helpers')
|
|
3
|
+
|
|
4
|
+
function fragmentInstantiator (args, contexts) {
|
|
5
|
+
return new Object({
|
|
6
|
+
contexts: () => contexts,
|
|
7
|
+
instantiate: async (mappings) => {
|
|
8
|
+
const instantiated = _.cloneDeep(contexts)
|
|
9
|
+
const todo = [{ context: instantiated, path: [] }]
|
|
10
|
+
args = { ...args }
|
|
11
|
+
while (todo.length > 0) {
|
|
12
|
+
const { context, path } = todo.pop()
|
|
13
|
+
args.context = context
|
|
14
|
+
args.path = path
|
|
15
|
+
for (const mapping of mappings) {
|
|
16
|
+
if (await mapping.match(args)) {
|
|
17
|
+
await mapping.apply(args)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
for (const key of Object.keys(context)) {
|
|
21
|
+
// if (['number', 'string', 'boolean'].includes(typeof (context[key]))) {
|
|
22
|
+
if (!helpers.isCompound(context[key])) {
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
if (context[key].instantiated) {
|
|
26
|
+
continue
|
|
27
|
+
}
|
|
28
|
+
todo.push({ context: context[key], path: [...path, key] })
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return instantiated
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function fragmentMapperInstantiator(values, modelFrom, modelTo) {
|
|
37
|
+
const paths = {}
|
|
38
|
+
for (const value of values) {
|
|
39
|
+
paths[value] = { value }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
{
|
|
43
|
+
const fi = fragmentInstantiator({paths}, modelFrom)
|
|
44
|
+
await fi.instantiate([
|
|
45
|
+
{
|
|
46
|
+
match: ({context, path}) => values.includes(context.value),
|
|
47
|
+
apply: ({context, path}) => paths[context.value].from = path
|
|
48
|
+
},
|
|
49
|
+
])
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
{
|
|
53
|
+
const fi = fragmentInstantiator({paths}, modelTo)
|
|
54
|
+
await fi.instantiate([
|
|
55
|
+
{
|
|
56
|
+
match: ({context, path}) => values.includes(context.value),
|
|
57
|
+
apply: ({context, path}) => paths[context.value].to = path
|
|
58
|
+
},
|
|
59
|
+
])
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
instantiate: (actualFrom) => {
|
|
63
|
+
const actualTo = structuredClone(modelTo)
|
|
64
|
+
for (const value in paths) {
|
|
65
|
+
const { from, to } = paths[value]
|
|
66
|
+
const actualValue = helpers.getByPath(actualFrom, from, null)
|
|
67
|
+
helpers.setByPath(actualTo, to, actualValue)
|
|
68
|
+
}
|
|
69
|
+
return actualTo
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = {
|
|
75
|
+
fragmentInstantiator,
|
|
76
|
+
fragmentMapperInstantiator,
|
|
77
|
+
}
|
package/src/generators.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const { stringify } = require('flatted');
|
|
1
2
|
const { args: contextArgs, normalizeGenerator } = require('./helpers')
|
|
2
3
|
const Lines = require('../lines')
|
|
3
4
|
const helpers = require('./helpers')
|
|
@@ -182,7 +183,7 @@ class Generators {
|
|
|
182
183
|
const generator = this.generators[igenerator]
|
|
183
184
|
if (await generator.matches(args, objects, context, hierarchy, config, options)) {
|
|
184
185
|
const log = (message) => { this.logs.push(message) }
|
|
185
|
-
// this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${
|
|
186
|
+
// this.logs.push(`Generators: applied ${generator.toString()}\n to\n ${stringify(context)}`)
|
|
186
187
|
let errorMessage = 'The apply function did not return a value'
|
|
187
188
|
try {
|
|
188
189
|
generated = await generator.apply(args, objects, context, hierarchy, config, response, log)
|
|
@@ -202,7 +203,7 @@ class Generators {
|
|
|
202
203
|
}
|
|
203
204
|
}
|
|
204
205
|
if (!generated && generated !== '') {
|
|
205
|
-
const widths = [10, 10
|
|
206
|
+
const widths = Lines.addRemainder([10, 10])
|
|
206
207
|
const lines = new Lines(widths)
|
|
207
208
|
lines.setElement(0, 0, 'Generator')
|
|
208
209
|
const source = `${generator.km}/#${generator.index}`
|
|
@@ -212,7 +213,7 @@ class Generators {
|
|
|
212
213
|
lines.newRow()
|
|
213
214
|
lines.setElement(0, 1, 'TO')
|
|
214
215
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
215
|
-
lines.setElement(1, 2,
|
|
216
|
+
lines.setElement(1, 2, stringify(helpers.sortJson(context, { depth: 10 }), null, 2))
|
|
216
217
|
lines.newRow()
|
|
217
218
|
lines.setElement(0, 1, 'STACK')
|
|
218
219
|
lines.setElement(0, 2, stack)
|
|
@@ -223,14 +224,14 @@ class Generators {
|
|
|
223
224
|
lines.setElement(0, 1, 'ERROR')
|
|
224
225
|
lines.setElement(0, 2, errorMessage)
|
|
225
226
|
this.logs.push(lines.toString())
|
|
226
|
-
const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${
|
|
227
|
+
const message = `ERROR while applying (${source}) ${generator.toLabel()}\n to\n ${stringify(context, null, 2)}.\n${errorMessage}'`
|
|
227
228
|
// this.logs.push(message)
|
|
228
229
|
// return [message]
|
|
229
230
|
args.calls.pop()
|
|
230
231
|
throw { error: [message], logs: this.logs }
|
|
231
232
|
}
|
|
232
233
|
if (((config || {}).config || {}).debug) {
|
|
233
|
-
const widths = [10, 10
|
|
234
|
+
const widths = Lines.addRemainder([10, 10])
|
|
234
235
|
const lines = new Lines(widths)
|
|
235
236
|
lines.setElement(0, 0, 'Generator')
|
|
236
237
|
if (generator.index > -1 && generator.km) {
|
|
@@ -254,7 +255,7 @@ class Generators {
|
|
|
254
255
|
lines.newRow()
|
|
255
256
|
lines.setElement(0, 1, 'TO')
|
|
256
257
|
lines.setElement(0, 2, `context_id: ${context.context_id}`)
|
|
257
|
-
lines.setElement(1, 2,
|
|
258
|
+
lines.setElement(1, 2, stringify(helpers.sortJson(context, { depth: 25 }), null, 2))
|
|
258
259
|
this.logs.push(lines.toString())
|
|
259
260
|
}
|
|
260
261
|
applied = true
|
|
@@ -263,7 +264,7 @@ class Generators {
|
|
|
263
264
|
}
|
|
264
265
|
args.calls.pop()
|
|
265
266
|
if (!applied && ((config || {}).config || {}).debug) {
|
|
266
|
-
const widths = [10, 10
|
|
267
|
+
const widths = Lines.addRemainder([10, 10])
|
|
267
268
|
const lines = new Lines(widths)
|
|
268
269
|
lines.setElement(0, 0, 'Generator')
|
|
269
270
|
lines.setElement(0, 2, 'No generator applied')
|
|
@@ -272,7 +273,7 @@ class Generators {
|
|
|
272
273
|
lines.setElement(0, 2, stack)
|
|
273
274
|
lines.newRow()
|
|
274
275
|
lines.setElement(0, 1, 'TO')
|
|
275
|
-
lines.setElement(0, 2,
|
|
276
|
+
lines.setElement(0, 2, stringify(context, null, 2))
|
|
276
277
|
this.logs.push(lines.toString())
|
|
277
278
|
}
|
|
278
279
|
return ((config || {}).parenthesized ? '(' + generated + ')' : generated)
|
package/src/helpers.js
CHANGED
|
@@ -436,6 +436,63 @@ const stableId = (tag) => {
|
|
|
436
436
|
return id
|
|
437
437
|
}
|
|
438
438
|
|
|
439
|
+
function getByPath(obj, path, defaultValue) {
|
|
440
|
+
let current = obj;
|
|
441
|
+
for (const key of path) {
|
|
442
|
+
if (current === null || current === undefined) return defaultValue;
|
|
443
|
+
if (typeof current !== 'object') return defaultValue;
|
|
444
|
+
current = current[key];
|
|
445
|
+
}
|
|
446
|
+
return current === undefined ? defaultValue : current;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Set a value in an object by path array.
|
|
451
|
+
* Automatically creates missing objects {} or arrays [] as needed.
|
|
452
|
+
*
|
|
453
|
+
* @param {Object} obj - The root object to modify
|
|
454
|
+
* @param {Array<string|number>} path - Array of keys/indices
|
|
455
|
+
* @param {*} value - Value to set
|
|
456
|
+
* @returns {*} The set value (for chaining)
|
|
457
|
+
*/
|
|
458
|
+
function setByPath(obj, path, value) {
|
|
459
|
+
if (!Array.isArray(path) || path.length === 0) {
|
|
460
|
+
throw new Error('Path must be a non-empty array');
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
let current = obj;
|
|
464
|
+
|
|
465
|
+
for (let i = 0; i < path.length; i++) {
|
|
466
|
+
const key = path[i];
|
|
467
|
+
const isLast = i === path.length - 1;
|
|
468
|
+
|
|
469
|
+
if (isLast) {
|
|
470
|
+
// Final step — just assign
|
|
471
|
+
current[key] = value;
|
|
472
|
+
} else {
|
|
473
|
+
// Not last — ensure next level exists
|
|
474
|
+
const nextKey = path[i + 1];
|
|
475
|
+
|
|
476
|
+
if (current[key] == null) {
|
|
477
|
+
// Auto-create: array if next key is number, otherwise object
|
|
478
|
+
current[key] = typeof nextKey === 'number' || String(nextKey >>> 0) === nextKey
|
|
479
|
+
? []
|
|
480
|
+
: {};
|
|
481
|
+
} else if (Array.isArray(current[key]) && typeof nextKey !== 'number') {
|
|
482
|
+
// Safety: if current is array but next key isn't a valid index → convert to object
|
|
483
|
+
current[key] = { ...current[key] };
|
|
484
|
+
} else if (!Array.isArray(current[key]) && typeof nextKey === 'number') {
|
|
485
|
+
// If next expects array but current is object → convert
|
|
486
|
+
current[key] = Object.values(current[key]);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
current = current[key];
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return value;
|
|
494
|
+
}
|
|
495
|
+
|
|
439
496
|
module.exports = {
|
|
440
497
|
stableId,
|
|
441
498
|
ecatch,
|
|
@@ -463,4 +520,6 @@ module.exports = {
|
|
|
463
520
|
w,
|
|
464
521
|
suggestAssociationsFix,
|
|
465
522
|
suggestAssociationsFixFromSummaries,
|
|
523
|
+
getByPath,
|
|
524
|
+
setByPath,
|
|
466
525
|
}
|
package/src/semantics.js
CHANGED
|
@@ -218,7 +218,7 @@ class Semantics {
|
|
|
218
218
|
errorMessage = e.toString()
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
const widths = [10, 10
|
|
221
|
+
const widths = Lines.addRemainder([10, 10])
|
|
222
222
|
const lines = new Lines(widths)
|
|
223
223
|
lines.setElement(0, 0, 'Semantic')
|
|
224
224
|
const source = `${semantic.km}/#${semantic.index}`
|
|
@@ -248,7 +248,7 @@ class Semantics {
|
|
|
248
248
|
args.calls.touch(contextPrime)
|
|
249
249
|
// this.logs.push(`Semantics: applied ${semantic.toString()}\n to\n ${JSON.stringify(context)}\n the result was ${JSON.stringify(contextPrime)}\n`)
|
|
250
250
|
if (((config || {}).config || {}).debug) {
|
|
251
|
-
const widths = [10, 10
|
|
251
|
+
const widths = Lines.addRemainder([10, 10])
|
|
252
252
|
const lines = new Lines(widths)
|
|
253
253
|
lines.setElement(0, 0, 'Semantic')
|
|
254
254
|
if (semantic.index > -1 && semantic.km) {
|
|
@@ -295,7 +295,7 @@ class Semantics {
|
|
|
295
295
|
}
|
|
296
296
|
args.calls.pop()
|
|
297
297
|
if (!applied && ((config || {}).config || {}).debug) {
|
|
298
|
-
const widths = [10, 10
|
|
298
|
+
const widths = Lines.addRemainder([10, 10])
|
|
299
299
|
const lines = new Lines(widths)
|
|
300
300
|
lines.setElement(0, 0, 'Semantic')
|
|
301
301
|
lines.setElement(0, 2, 'No semantic applied')
|