@platforma-sdk/workflow-tengo 3.0.2 → 3.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.
Files changed (46) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +2 -1
  3. package/dist/index.mjs +2 -1
  4. package/dist/tengo/lib/canonical.lib.tengo +73 -0
  5. package/dist/tengo/lib/exec.monetization.lib.tengo +3 -1
  6. package/dist/tengo/lib/exec.monetization_internal.lib.tengo +2 -1
  7. package/dist/tengo/lib/maps.lib.tengo +1 -1
  8. package/dist/tengo/lib/pframes.builder.lib.tengo +5 -1
  9. package/dist/tengo/lib/pframes.bundle.lib.tengo +544 -0
  10. package/dist/tengo/lib/pframes.constants.lib.tengo +5 -1
  11. package/dist/tengo/lib/pframes.lib.tengo +3 -0
  12. package/dist/tengo/lib/pframes.spec.lib.tengo +224 -1
  13. package/dist/tengo/lib/pframes.xsv-import-file.lib.tengo +3 -3
  14. package/dist/tengo/lib/pframes.xsv.lib.tengo +79 -4
  15. package/dist/tengo/lib/sets.lib.tengo +2 -0
  16. package/dist/tengo/lib/slices.lib.tengo +4 -1
  17. package/dist/tengo/lib/smart.lib.tengo +24 -6
  18. package/dist/tengo/lib/tpl.base.lib.tengo +582 -0
  19. package/dist/tengo/lib/tpl.lib.tengo +6 -567
  20. package/dist/tengo/lib/tpl.light.lib.tengo +9 -0
  21. package/dist/tengo/lib/workdir.proc.lib.tengo +1 -1
  22. package/dist/tengo/lib/workflow.lib.tengo +41 -2
  23. package/dist/tengo/lib/workflow.model.lib.tengo +3 -2
  24. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  25. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  26. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  27. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  28. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  29. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  30. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  31. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  32. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  36. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  37. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  38. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  39. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  40. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  41. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  42. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  43. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  44. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  45. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  46. package/package.json +3 -3
@@ -6,6 +6,8 @@
6
6
 
7
7
  ll := import("@platforma-sdk/workflow-tengo:ll")
8
8
  maps := import("@platforma-sdk/workflow-tengo:maps")
9
+ sets := import("@platforma-sdk/workflow-tengo:sets")
10
+ slices := import("@platforma-sdk/workflow-tengo:slices")
9
11
  validation := import("@platforma-sdk/workflow-tengo:validation")
10
12
  json := import("json")
11
13
 
@@ -33,6 +35,12 @@ P_COLUMN_SPEC_SCHEMA := {
33
35
  `axesSpec,?`: [ P_AXIS_SPEC_SCHEMA ]
34
36
  }
35
37
 
38
+ P_OBJECT_SPEC_SCHEMA := ["or", P_COLUMN_SPEC_SCHEMA, {
39
+ `kind`: `string`,
40
+ `annotations,?`: { any: `string` }
41
+ }]
42
+
43
+
36
44
  KIND_P_COLUMN := "PColumn"
37
45
 
38
46
 
@@ -251,9 +259,219 @@ makeTrace := func(input, ...steps) {
251
259
  })
252
260
  }
