@platforma-sdk/workflow-tengo 2.8.4 → 2.8.6

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 (58) hide show
  1. package/dist/tengo/lib/assets.lib.tengo +6 -0
  2. package/dist/tengo/lib/constants.lib.tengo +3 -0
  3. package/dist/tengo/lib/exec.R.lib.tengo +8 -0
  4. package/dist/tengo/lib/exec.internal.lib.tengo +12 -0
  5. package/dist/tengo/lib/exec.lib.tengo +67 -0
  6. package/dist/tengo/lib/exec.package.lib.tengo +9 -0
  7. package/dist/tengo/lib/exec.python.internal.lib.tengo +1 -0
  8. package/dist/tengo/lib/exec.python.lib.tengo +8 -0
  9. package/dist/tengo/lib/exec.runcmd.lib.tengo +19 -0
  10. package/dist/tengo/lib/exec.runenv.lib.tengo +4 -0
  11. package/dist/tengo/lib/exec.stream.lib.tengo +4 -0
  12. package/dist/tengo/lib/file.internal.lib.tengo +7 -0
  13. package/dist/tengo/lib/file.lib.tengo +3 -0
  14. package/dist/tengo/lib/ll.lib.tengo +24 -0
  15. package/dist/tengo/lib/maps.lib.tengo +8 -0
  16. package/dist/tengo/lib/objects.lib.tengo +2 -0
  17. package/dist/tengo/lib/oop.lib.tengo +3 -0
  18. package/dist/tengo/lib/path.lib.tengo +9 -0
  19. package/dist/tengo/lib/pframes.constants.lib.tengo +3 -0
  20. package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +5 -0
  21. package/dist/tengo/lib/pframes.lib.tengo +5 -0
  22. package/dist/tengo/lib/pframes.ll.lib.tengo +2 -0
  23. package/dist/tengo/lib/pframes.pcolumn.lib.tengo +4 -0
  24. package/dist/tengo/lib/pframes.spec.lib.tengo +26 -0
  25. package/dist/tengo/lib/pframes.util.lib.tengo +134 -0
  26. package/dist/tengo/lib/pframes.xsv.lib.tengo +12 -0
  27. package/dist/tengo/lib/render.lib.tengo +10 -0
  28. package/dist/tengo/lib/sets.lib.tengo +7 -0
  29. package/dist/tengo/lib/slices.lib.tengo +11 -0
  30. package/dist/tengo/lib/smart.lib.tengo +114 -1
  31. package/dist/tengo/lib/test.lib.tengo +32 -0
  32. package/dist/tengo/lib/tpl.lib.tengo +68 -0
  33. package/dist/tengo/lib/tpl.state-await.lib.tengo +14 -0
  34. package/dist/tengo/lib/tpl.util.lib.tengo +5 -0
  35. package/dist/tengo/lib/validation.lib.tengo +44 -0
  36. package/dist/tengo/lib/workdir.lib.tengo +22 -0
  37. package/dist/tengo/lib/workdir.proc.lib.tengo +18 -0
  38. package/dist/tengo/lib/workdir.save.lib.tengo +17 -0
  39. package/dist/tengo/lib/workflow.bobject.lib.tengo +5 -0
  40. package/dist/tengo/lib/workflow.bquery.lib.tengo +25 -0
  41. package/dist/tengo/lib/workflow.constants.lib.tengo +1 -0
  42. package/dist/tengo/lib/workflow.context.lib.tengo +5 -0
  43. package/dist/tengo/lib/workflow.lib.tengo +39 -0
  44. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  45. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  46. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  47. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  48. package/dist/tengo/tpl/pframes.aggregate.plj.gz +0 -0
  49. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  50. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  51. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  52. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  53. package/dist/tengo/tpl/pframes.map-pframe.plj.gz +0 -0
  54. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  55. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  56. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  57. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  58. package/package.json +3 -3
@@ -6,6 +6,7 @@
6
6
 
7
7
 
8
8
 
9
+
9
10
  test := import("test")
10
11
 
11
12
 
@@ -14,6 +15,10 @@ test := import("test")
14
15
 
15
16
 
16
17
 
18
+
19
+
20
+
21
+
17
22
  skip := func(...args) {
18
23
  test.skip(args...)
19
24
  }
@@ -23,6 +28,7 @@ test.skip(args...)
23
28
 
24
29
 
25
30
 
