@platforma-sdk/workflow-tengo 4.7.0 → 4.7.2
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/dist/tengo/lib/feats.lib.tengo +7 -1
- package/dist/tengo/lib/ll.lib.tengo +138 -1
- package/dist/tengo/lib/smart.lib.tengo +71 -1
- package/dist/tengo/lib/tpl.base.lib.tengo +3 -2
- package/dist/tengo/lib/tpl.state-await.lib.tengo +88 -29
- package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
- package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
- package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
- package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
- package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
- package/package.json +2 -2
|
@@ -37,5 +37,11 @@ export ll.toStrict({
|
|
|
37
37
|
pureFutureFields: _isEnabled("pureFutureFields") || _api >= 1, // 'pure' future fields magic that provides deduplication
|
|
38
38
|
commandExpressions: _isEnabled("commandExpressions") || _api >= 2, // rich expressions in command arguments ( {{ system.ram_bytes / 20 }} )
|
|
39
39
|
workdirLimits: _isEnabled("workdirLimits") || _api >= 4, // workdir storage controller can limit concurrency
|
|
40
|
-
computeLimits: _isEnabled("computeLimits")
|
|
40
|
+
computeLimits: _isEnabled("computeLimits"), // runner can plan CPU and RAM
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
fullFeaturedApi: _isEnabled("fullFeaturedAPI")
|
|
41
47
|
})
|
|
@@ -289,10 +289,137 @@ parseUrl := func(url) {
|
|
|
289
289
|
|
|
290
290
|
|
|
291
291
|
|
|
292
|
+
|
|
293
|
+
|
|
292
294
|
getCtx := func() {
|
|
295
|
+
if methodExists(plapi, "getPersistentCtx") {
|
|
296
|
+
return plapi.getPersistentCtx()
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
return plapi.getCtx()
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
getPersistentCtx := func() {
|
|
308
|
+
if methodExists(plapi, "getPersistentCtx") {
|
|
309
|
+
return plapi.getPersistentCtx()
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
|
|
293
313
|
return plapi.getCtx()
|
|
294
314
|
}
|
|
295
315
|
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
getExecutionCtx := func() {
|
|
327
|
+
assert(methodExists(plapi, "getExecutionCtx"), "ll.getExecutionCtx: method does not exists in this backend instance.")
|
|
328
|
+
return plapi.getExecutionCtx()
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
moduleVars := func(moduleName) {
|
|
338
|
+
assert(is_string(moduleName), "ll.moduleVars: moduleName must be a string")
|
|
339
|
+
|
|
340
|
+
name := "module/" + moduleName
|
|
341
|
+
|
|
342
|
+
ctx := getExecutionCtx()
|
|
343
|
+
if is_undefined(ctx[name]) {
|
|
344
|
+
ctx[name] = {}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
get: func(k) {
|
|
349
|
+
return ctx[name][k]
|
|
350
|
+
},
|
|
351
|
+
|
|
352
|
+
set: func(k, v) {
|
|
353
|
+
ctx[name][k] = v
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
sha256Encode := func(b) {
|
|
362
|
+
assert(methodExists(plapi, "sha256Encode"), "ll.sha256Encode: method does not exists in this backend instance.")
|
|
363
|
+
return plapi.sha256Encode(b)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
gzipEncode := func(b) {
|
|
370
|
+
assert(methodExists(plapi, "gzipEncode"), "ll.gzipEncode: method does not exists in this backend instance.")
|
|
371
|
+
return plapi.gzipEncode(b)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
gzipDecode := func(b) {
|
|
378
|
+
assert(methodExists(plapi, "gzipDecode"), "ll.gzipDecode: method does not exists in this backend instance.")
|
|
379
|
+
return plapi.gzipDecode(b)
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
base32Encode := func(b) {
|
|
386
|
+
assert(methodExists(plapi, "base32Encode"), "ll.base32Encode: method does not exists in this backend instance.")
|
|
387
|
+
return plapi.base32Encode(b)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
base32HexEncode := func(b) {
|
|
398
|
+
assert(methodExists(plapi, "base32HexEncode"), "ll.base32HexEncode: method does not exists in this backend instance.")
|
|
399
|
+
return plapi.base32HexEncode(b)
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
base32Decode := func(s) {
|
|
406
|
+
assert(methodExists(plapi, "base32Decode"), "ll.base32Decode: method does not exists in this backend instance.")
|
|
407
|
+
return plapi.base32Decode(s)
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
base32HexDecode := func(s) {
|
|
418
|
+
assert(methodExists(plapi, "base32HexDecode"), "ll.base32HexDecode: method does not exists in this backend instance.")
|
|
419
|
+
return plapi.base32HexDecode(s)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
|
|
296
423
|
export toStrict({
|
|
297
424
|
apiVersion: apiVersion,
|
|
298
425
|
print: print,
|
|
@@ -315,5 +442,15 @@ export toStrict({
|
|
|
315
442
|
pathSeparator: pathSeparator,
|
|
316
443
|
filepathCanonize: filepathCanonize,
|
|
317
444
|
parseUrl: parseUrl,
|
|
318
|
-
getCtx: getCtx
|
|
445
|
+
getCtx: getCtx,
|
|
446
|
+
getPersistentCtx: getPersistentCtx,
|
|
447
|
+
getExecutionCtx: getExecutionCtx,
|
|
448
|
+
moduleVars: moduleVars,
|
|
449
|
+
sha256Encode: sha256Encode,
|
|
450
|
+
gzipEncode: gzipEncode,
|
|
451
|
+
gzipDecode: gzipDecode,
|
|
452
|
+
base32Encode: base32Encode,
|
|
453
|
+
base32HexEncode: base32HexEncode,
|
|
454
|
+
base32Decode: base32Decode,
|
|
455
|
+
base32HexDecode: base32HexDecode
|
|
319
456
|
})
|
|
@@ -362,6 +362,13 @@ resource = func(r) {
|
|
|
362
362
|
|
|
363
363
|
|
|
364
364
|
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
|
|
365
372
|
|
|
366
373
|
|
|
367
374
|
|
|
@@ -390,7 +397,14 @@ resource = func(r) {
|
|
|
390
397
|
|
|
391
398
|
|
|
392
399
|
isFinal: func() {
|
|
393
|
-
|
|
400
|
+
|
|
401
|
+
if false {
|
|
402
|
+
return self.info().IsFinal
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
info := self.info()
|
|
406
|
+
|
|
407
|
+
return info.ResourceReady || info.IsDuplicate || info.HasErrors
|
|
394
408
|
},
|
|
395
409
|
|
|
396
410
|
isEphemeral: func() {
|
|
@@ -685,6 +699,24 @@ resource = func(r) {
|
|
|
685
699
|
|
|
686
700
|
|
|
687
701
|
|
|
702
|
+
createDynamicField: func(name) {
|
|
703
|
+
if is_bytes(name) {
|
|
704
|
+
name = string(name)
|
|
705
|
+
}
|
|
706
|
+
ll.assert(is_string(name) && name != "", "field name must be a non-empty string")
|
|
707
|
+
fid := ll.fieldId(self.id, name)
|
|
708
|
+
tx.createField(fid, constants.FTYPE_DYNAMIC)
|
|
709
|
+
return field(fid)
|
|
710
|
+
},
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
|
|
688
720
|
|
|
689
721
|
kvGet: func(key) {
|
|
690
722
|
return tx.resourceKeyValueGet(self.id, key)
|
|
@@ -696,6 +728,17 @@ resource = func(r) {
|
|
|
696
728
|
|
|
697
729
|
|
|
698
730
|
|
|
731
|
+
kvGetFlag: func(key) {
|
|
732
|
+
ll.assert(feats.fullFeaturedApi, "smart.resource.kvGetFlag: the feature is not available on older backends. Please, update the backend.")
|
|
733
|
+
return tx.resourceKeyValueGetFlag(self.id, key)
|
|
734
|
+
},
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
|
|
699
742
|
|
|
700
743
|
kvSet: func(key, value) {
|
|
701
744
|
tx.resourceKeyValueSet(self.id, key, value)
|
|
@@ -707,6 +750,17 @@ resource = func(r) {
|
|
|
707
750
|
|
|
708
751
|
|
|
709
752
|
|
|
753
|
+
kvSetFlag: func(key, flag) {
|
|
754
|
+
ll.assert(feats.fullFeaturedApi, "smart.resource.kvSetFlag: the feature is not available on older backends. Please, update the backend.")
|
|
755
|
+
tx.resourceKeyValueSetFlag(self.id, key, flag)
|
|
756
|
+
},
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
710
764
|
|
|
711
765
|
kvGetAsString: func(key) {
|
|
712
766
|
value := tx.resourceKeyValueGet(self.id, key)
|
|
@@ -1092,6 +1146,22 @@ field = func(f) {
|
|
|
1092
1146
|
|
|
1093
1147
|
buildFutureField: func(nameOrPath) {
|
|
1094
1148
|
return _buildFutureField(strictSelf, nameOrPath)
|
|
1149
|
+
},
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
reset: func() {
|
|
1155
|
+
ll.assert(feats.fullFeaturedApi, "smart.field.reset: the feature is not available on older backends. Please, update the backend.")
|
|
1156
|
+
tx.resetField(self.id)
|
|
1157
|
+
},
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
|
|
1162
|
+
remove: func() {
|
|
1163
|
+
ll.assert(feats.fullFeaturedApi, "smart.field.remove: the feature is not available on older backends. Please, update the backend.")
|
|
1164
|
+
tx.removeField(self.id)
|
|
1095
1165
|
}
|
|
1096
1166
|
}
|
|
1097
1167
|
|
|
@@ -102,7 +102,8 @@ AWAIT_TEMPLATES := {
|
|
|
102
102
|
"PColumnBundleWithPartitions": [
|
|
103
103
|
[{ wildcard: "*" }, { match: "^ref$" }, "ResourceReady"], // optional ref field
|
|
104
104
|
[{ wildcard: "*" }, "spec", "ResourceReady"],
|
|
105
|
-
[{ wildcard: "*" }, "data", "InputsLocked"]
|
|
105
|
+
[{ wildcard: "*" }, "data", "InputsLocked"],
|
|
106
|
+
[{ wildcard: "*" }, "data", { match: "^\\{.*\\}$" }, "InputsLocked"] // for multi-hit BQuery results; key is always ref
|
|
106
107
|
]
|
|
107
108
|
}
|
|
108
109
|
|
|
@@ -568,7 +569,7 @@ tpl := func(ops) {
|
|
|
568
569
|
if _hasPrepared {
|
|
569
570
|
_stateRequests = append(_stateRequests, {
|
|
570
571
|
path: [tplutil.PREPARE_MAP_FIELD_NAME],
|
|
571
|
-
state: "
|
|
572
|
+
state: "Final"
|
|
572
573
|
})
|
|
573
574
|
}
|
|
574
575
|
|
|
@@ -7,6 +7,9 @@ tx := import("tx")
|
|
|
7
7
|
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
8
8
|
text := import("text")
|
|
9
9
|
regexp := import("@platforma-sdk/workflow-tengo:regexp")
|
|
10
|
+
smart := import("@platforma-sdk/workflow-tengo:smart")
|
|
11
|
+
maps := import("@platforma-sdk/workflow-tengo:maps")
|
|
12
|
+
feats := import("@platforma-sdk/workflow-tengo:feats")
|
|
10
13
|
|
|
11
14
|
createContext := func() {
|
|
12
15
|
return {
|
|
@@ -15,6 +18,9 @@ createContext := func() {
|
|
|
15
18
|
}
|
|
16
19
|
}
|
|
17
20
|
|
|
21
|
+
|
|
22
|
+
RTYPE_AWAITER := { Name: "awaiter", Version: "1" }
|
|
23
|
+
|
|
18
24
|
awaitOneState := func(field, path, state) {
|
|
19
25
|
if field.isErrorSet() && !field.isValueSet() {
|
|
20
26
|
|
|
@@ -51,9 +57,6 @@ awaitOneState := func(field, path, state) {
|
|
|
51
57
|
subscriptions: [{
|
|
52
58
|
resource: resource.id,
|
|
53
59
|
event: "FieldCreated"
|
|
54
|
-
},{
|
|
55
|
-
resource: resource.id,
|
|
56
|
-
event: "InputsLocked"
|
|
57
60
|
}]
|
|
58
61
|
}
|
|
59
62
|
}
|
|
@@ -93,19 +96,19 @@ awaitOneState := func(field, path, state) {
|
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
subscriptions := []
|
|
96
|
-
|
|
99
|
+
maps.forEach(resource.inputs(), func(nextFieldName, nextField) {
|
|
97
100
|
if !matcher(nextFieldName) {
|
|
98
|
-
|
|
101
|
+
return
|
|
99
102
|
}
|
|
100
103
|
res := awaitOneState(nextField, rPath, state)
|
|
101
104
|
if res.type == "Ready" {
|
|
102
|
-
|
|
105
|
+
return
|
|
103
106
|
} else if res.type == "Subscribe" {
|
|
104
107
|
subscriptions = append(subscriptions, res.subscriptions...)
|
|
105
108
|
} else {
|
|
106
109
|
ll.panic("Unknown result type: %v", res.type)
|
|
107
110
|
}
|
|
108
|
-
}
|
|
111
|
+
})
|
|
109
112
|
if len(subscriptions) == 0 {
|
|
110
113
|
return { type: "Ready" }
|
|
111
114
|
} else {
|
|
@@ -157,7 +160,7 @@ awaitOneState := func(field, path, state) {
|
|
|
157
160
|
}]
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
|
-
} else if state == "ResourceReady" {
|
|
163
|
+
} else if state == "ResourceReady" || state == "Final" {
|
|
161
164
|
|
|
162
165
|
|
|
163
166
|
if resource.isFinal() {
|
|
@@ -167,7 +170,7 @@ awaitOneState := func(field, path, state) {
|
|
|
167
170
|
type: "Subscribe",
|
|
168
171
|
subscriptions: [{
|
|
169
172
|
resource: resource.id,
|
|
170
|
-
event: "
|
|
173
|
+
event: "Final" // will also effectively subscribe to ResourceDuplicate and ResourceError
|
|
171
174
|
}]
|
|
172
175
|
}
|
|
173
176
|
}
|
|
@@ -178,19 +181,21 @@ awaitOneState := func(field, path, state) {
|
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
183
|
|
|
184
|
+
_renderer := smart.resource(ll.getCurrentTemplateRenderer())
|
|
185
|
+
|
|
181
186
|
|
|
182
187
|
await := func(rootField, ctxStorageResource, requests) {
|
|
183
188
|
pssKey := "await:" + string(rootField.id.ResourceID) + ":" + rootField.id.Name
|
|
184
189
|
prevSubscriptions := ctxStorageResource.kvGetAsJson(pssKey)
|
|
185
190
|
|
|
186
|
-
|
|
191
|
+
lastSubscriptionKey := undefined
|
|
192
|
+
if !is_undefined(prevSubscriptions) {
|
|
193
|
+
if is_undefined(prevSubscriptions.lastSubscriptionKey) {
|
|
187
194
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
prevSubscriptions = {}
|
|
195
|
+
ll.panic("Unexpected state, desired state was reached in the previous call")
|
|
196
|
+
} else {
|
|
197
|
+
lastSubscriptionKey = prevSubscriptions.lastSubscriptionKey
|
|
198
|
+
}
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
subscriptions := {}
|
|
@@ -222,34 +227,88 @@ await := func(rootField, ctxStorageResource, requests) {
|
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
|
|
225
|
-
for key, sub in subscriptions {
|
|
226
|
-
if !is_undefined(prevSubscriptions[key]) {
|
|
227
230
|
|
|
228
|
-
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
firstSubscriptionKey := undefined
|
|
238
|
+
firstSubscription := undefined
|
|
239
|
+
lastSubscriptionKeyPresent := false
|
|
240
|
+
maps.forEach(subscriptions, func(key, sub) {
|
|
241
|
+
if is_undefined(firstSubscriptionKey) {
|
|
242
|
+
firstSubscriptionKey = key
|
|
243
|
+
firstSubscription = sub
|
|
229
244
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
245
|
+
if !is_undefined(lastSubscriptionKey) && lastSubscriptionKey == key {
|
|
246
|
+
lastSubscriptionKeyPresent = true
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
if lastSubscriptionKeyPresent {
|
|
253
|
+
return false
|
|
233
254
|
}
|
|
234
255
|
|
|
235
256
|
|
|
236
|
-
|
|
237
|
-
if !is_undefined(subscriptions[key]) {
|
|
257
|
+
if !is_undefined(firstSubscriptionKey) {
|
|
238
258
|
|
|
239
|
-
|
|
259
|
+
fullEventId := pssKey + ":" + firstSubscriptionKey
|
|
260
|
+
targetResource := firstSubscription.resource
|
|
261
|
+
targetEvents := [firstSubscription.event]
|
|
262
|
+
|
|
263
|
+
if firstSubscription.event == "Final" { // special case
|
|
264
|
+
if !feats.fullFeaturedApi {
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
target := smart.resource(targetResource)
|
|
272
|
+
isEphemeral := target.info().Features.ephemeral
|
|
273
|
+
if !isEphemeral { // doing proxy-object workaround for pure resources only
|
|
274
|
+
awaiterBuilder := smart.ephemeralBuilder(RTYPE_AWAITER)
|
|
275
|
+
awaiterBuilder.createInputField("target").set(target)
|
|
276
|
+
awaiter := awaiterBuilder.lockAndBuild()
|
|
277
|
+
_renderer.createDynamicField("tmp:" + fullEventId).set(awaiter)
|
|
278
|
+
targetResource = awaiter.info().ID // converting to global resource id; this is a hack to overcome the fact that tx.subscribeTo can't work with local ids
|
|
279
|
+
}
|
|
280
|
+
targetEvents = ["ResourceReady", "ResourceError"]
|
|
281
|
+
|
|
282
|
+
} else {
|
|
283
|
+
targetEvents = ["ResourceReady", "ResourceError", "ResourceDuplicate"]
|
|
284
|
+
}
|
|
285
|
+
} else if firstSubscription.event == "FieldCreated" { // another special case
|
|
286
|
+
|
|
287
|
+
targetEvents = ["FieldCreated", "InputsLocked"]
|
|
240
288
|
}
|
|
241
|
-
|
|
289
|
+
|
|
290
|
+
e := {}
|
|
291
|
+
for event in targetEvents {
|
|
292
|
+
e[event] = true
|
|
293
|
+
}
|
|
294
|
+
tx.subscribeTo(targetResource, fullEventId, e)
|
|
295
|
+
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
if !is_undefined(lastSubscriptionKey) {
|
|
300
|
+
tx.unsubscribeFrom(pssKey + ":" + lastSubscriptionKey)
|
|
242
301
|
}
|
|
243
302
|
|
|
244
303
|
|
|
245
304
|
newPrevSubscriptions := {}
|
|
246
|
-
|
|
247
|
-
newPrevSubscriptions
|
|
305
|
+
if !is_undefined(firstSubscriptionKey) {
|
|
306
|
+
newPrevSubscriptions.lastSubscriptionKey = firstSubscriptionKey
|
|
248
307
|
}
|
|
249
308
|
|
|
250
309
|
ctxStorageResource.kvSetJson(pssKey, newPrevSubscriptions)
|
|
251
310
|
|
|
252
|
-
return
|
|
311
|
+
return is_undefined(firstSubscriptionKey)
|
|
253
312
|
}
|
|
254
313
|
|
|
255
314
|
export ll.toStrict({
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
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.7.
|
|
3
|
+
"version": "4.7.2",
|
|
4
4
|
"description": "Tengo SDK library",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"@platforma-open/milaboratories.software-ptabler": "1.6.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@platforma-sdk/tengo-builder": "^2.1.
|
|
24
|
+
"@platforma-sdk/tengo-builder": "^2.1.8"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"type-check": "pl-tengo check",
|