@platforma-sdk/workflow-tengo 4.12.0 → 4.13.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 (44) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -0
  3. package/dist/index.mjs +1 -0
  4. package/dist/tengo/lib/maps.lib.tengo +8 -2
  5. package/dist/tengo/lib/pframes.lib.tengo +148 -30
  6. package/dist/tengo/lib/pframes.spec.lib.tengo +37 -3
  7. package/dist/tengo/lib/slices.lib.tengo +1 -1
  8. package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
  9. package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
  10. package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
  11. package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
  12. package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
  13. package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
  14. package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
  15. package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
  16. package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
  17. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  18. package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
  19. package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
  20. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  21. package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
  22. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  23. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  24. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  25. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  26. package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
  27. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  28. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  29. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  30. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  31. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  32. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  36. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  37. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  38. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  39. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  40. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  41. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  42. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  43. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  44. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  declare type TemplateFromFile = { readonly type: "from-file"; readonly path: string; };
2
- declare type TplName = "ll.get-field" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.remove-nulls" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "workflow.query-anchored" | "anonymize.deanonymize" | "anonymize.impl" | "check_network.workdir_type_name_extractor" | "exec.delayed-compute-allocation.impl" | "exec.monetization_to_json" | "exec.python.install-deps" | "exec.python.venv-bin-path" | "pframes.export-multiple-pcolumns" | "pframes.slice-data" | "check_network.create_workdir_from_storage" | "check_network.download_blob" | "check_network.upload_blob" | "check_network.upload_template" | "exec.R.create-renv" | "exec.exec-impl" | "exec.monetization_info" | "exec.python.create-venv" | "exec.load-software.impl" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "check_network.run_hello_world" | "check_network.run_hello_world_py" | "pframes.process-pcolumn-data" | "pframes.export-pframe" | "pframes.export-pframe-for-ui";
2
+ declare type TplName = "ll.get-field" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.remove-nulls" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "workflow.query-anchored" | "anonymize.deanonymize" | "anonymize.impl" | "check_network.workdir_type_name_extractor" | "exec.delayed-compute-allocation.impl" | "exec.monetization_to_json" | "exec.python.install-deps" | "exec.python.venv-bin-path" | "pframes.export-multiple-pcolumns" | "pframes.slice-data" | "check_network.create_workdir_from_storage" | "check_network.download_blob" | "check_network.upload_blob" | "check_network.upload_template" | "exec.R.create-renv" | "exec.exec-impl" | "exec.monetization_info" | "exec.python.create-venv" | "pframes.parse-to-json" | "exec.load-software.impl" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "check_network.run_hello_world" | "check_network.run_hello_world_py" | "pframes.process-pcolumn-data" | "pframes.export-pframe" | "pframes.export-pframe-for-ui";
3
3
  declare const Templates: Record<TplName, TemplateFromFile>;