31
+
26
32
  skipf := func(msg, ...args) {
27
33
  skip(format(msg, args...))
28
34
  }
@@ -33,6 +39,7 @@ skip(format(msg, args...))
33
39
 
34
40
 
35
41
 
42
+
36
43
  fail := func(...args) {
37
44
  test.fail(args...)
38
45
  }
@@ -42,6 +49,7 @@ test.fail(args...)
42
49
 
43
50
 
44
51
 
52
+
45
53
  failf := func(msg, ...args) {
46
54
  fail(format(msg, args...))
47
55
  }
@@ -51,6 +59,7 @@ fail(format(msg, args...))
51
59
 
52
60
 
53
61
 
62
+
54
63
  log := func(...args) {
55
64
  test.log(args...)
56
65
  }
@@ -60,6 +69,7 @@ test.log(args...)
60
69
 
61
70
 
62
71
 
72
+
63
73
  logf := func(msg, ...args) {
64
74
  test.log(format(msg, args...))
65
75
  }
@@ -78,6 +88,7 @@ test.log(format(msg, args...))
78
88
 
79
89
 
80
90
 
91
+
81
92
  done := func() {
82
93
  test.done()
83
94
  }
@@ -88,6 +99,10 @@ test.done()
88
99
 
89
100
 
90
101
 