253
261
 
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+ createSpecDistiller := func(specs) {
270
+
271
+
272
+ domainsValues := {}
273
+
274
+ addDomainValue := func(name, domainName, domainValue) {
275
+ if is_undefined(domainsValues[name]) {
276
+ domainsValues[name] = {}
277
+ }
278
+
279
+ if is_undefined(domainsValues[name][domainName]) {
280
+ domainsValues[name][domainName] = {}
281
+ }
282
+
283
+ domainsValues[name][domainName][domainValue] = true
284
+ }
285
+
286
+
287
+ for _, spec in specs {
288
+
289
+ columnName := spec.name
290
+ if !is_undefined(spec.domain) {
291
+ for domainName, domainValue in spec.domain {
292
+ addDomainValue(columnName, domainName, domainValue)
293
+ }
294
+ }
295
+
296
+
297
+ if !is_undefined(spec.axesSpec) {
298
+ for _, axis in spec.axesSpec {
299
+ axisName := axis.name
300
+ if !is_undefined(axis.domain) {
301
+ for domainName, domainValue in axis.domain {
302
+ addDomainValue(axisName, domainName, domainValue)
303
+ }
304
+ }
305
+ }
306
+ }
307
+ }
308
+
309
+
310
+ discriminativeDomains := {}
311
+ for name, domains in domainsValues {
312
+ for domainName, valueSet in domains {
313
+ if len(valueSet) > 1 {
314
+ if is_undefined(discriminativeDomains[name]) {
315
+ discriminativeDomains[name] = {}
316
+ }
317
+ discriminativeDomains[name][domainName] = true
318
+ }
319
+ }
320
+ }
321
+
322
+
323
+ filterDomain := func(domain, entityName) {
324
+ if is_undefined(domain) {
325
+ return undefined
326
+ }
327
+
328
+ filteredDomain := undefined
329
+
330
+ if !is_undefined(discriminativeDomains[entityName]) {
331
+ for domainName, domainValue in domain {
332
+ if sets.hasElement(discriminativeDomains[entityName], domainName) {
333
+ if is_undefined(filteredDomain) {
334
+ filteredDomain = {}
335
+ }
336
+ filteredDomain[domainName] = domainValue
337
+ }
338
+ }
339
+ }
340
+
341
+ return filteredDomain
342
+ }
343
+
344
+
345
+ distillEntity := func(entity, entityName) {
346
+ result := maps.clone(entity)
347
+
348
+ delete(result, "annotations")
349
+
350
+
351
+ filteredDomain := filterDomain(result.domain, entityName)
352
+ if !is_undefined(filteredDomain) {
353
+ result.domain = filteredDomain
354
+ } else if !is_undefined(result.domain) {
355
+ delete(result, "domain")
356
+ }
357
+
358
+ return result
359
+ }
360
+
361
+ result := undefined
362
+ result = ll.toStrict({
363
+
364
+
365
+
366
+
367
+
368
+
369
+ getDiscriminativeDomains: func(name) {
370
+ return slices.fromSet(discriminativeDomains[name])
371
+ },
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+ getDiscriminativeDomainsSet: func(name) {
380
+ return discriminativeDomains[name]
381
+ },
382
+
383
+
384
+
385
+
386
+
387
+
388
+
389
+ distill: func(spec) {
390
+ result := distillEntity(spec, spec.name)
391
+
392
+
393
+ if !is_undefined(result.axesSpec) {
394
+ for i, axis in result.axesSpec {
395
+ result.axesSpec[i] = distillEntity(axis, axis.name)
396
+ }
397
+ }
398
+
399
+ return result
400
+ }
401
+ })
402
+
403
+ return result
404
+ }
405
+
406
+
407
+
408
+
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+ prepareAxisFilters := func(rules, spec) {
421
+ axisFilters := []
422
+ filteredIndices := {}
423
+
424
+ for _, rule in rules {
425
+ if len(rule) != 2 {
426
+ ll.panic("Invalid filtering rule format: %v", rule)
427
+ }
428
+
429
+ axisIdentifier := rule[0]
430
+ value := rule[1]
431
+
432
+ axisIdx := axisIdentifier
433
+ if is_string(axisIdentifier) {
434
+ axisIdx = -1
435
+ for idx, axis in spec.axesSpec {
436
+ if axis.name == axisIdentifier {
437
+ axisIdx = idx
438
+ break
439
+ }
440
+ }
441
+
442
+ if axisIdx == -1 {
443
+ ll.panic("Cannot find axis with name '%v' in column spec %v", axisIdentifier, spec)
444
+ }
445
+ }
446
+
447
+ if !is_int(axisIdx) {
448
+ ll.panic("Axis identifier must be a number or a string that can be resolved to an index: %v", axisIdentifier)
449
+ }
450
+
451
+ valueStr := string(value)
452
+ axisFilters = append(axisFilters, [axisIdx, valueStr])
453
+ filteredIndices[axisIdx] = true
454
+ }
455
+
456
+ transformedSpec := maps.clone(spec)
457
+ newAxesSpec := []
458
+ for idx, axis in spec.axesSpec {
459
+ if !filteredIndices[idx] {
460
+ newAxesSpec = append(newAxesSpec, maps.clone(axis))
461
+ }
462
+ }
463
+ transformedSpec.axesSpec = newAxesSpec
464
+
465
+ return {
466
+ axisFilters: axisFilters,
467
+ columnSpec: transformedSpec
468
+ }
469
+ }
470
+
254
471
  export ll.toStrict({
255
472
  P_AXIS_SPEC_SCHEMA: P_AXIS_SPEC_SCHEMA,
256
473
  P_COLUMN_SPEC_SCHEMA: P_COLUMN_SPEC_SCHEMA,
474
+ P_OBJECT_SPEC_SCHEMA: P_OBJECT_SPEC_SCHEMA,
257
475
 
258
476
  KIND_P_COLUMN: KIND_P_COLUMN,
259
477
 
@@ -269,5 +487,10 @@ export ll.toStrict({
269
487
  matchAxis: matchAxis,
270
488
  matchAxes: matchAxes,
271
489
 
272
- makeTrace: makeTrace
490
+ makeTrace: makeTrace,
491
+
492
+ createSpecDistiller: createSpecDistiller,
493
+
494
+ prepareAxisFilters: prepareAxisFilters
273
495
  })
496
+
@@ -10,6 +10,9 @@ constants := import("@platforma-sdk/workflow-tengo:pframes.constants")
10
10
  transposeXsvSw := assets.importSoftware("@platforma-open/milaboratories.software-small-binaries:table-converter")
11
11
  pfconvSw := assets.importSoftware("@milaboratories/software-pframes-conv:main")
12
12
 
13
+
14
+ importDirTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.import-dir")
15
+
13
16
  renderOps := func(defaults, ...ops) {
14
17
  o := { }
15
18
 
@@ -109,9 +112,6 @@ importFile := func(xsvFile, xsvType, spec, ...ops) {
109
112
  }
110
113
 
111
114
 
112
- importDirTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.import-dir")
113
-
114
-
115
115
  pureSpec := util.purifySpec(spec)
116
116
 
117
117
 
@@ -5,12 +5,15 @@
5
5
  validation := import("@platforma-sdk/workflow-tengo:validation")
6
6
  constants := import("@platforma-sdk/workflow-tengo:pframes.constants")
7
7
  objects := import("@platforma-sdk/workflow-tengo:objects")
8
+ smart := import("@platforma-sdk/workflow-tengo:smart")
8
9
  render := import("@platforma-sdk/workflow-tengo:render")
9
10
  maps := import("@platforma-sdk/workflow-tengo:maps")
10
11
  util := import("@platforma-sdk/workflow-tengo:pframes.util")
12
+ pBuilder := import("@platforma-sdk/workflow-tengo:pframes.builder")
11
13
  ll := import("@platforma-sdk/workflow-tengo:ll")
12
14
  assets := import("@platforma-sdk/workflow-tengo:assets")
13
15
  xsvIF := import("@platforma-sdk/workflow-tengo:pframes.xsv-import-file")
16
+ text := import("text")
14
17
 
15
18
  importXsvIfNullTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.xsv-import-if-not-null")
16
19
 
@@ -180,6 +183,67 @@ importFileMap := func(xsvMap, xsvType, spec, ...ops) {
180
183
 
181
184
  return result
182
185
  }
186
+
187
+ isFlatPfMap := func(pf) {
188
+ if !is_map(pf) {
189
+ return false
190
+ }
191
+
192
+ for key, _ in pf {
193
+ if !text.has_suffix(key, ".spec") && !text.has_suffix(key, ".data") {
194
+ return false
195
+ }
196
+ }
197
+
198
+ return true
199
+ }
200
+
201
+ isStructuredPfMap := func(pf) {
202
+ if !is_map(pf) {
203
+ return false
204
+ }
205
+
206
+ for _, value in pf {
207
+ if !is_map(value) {
208
+ return false
209
+ }
210
+
211
+ for k, _ in value {
212
+ if k != "spec" && k != "data" {
213
+ return false
214
+ }
215
+ }
216
+
217
+ if is_undefined(value.spec) || is_undefined(value.data) {
218
+ return false
219
+ }
220
+ }
221
+
222
+ return true
223
+ }
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
241
+
242
+
243
+
244
+
245
+
246
+
183
247
 
184
248
 
185
249
 
@@ -200,16 +264,27 @@ exportFrame := func(pf, xsvType, params, ...ops) {
200
264
  if is_array(pf) {
201
265
 
202
266
 
203
- pfm := {}
267
+ pfBuilder := pBuilder.pFrameBuilder()
204
268
  i := 0
205
269
  for col in pf {
206
270
  ll.assert(!is_undefined(col.spec), "expected array of {spec, data} maps as a list of columns, but spec is undefined for: ", col)
207
271
  ll.assert(!is_undefined(col.data), "expected array of {spec, data} maps as a list of columns, but data is undefined for: ", col)
208
- pfm["" + i + ".spec"] = col.spec
209
- pfm["" + i + ".data"] = col.data
272
+ pfBuilder.add(string(i), col.spec, col.data)
210
273
  i = i + 1
211
274
  }
212
- pf = pfm
275
+ pf = pfBuilder.build()
276
+ } else if isStructuredPfMap(pf) {
277
+ pfBuilder := pBuilder.pFrameBuilder()
278
+ for key, value in pf {
279
+ pfBuilder.add(key, value.spec, value.data)
280
+ }
281
+ pf = pfBuilder.build()
282
+ } else if smart.isResource(pf) {
283
+ if !pf.checkResourceType(constants.RTYPE_P_FRAME) {
284
+ ll.panic("Unexpected resource type: %s", pf.info().Type.Name)
285
+ }
286
+ } else if !isFlatPfMap(pf) && !smart.isReference(pf) {
287
+ ll.panic("Unexpected p-frame format: %s", pf)
213
288
  }
214
289
 
215
290
  r := render.create(exportPfTpl, {
@@ -5,6 +5,7 @@
5
5
 
6
6
 
7
7
  ll := import("@platforma-sdk/workflow-tengo:ll")
8
+ slices := import("@platforma-sdk/workflow-tengo:slices")
8
9
  maps := import("@platforma-sdk/workflow-tengo:maps")
9
10
 
10
11
 
@@ -32,6 +33,7 @@ toSlice := func(set) {
32
33
  for v, _ in set {
33
34
  sl = append(sl, v)
34
35
  }
36
+ slices.quickSortInPlace(sl)
35
37
  return sl
36
38
  }
37
39
 
@@ -292,8 +292,11 @@ sortByFn := func(notSortedSlice, fn) {
292
292
 
293
293
 
294
294
  fromSet := func(set) {
295
+ if is_undefined(set) {
296
+ return []
297
+ }
295
298
  slice := enum.map(set, func(k, _) { return k })
296
- return sortByFn(slice, func(elem) { return elem })
299
+ return quickSortInPlace(slice)
297
300
  }
298
301
 
299
302
 
@@ -1189,8 +1189,16 @@ structBuilder = func(resourceType, ...data) {
1189
1189
 
1190
1190
 
1191
1191
 
1192
- _mapBuilder := func(isEph) {
1193
- builder := isEph ? ephemeralBuilder(constants.RTYPE_MAP_EPH) : structBuilder(constants.RTYPE_MAP)
1192
+
1193
+ _mapBuilder := func(isEph, ...resourceType) {
1194
+ mapType := undefined
1195
+ if len(resourceType) > 0 {
1196
+ mapType = resourceType[0]
1197
+ } else {
1198
+ mapType = isEph ? constants.RTYPE_MAP_EPH : constants.RTYPE_MAP
1199
+ }
1200
+
1201
+ builder := isEph ? ephemeralBuilder(mapType) : structBuilder(mapType)
1194
1202
 
1195
1203
  builder.lockOutputs()
1196
1204
 
@@ -1259,12 +1267,22 @@ _mapBuilder := func(isEph) {
1259
1267
  return self
1260
1268
  }
1261
1269
 
1262
- mapBuilder = func() {
1263
- return _mapBuilder(false)
1270
+
1271
+
1272
+
1273
+
1274
+
1275
+ mapBuilder = func(...resourceType) {
1276
+ return _mapBuilder(false, resourceType...)
1264
1277
  }
1265
1278
 
1266
- ephemeralMapBuilder = func() {
1267
- return _mapBuilder(true)
1279
+
1280
+
1281
+
1282
+
1283
+
1284
+ ephemeralMapBuilder = func(...resourceType) {
1285
+ return _mapBuilder(true, resourceType...)
1268
1286
  }
1269
1287
 
1270
1288
  ephemeralBuilder = func(resourceType, ...data) {