4
4
  export { Templates };
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ module.exports = { Templates: {
24
24
  'exec.exec-impl': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.exec-impl.plj.gz') },
25
25
  'exec.monetization_info': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.monetization_info.plj.gz') },
26
26
  'exec.python.create-venv': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.python.create-venv.plj.gz') },
27
+ 'pframes.parse-to-json': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.parse-to-json.plj.gz') },
27
28
  'exec.load-software.impl': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.load-software.impl.plj.gz') },
28
29
  'exec.exec': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.exec.plj.gz') },
29
30
  'pframes.xsv-export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
package/dist/index.mjs CHANGED
@@ -25,6 +25,7 @@ export const Templates = {
25
25
  'exec.exec-impl': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.exec-impl.plj.gz') },
26
26
  'exec.monetization_info': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.monetization_info.plj.gz') },
27
27
  'exec.python.create-venv': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.python.create-venv.plj.gz') },
28
+ 'pframes.parse-to-json': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.parse-to-json.plj.gz') },
28
29
  'exec.load-software.impl': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.load-software.impl.plj.gz') },
29
30
  'exec.exec': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.exec.plj.gz') },
30
31
  'pframes.xsv-export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
@@ -213,8 +213,14 @@ deepTransform = func(...maps) {
213
213
  } else {
214
214
  res[k] = result
215
215
  }
216
- } else if is_map(res[k]) && is_map(v) {
217
- res[k] = deepTransform(res[k], v)
216
+ } else if is_map(v) {
217
+ if is_map(res[k]) {
218
+ res[k] = deepTransform(res[k], v)
219
+ } else {
220
+
221
+
222
+ res[k] = deepTransform({}, v)
223
+ }
218
224
  } else {
219
225
  res[k] = v
220
226
  }
@@ -20,6 +20,29 @@ pColumnData := import("@platforma-sdk/workflow-tengo:pframes.data")
20
20
  llProcessTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.process-pcolumn-data")
21
21
 
22
22
 
23
+ TSV_CONTENT_SETTINGS_SCHEMA := {
24
+ "axes": [{
25
+ "column": "string",
26
+ "spec": {
27
+ "type": "string,regex=Int|Long|Float|Double|String",
28
+ "name,?": "string",
29
+ "domain,?": { "any": "string" },
30
+ "annotations,?": { "any": "string" }
31
+ }
32
+ }],
33
+ "columns": [{
34
+ "column": "string",
35
+ "id,?": "string",
36
+ "spec": {
37
+ "valueType": "string,regex=Int|Long|Float|Double|String",
38
+ "name,?": "string",
39
+ "domain,?": { "any": "string" },
40
+ "annotations,?": { "any": "string" }
41
+ }
42
+ }]
43
+ }
44
+
45
+
23
46
 
24
47
 
25
48
 
@@ -185,6 +208,36 @@ __primitiveValueTypes := { "Int": true, "Long": true, "Float": true, "Double": t
185
208
 
186
209
 
187
210
 
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
188
241
 
189
242
 
190
243
 
@@ -249,12 +302,25 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
249
302
  ll.panic("can't use passAggregationAxesSpec, passAggregationAxesNames or passDistilledAggregationSpec without aggregate")
250
303
  }
251
304
 
305
+ createOutputTrace := func(output) {
306
+ hasOutputTrace := !is_undefined(output.traceSteps)
307
+ hasGlobalTrace := !is_undefined(opts.traceSteps)
308
+ hasInputTrace := !is_undefined(input.spec.annotations[pSpec.A_TRACE])
252
309
 
253
- trace := undefined
254
- if !is_undefined(opts.traceSteps) || !is_undefined(input.spec.annotations[pSpec.A_TRACE]) {
255
- trace = pSpec.makeTrace(input.spec, (opts.traceSteps ? opts.traceSteps : [])...)
256
- }
310
+ outputTraceSteps := slices.normalize(opts.traceSteps) + slices.normalize(output.traceSteps)
311
+
312
+ trace := undefined
313
+ if len(outputTraceSteps) > 0 || hasInputTrace {
314
+ trace = pSpec.makeTrace(input.spec, outputTraceSteps...)
315
+ }
257
316
 
317
+ outputOverrideTrace := output.overrideTrace
318
+ if is_undefined(outputOverrideTrace) {
319
+ outputOverrideTrace = hasOutputTrace || hasGlobalTrace
320
+ }
321
+
322
+ return { trace: trace, overrideTrace: outputOverrideTrace }
323
+ }
258
324
 
259
325
  processTemplateParams := {
260
326
  eph: opts.isEphemeral,
@@ -289,7 +355,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
289
355
  metaExtra = {}
290
356
  }
291
357
 
292
- iterationAxesSpec := input.spec.axesSpec
358
+ iterationAxesSpec := copy(input.spec.axesSpec)
293
359
 
294
360
 
295
361
  if !isPotentiallyPartitioned {
@@ -376,19 +442,20 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
376
442
  for output in outputs {
377
443
 
378
444
  outputsMap[output.name] = output
445
+ traceInfo := createOutputTrace(output)
379
446
  if output.type == "Resource" || output.type == "BinaryPartitioned" || output.type == "JsonPartitioned" {
380
- spec := maps.merge(output.spec, { axesSpec: iterationAxesSpec + slices.normalize(output.spec.axesSpec) })
381
- if !is_undefined(trace) {
382
- spec = trace.inject(spec)
447
+ spec := maps.merge(output.spec, { axesSpec: copy(iterationAxesSpec) + slices.normalize(output.spec.axesSpec) })
448
+ if !is_undefined(traceInfo.trace) {
449
+ spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
383
450
  }
384
451
  outputSpecs[output.name] = spec
385
- processedOutputs = append(processedOutputs, maps.merge(output, {spec: undefined })) // removing spec field
452
+ processedOutputs = append(processedOutputs, maps.merge(output, {spec: undefined, traceSteps: undefined, overrideTrace: undefined }))
386
453
  } else if output.type == "ResourceMap" {
387
454
  processedOutputs = append(processedOutputs, maps.merge(output,
388
- { keyLength: len(output.spec.axesSpec), spec: undefined }))
389
- spec := maps.merge(output.spec, { axesSpec: iterationAxesSpec + slices.normalize(output.spec.axesSpec) })
390
- if !is_undefined(trace) {
391
- spec = trace.inject(spec)
455
+ { keyLength: len(output.spec.axesSpec), spec: undefined, traceSteps: undefined, overrideTrace: undefined }))
456
+ spec := maps.merge(output.spec, { axesSpec: copy(iterationAxesSpec) + slices.normalize(output.spec.axesSpec) })
457
+ if !is_undefined(traceInfo.trace) {
458
+ spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
392
459
  }
393
460
  outputSpecs[output.name] = spec
394
461
  } else if output.type == "Xsv" {
@@ -400,17 +467,68 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
400
467
  })
401
468
  purifiedPfconvCfg := decomposition.purifiedCfg
402
469
  columnsSpec := decomposition.columnsSpec
403
- if !is_undefined(trace) {
470
+ if !is_undefined(traceInfo.trace) {
404
471
  for columnName, spec in columnsSpec {
405
- columnsSpec[columnName] = trace.inject(spec)
472
+ columnsSpec[columnName] = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
406
473
  }
407
474
  }
408
475
  outputSpecs[output.name] = columnsSpec
409
476
  processedOutputs = append(processedOutputs, maps.merge(output,
410
477
  {
411
478
  settings: purifiedPfconvCfg,
412
- flattenWithDelimiter: "/"
479
+ flattenWithDelimiter: "/",
480
+ traceSteps: undefined,
481
+ overrideTrace: undefined
413
482
  }))
483
+ } else if output.type == "TsvContent" {
484
+ validation.assertType(output.settings, TSV_CONTENT_SETTINGS_SCHEMA, "Invalid TsvContent settings")
485
+
486
+
487
+ transformedSettings := {
488
+ axes: slices.map(output.settings.axes, func(axis) {
489
+ return {
490
+ name: axis.column,
491
+ type: axis.spec.type
492
+ }
493
+ }),
494
+ columns: slices.map(output.settings.columns, func(column) {
495
+ transformedColumn := {
496
+ name: column.column,
497
+ type: column.spec.valueType
498
+ }
499
+ if !is_undefined(column.id) {
500
+ transformedColumn.id = column.id
501
+ }
502
+ return transformedColumn
503
+ })
504
+ }
505
+
506
+
507
+ columnsSpec := {}
508
+ axesSpec := copy(iterationAxesSpec)
509
+ for axis in output.settings.axes {
510
+ axesSpec = append(axesSpec, axis.spec)
511
+ }
512
+
513
+ for column in output.settings.columns {
514
+ columnId := column.id
515
+ if is_undefined(columnId) {
516
+ columnId = column.column
517
+ }
518
+ spec := maps.merge(column.spec, { axesSpec: axesSpec, kind: "PColumn" })
519
+ if !is_undefined(traceInfo.trace) {
520
+ spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
521
+ }
522
+ columnsSpec[columnId] = spec
523
+ }
524
+
525
+ outputSpecs[output.name] = columnsSpec
526
+ processedOutputs = append(processedOutputs, maps.merge(output, {
527
+ settings: transformedSettings,
528
+ flattenWithDelimiter: "/",
529
+ traceSteps: undefined,
530
+ overrideTrace: undefined
531
+ }))
414
532
  } else {
415
533
  ll.panic("unknown output type: " + output.type)
416
534
  }
@@ -455,9 +573,9 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
455
573
  }
456
574
 
457
575
  spec := outputSpecs[name]
458
- if output.type == "Xsv" {
576
+ if output.type == "Xsv" || output.type == "TsvContent" {
459
577
  if len(column) != 1 {
460
- ll.panic("column name must be provided for Xsv output")
578
+ ll.panic("column name must be provided for " + output.type + " output")
461
579
  }
462
580
  columnName := column[0]
463
581
  spec = spec[columnName]
@@ -467,7 +585,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
467
585
  return spec
468
586
  } else {
469
587
  if len(column) > 0 {
470
- ll.panic("column name should not be provided for non-Xsv output")
588
+ ll.panic("column name should not be provided for non-Xsv/TsvContent output")
471
589
  }
472
590
  return spec
473
591
  }
@@ -490,14 +608,14 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
490
608
  ll.panic("unknown output: " + name)
491
609
  }
492
610
 
493
- if output.type == "Xsv" {
611
+ if output.type == "Xsv" || output.type == "TsvContent" {
494
612
  if len(column) != 1 {
495
- ll.panic("column name must be provided for Xsv output")
613
+ ll.panic("column name must be provided for " + output.type + " output")
496
614
  }
497
615
  return renderResult.output(name + "/" + column[0])
498
616
  } else {
499
617
  if len(column) > 0 {
500
- ll.panic("column name should not be provided for non-Xsv output")
618
+ ll.panic("column name should not be provided for non-Xsv/TsvContent output")
501
619
  }
502
620
  return renderResult.output(name)
503
621
  }
@@ -520,9 +638,9 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
520
638
  ll.panic("unknown output: " + name)
521
639
  }
522
640
 
523
- if output.type == "Xsv" {
641
+ if output.type == "Xsv" || output.type == "TsvContent" {
524
642
  if len(column) != 1 {
525
- ll.panic("column name must be provided for Xsv output")
643
+ ll.panic("column name must be provided for " + output.type + " output")
526
644
  }
527
645
  columnName := column[0]
528
646
  spec := outputSpecs[name][columnName]
@@ -535,7 +653,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
535
653
  }
536
654
  } else {
537
655
  if len(column) > 0 {
538
- ll.panic("column name should not be provided for non-Xsv output")
656
+ ll.panic("column name should not be provided for non-Xsv/TsvContent output")
539
657
  }
540
658
  return {
541
659
  data: renderResult.output(name),
@@ -556,8 +674,8 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
556
674
  ll.panic("unknown output: " + name)
557
675
  }
558
676
 
559
- if output.type != "Xsv" {
560
- ll.panic("outputFrame can only be used with Xsv outputs")
677
+ if output.type != "Xsv" && output.type != "TsvContent" {
678
+ ll.panic("outputFrame can only be used with Xsv or TsvContent outputs")
561
679
  }
562
680
 
563
681
  builder := builder.pFrameBuilder()
@@ -581,7 +699,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
581
699
  }
582
700
 
583
701
  maps.forEach(outputsMap, func(name, output) {
584
- if output.type == "Xsv" {
702
+ if output.type == "Xsv" || output.type == "TsvContent" {
585
703
 
586
704
  for columnName, spec in outputSpecs[name] {
587
705
  builder.add(
@@ -649,8 +767,8 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
649
767
  if is_undefined(output) {
650
768
  ll.panic("unknown output: " + name)
651
769
  }
652
- if output.type != "Xsv" {
653
- ll.panic("output is not Xsv: " + name)
770
+ if output.type != "Xsv" && output.type != "TsvContent" {
771
+ ll.panic("output is not Xsv or TsvContent: " + name)
654
772
  }
655
773
 
656
774
  return maps.getKeys(outputSpecs[name])
@@ -258,10 +258,44 @@ makeTrace := func(input, ...steps) {
258
258
  return ll.toStrict({
259
259
  value: currentTrace,
260
260
  valueStr: currentTraceStr,
261
-
262
- inject: func(spec) {
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+ inject: func(spec, ...opts) {
263
274
  validation.assertType(spec, P_COLUMN_SPEC_SCHEMA)
264
- return maps.deepMerge(spec, {annotations: {"pl7.app/trace": currentTraceStr}})
275
+
276
+
277
+ options := {}
278
+ if len(opts) > 0 {
279
+ if len(opts) == 1 && is_map(opts[0]) {
280
+ options = opts[0]
281
+ } else {
282
+ ll.panic("inject: optional parameters must be a single map argument, got: %v", opts)
283
+ }
284
+ }
285
+
286
+
287
+ override := options.override
288
+ if is_undefined(override) {
289
+ override = true
290
+ }
291
+
292
+ return maps.deepTransform(spec, {annotations: {"pl7.app/trace": func(oldValue) {
293
+
294
+ if override || is_undefined(oldValue) {
295
+ return currentTraceStr
296
+ }
297
+ return oldValue
298
+ }}})
265
299
  }
266
300
  })
267
301
  }
@@ -310,7 +310,7 @@ normalize := func(s) {
310
310
  if is_undefined(s) {
311
311
  return []
312
312
  }
313
- return s
313
+ return copy(s)
314
314
  }
315
315
 
316
316
  export ll.toStrict({
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/workflow-tengo",
3
- "version": "4.12.0",
3
+ "version": "4.13.0",
4
4
  "description": "Tengo SDK library",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",