102
+
103
+
104
+
105
+
91
106
  isTrue := func(condition, ...msg) {
92
107
  if !condition {
93
108
  test.fail("<condition> != 'true': ", msg...)
@@ -100,6 +115,7 @@ test.fail("<condition> != 'true': ", msg...)
100
115
 
101
116
 
102
117
 
118
+
103
119
  isTruef := func(condition, msg, ...args) {
104
120
  isTrue(condition, format(msg, args...))
105
121
  }
@@ -109,6 +125,7 @@ isTrue(condition, format(msg, args...))
109
125
 
110
126
 
111
127
 
128
+
112
129
  isFalse := func(condition, ...args) {
113
130
  if condition {
114
131
  test.fail("<condition> != 'false'", args...)
@@ -121,6 +138,7 @@ test.fail("<condition> != 'false'", args...)
121
138
 
122
139
 
123
140
 
141
+
124
142
  isFalsef := func(condition, msg, ...args) {
125
143
  isFalse(condition, format(msg, args...))
126
144
  }
@@ -132,6 +150,10 @@ isFalse(condition, format(msg, args...))
132
150
 
133
151
 
134
152
 
153
+
154
+
155
+
156
+
135
157
  isEqual := func(expect, value, ...args) {
136
158
  if expect == value {
137
159
  return
@@ -149,11 +171,15 @@ fail(msg, args...)
149
171
 
150
172
 
151
173
 
174
+
152
175
  isEqualf := func(expect, value, msg, ...args) {
153
176
  isEqual(expect, value, format(msg, args...))
154
177
  }
155
178
 
156
179
  export {
180
+
181
+
182
+
157
183
  done : done,
158
184
  skip : skip,
159
185
  skipf : skipf,
@@ -162,11 +188,17 @@ failf : failf,
162
188
  log : log,
163
189
  logf : logf,
164
190
 
191
+
192
+
193
+
165
194
  isTrue : isTrue,
166
195
  isTruef : isTruef,
167
196
  isFalse : isFalse,
168
197
  isFalsef : isFalsef,
169
198
 
199
+
200
+
201
+
170
202
  isEqual : isEqual,
171
203
  isEqualf : isEqualf
172
204
  }
@@ -1,4 +1,5 @@
1
1
 
2
+
2
3
  tx := import("tx")
3
4
  ll := import("@platforma-sdk/workflow-tengo:ll")
4
5
  render := import("@platforma-sdk/workflow-tengo:render")
@@ -20,11 +21,14 @@ bquery := import("@platforma-sdk/workflow-tengo:workflow.bquery")
20
21
 
21
22
 
22
23
 
24
+
23
25
  _unmarshal := func(resource, preprocessors) {
24
26
  ll.assert(smart.isResource(resource), "expected resource, found ", resource)
25
27
 
28
+
26
29
  self := func(resource) { return _unmarshal(resource, preprocessors) }
27
30
 
31
+
28
32
  for preproc in preprocessors {
29
33
  if preproc.canParse(resource) {
30
34
  return preproc.parse(resource, self)
@@ -37,9 +41,11 @@ ll.panic("input resource has errors: ", resource, resource.getError())
37
41
 
38
42
  if smart.isJsonResource(resource) || resource.checkResourceType(constants.RTYPE_BOBJECT_SPEC) {
39
43
 
44
+
40
45
  return resource.getDataAsJson()
41
46
  } else if smart.isMapResource(resource) || smart.isLockedEphMapResource(resource) {
42
47
 
48
+
43
49
  result := {}
44
50
  for field, value in resource.inputs() {
45
51
  if value.isErrorSet() {
@@ -53,12 +59,14 @@ result[field] = value
53
59
  }
54
60
  return result
55
61
  } else {
62
+
56
63
  return resource
57
64
  }
58
65
  }
59
66
 
60
67
 
61
68
 
69
+
62
70
  tpl := func() {
63
71
  self := undefined
64
72
 
@@ -81,18 +89,21 @@ self = {
81
89
 
82
90
 
83
91
 
92
+
84
93
  renderer: func() {
85
94
  return _renderer
86
95
  },
87
96
 
88
97
 
89
98
 
99
+
90
100
  isEphemeral: func() {
91
101
  return _isEphemeral
92
102
  },
93
103
 
94
104
 
95
105
 
106
+
96
107
  template: func() {
97
108
  return smart.resource(_templateId)
98
109
  },
@@ -103,6 +114,7 @@ _unmarshallers: [bquery.resultUnmarshaller()],
103
114
 
104
115
 
105
116
 
117
+
106
118
  registerUnmarshaller: func(preproc) {
107
119
  ll.assert(is_undefined(self._inputs), "input preprocessors must be registered before getting inputs")
108
120
  self._unmarshallers = append(self._unmarshallers, preproc)
@@ -110,6 +122,7 @@ self._unmarshallers = append(self._unmarshallers, preproc)
110
122
 
111
123
 
112
124
 
125
+
113
126
  rawInputs: func() {
114
127
  return self.renderer().get(tplutil.INPUTS_MAP_FIELD).inputs()
115
128
  },
@@ -118,10 +131,12 @@ _inputs: undefined,
118
131
 
119
132
 
120
133
 
134
+
121
135
  inputs: func() {
122
136
  if self._inputs == undefined {
123
137
  inputs := _unmarshal(self.renderer().get(tplutil.INPUTS_MAP_FIELD), self._unmarshallers)
124
138
 
139
+
125
140
  pp := inputs[tplutil.PREPARE_MAP_FIELD_NAME]
126
141
  if !is_undefined(pp) {
127
142
  delete(inputs, tplutil.PREPARE_MAP_FIELD_NAME)
@@ -138,10 +153,12 @@ return self._inputs
138
153
 
139
154
 
140
155
 
156
+
141
157
  hasInput: func(name) {
142
158
  return self.renderer().get(tplutil.INPUTS_MAP_FIELD).hasField(name)
143
159
  },
144
160
 
161
+
145
162
  definedOutputs : [],
146
163
 
147
164
 
@@ -149,6 +166,7 @@ definedOutputs : [],
149
166
 
150
167
 
151
168
 
169
+
152
170
  defineOutputs : func(...name) {
153
171
  if len(name) == 1 && is_array(name[0]) {
154
172
  for v in name[0] {
@@ -189,6 +207,7 @@ self.definedOutputs = append(self.definedOutputs, name...)
189
207
 
190
208
 
191
209
 
210
+
192
211
 
193
212
 
194
213
  awaitState: func(...pathAndState) {
@@ -197,25 +216,37 @@ ll.panic("awaitState allowed only in ephemeral templates")
197
216
  }
198
217
  path := pathAndState[:len(pathAndState) - 1]
199
218
  state := pathAndState[len(pathAndState) - 1]
219
+
200
220
  _stateRequests = append(_stateRequests, {
201
221
  path: path,
202
222
  state: state
203
223
  })
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
204
232
  },
205
233
 
206
234
 
207
235
 
208
236
 
237
+
209
238
  ignorePrepare: _hasPrepared,
210
239
 
211
240
 
212
241
 
242
+
213
243
  preparedMapResource: func() {
214
244
  return _preparedMap
215
245
  },
216
246
 
217
247
 
218
248
 
249
+
219
250
  prepareQueue : [],
220
251
 
221
252
 
@@ -223,6 +254,7 @@ prepareQueue : [],
223
254
 
224
255
 
225
256
 
257
+
226
258
  prepare : func(codeFn) {
227
259
  if self.ignorePrepare {
228
260
  return
@@ -236,13 +268,16 @@ self.prepareQueue = append(self.prepareQueue, codeFn)
236
268
 
237
269
 
238
270
 
271
+
239
272
  renderPrepare: func() {
240
273
  ll.assert(!self.ignorePrepare, "expected !ignorePrepare")
241
274
 
242
275
  inputs := self.inputs()
243
276
 
277
+
244
278
  newInputs := copy(inputs)
245
279
 
280
+
246
281
  builder := undefined
247
282
  if self.isEphemeral() {
248
283
  builder = smart.ephemeralMapBuilder()
@@ -250,8 +285,10 @@ builder = smart.ephemeralMapBuilder()
250
285
  builder = smart.mapBuilder()
251
286
  }
252
287
 
288
+
253
289
  self._validateInputs()
254
290
  for cb in self.prepareQueue {
291
+
255
292
  r := cb(inputs)
256
293
 
257
294
  ll.assert(is_map(r), "expected map, got ", r)
@@ -264,12 +301,14 @@ builder.add(name, ref)
264
301
  }
265
302
  newInputs[tplutil.PREPARE_MAP_FIELD_NAME] = builder.build()
266
303
 
304
+
267
305
  renderer := undefined
268
306
  if self.isEphemeral() {
269
307
  renderer = render.createEphemeral(self.template(), newInputs)
270
308
  } else {
271
309
  renderer = render.create(self.template(), newInputs)
272
310
  }
311
+
273
312
  for output in self.definedOutputs {
274
313
  self.getOutputField(output).set(renderer.output(output))
275
314
  }
@@ -278,9 +317,11 @@ self.getOutputField(output).set(renderer.output(output))
278
317
 
279
318
 
280
319
 
320
+
281
321
  setOutputs : func(resultMap) {
282
322
  ll.assert(ll.isMap(resultMap), "expected map, got ", resultMap)
283
323
 
324
+
284
325
  for name, value in resultMap {
285
326
  f := self.getOutputField(name)
286
327
  if !f.isSet() {
@@ -291,12 +332,14 @@ f.setRefOrJson(value)
291
332
 
292
333
 
293
334
 
335
+
294
336
  getOutputField: func(name) {
295
337
  return self.renderer().getField(tplutil.TEMPLATE_OUTPUT_PREFIX + name)
296
338
  },
297
339
 
298
340
 
299
341
 
342
+
300
343
  createOutputsAndLock: func(outputs) {
301
344
  for name in outputs {
302
345
  self.renderer().createOutputField(tplutil.TEMPLATE_OUTPUT_PREFIX + name)
@@ -308,6 +351,7 @@ _inputsSchema: undefined,
308
351
 
309
352
 
310
353
 
354
+
311
355
  validateInputs: func(schema) {
312
356
  ll.assert(is_undefined(self._inputsSchema), "validateInputs was already invoked")
313
357
  self._inputsSchema = schema
@@ -323,6 +367,7 @@ validation.assertJsonSchema(self.inputs(), schema)
323
367
 
324
368
 
325
369
 
370
+
326
371
  body: func(bodyFn){
327
372
  if self.isEphemeral() {
328
373
 
@@ -335,21 +380,38 @@ self.routePure(bodyFn)
335
380
 
336
381
 
337
382
 
383
+
338
384
  routePure: func(bodyFn){
385
+
339
386
  if len(self.definedOutputs) == 0 {
340
387
  ll.panic("please define outputs before template body")
341
388
  }
342
389
 
343
390
 
391
+
392
+
393
+
394
+
395
+
396
+
397
+
398
+
399
+
400
+
401
+
344
402
  if ll.isInitializing() {
345
403
 
404
+
346
405
  self.createOutputsAndLock(self.definedOutputs)
347
406
  } else {
348
407
 
408
+
349
409
  if len(self.prepareQueue) != 0 {
350
410
 
411
+
351
412
  self.renderPrepare()
352
413
  } else {
414
+
353
415
  self._validateInputs()
354
416
  result := bodyFn(self.inputs())
355
417
 
@@ -363,6 +425,7 @@ ll.assert(sets.fromSlice(self.definedOutputs) == outputsWithValues,
363
425
  "tpl.body() callback must return the same list of outputs as were given to 'defineOutputs()'. Want %s, got %s",
364
426
  self.definedOutputs, sets.toSlice(outputsWithValues))
365
427
 
428
+
366
429
  self.setOutputs(result)
367
430
  }
368
431
  }
@@ -370,6 +433,7 @@ self.setOutputs(result)
370
433
 
371
434
 
372
435
 
436
+
373
437
  routeEph: func(bodyFn) {
374
438
 
375
439
  if len(_stateRequests) == 0 {
@@ -402,6 +466,7 @@ self.createOutputsAndLock(self.definedOutputs)
402
466
  self.renderPrepare()
403
467
  } else {
404
468
 
469
+
405
470
  self._validateInputs()
406
471
  result := bodyFn(self.inputs())
407
472
  ll.assert(ll.isMap(result),
@@ -409,6 +474,7 @@ ll.assert(ll.isMap(result),
409
474
 
410
475
  self.createOutputsAndLock(maps.getKeys(result))
411
476
 
477
+
412
478
  self.setOutputs(result)
413
479
  }
414
480
  }
@@ -421,6 +487,7 @@ self.setOutputs(result)
421
487
 
422
488
 
423
489
 
490
+
424
491
  routeDelegate: func(tpl, extraInputs, outputs) {
425
492
  _delegatedOutputs = outputs
426
493
 
@@ -450,6 +517,7 @@ return ll.toStrict(self)
450
517
 
451
518
 
452
519
 
520
+
453
521
  instance := tpl()
454
522
 
455
523
  export ll.toStrict({
@@ -2,6 +2,7 @@
2
2
 
3
3
 
4
4
 
5
+
5
6
  tx := import("tx")
6
7
  ll := import("@platforma-sdk/workflow-tengo:ll")
7
8
  text := import("text")
@@ -15,6 +16,10 @@ resolvedStates: {}
15
16
 
16
17
  awaitOneState := func(field, path, state) {
17
18
  if field.isErrorSet() && !field.isValueSet() {
19
+
20
+
21
+
22
+
18
23
  return { type: "Ready" }
19
24
  }
20
25
 
@@ -170,15 +175,18 @@ ll.panic("Unknown await state: %v", state)
170
175
  }
171
176
  }
172
177
 
178
+
173
179
  await := func(rootField, ctxStorageResource, requests) {
174
180
  pssKey := "await:" + string(rootField.id.ResourceID) + ":" + rootField.id.Name
175
181
  prevSubscriptions := ctxStorageResource.kvGetAsJson(pssKey)
176
182
 
177
183
  if !is_undefined(prevSubscriptions) && len(prevSubscriptions) == 0 {
184
+
178
185
  ll.panic("Unexpected state, desired state was reached in the previous call")
179
186
  }
180
187
 
181
188
  if is_undefined(prevSubscriptions) {
189
+
182
190
  prevSubscriptions = {}
183
191
  }
184
192
 
@@ -210,8 +218,10 @@ ll.panic("Unknown result type %v", res.type)
210
218
  }
211
219
  }
212
220
 
221
+
213
222
  for key, sub in subscriptions {
214
223
  if !is_undefined(prevSubscriptions[key]) {
224
+
215
225
  continue
216
226
  }
217
227
  e := {}
@@ -219,17 +229,21 @@ e[sub.event] = true
219
229
  tx.subscribeTo(sub.resource, pssKey + ":" + key, e)
220
230
  }
221
231
 
232
+
222
233
  for key, _ in prevSubscriptions {
223
234
  if !is_undefined(subscriptions[key]) {
235
+
224
236
  continue
225
237
  }
226
238
  tx.unsubscribeFrom(pssKey + ":" + key)
227
239
  }
228
240
 
241
+
229
242
  newPrevSubscriptions := {}
230
243
  for key, _ in subscriptions {
231
244
  newPrevSubscriptions[key] = true
232
245
  }
246
+
233
247
  ctxStorageResource.kvSetJson(pssKey, newPrevSubscriptions)
234
248
 
235
249
  return len(subscriptions) == 0
@@ -1,9 +1,14 @@
1
1
 
2
+
2
3
  ll := import("@platforma-sdk/workflow-tengo:ll")
3
4
 
5
+
4
6
  TEMPLATE_FIELD := "template"
7
+
5
8
  INPUTS_MAP_FIELD := "inputs"
9
+
6
10
  TEMPLATE_OUTPUT_PREFIX := "outputs/"
11
+
7
12
  PREPARE_MAP_FIELD_NAME := "__prepare__"
8
13
 
9
14
  export ll.toStrict({