@platforma-sdk/workflow-tengo 6.17.3 → 6.18.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 (59) hide show
  1. package/dist/index.cjs +2 -0
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/tengo/lib/pframes.bundle.lib.tengo +30 -5
  5. package/dist/tengo/lib/pframes.table-builder.lib.tengo +58 -17
  6. package/dist/tengo/lib/tpl.base.lib.tengo +1 -0
  7. package/dist/tengo/lib/v2.bquery.lib.tengo +9 -0
  8. package/dist/tengo/lib/v2.exports.lib.tengo +141 -0
  9. package/dist/tengo/lib/v2.node-rules.lib.tengo +102 -0
  10. package/dist/tengo/lib/v2.workflow.lib.tengo +281 -0
  11. package/dist/tengo/lib/workflow.bquery.lib.tengo +218 -26
  12. package/dist/tengo/tpl/annotations.compute.plj.gz +0 -0
  13. package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
  14. package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
  15. package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
  16. package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
  17. package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
  18. package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
  19. package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
  20. package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
  21. package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
  22. package/dist/tengo/tpl/exec.conda.create-env.plj.gz +0 -0
  23. package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
  24. package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
  25. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  26. package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
  27. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  28. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  29. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  30. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  31. package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
  32. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.build-table.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.export-parquet-pcolumn-chunk.plj.gz +0 -0
  36. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  37. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  38. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  39. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  40. package/dist/tengo/tpl/pframes.merge-resource-maps.plj.gz +0 -0
  41. package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
  42. package/dist/tengo/tpl/pframes.process-pcolumn-batch-split.plj.gz +0 -0
  43. package/dist/tengo/tpl/pframes.process-pcolumn-batch.plj.gz +0 -0
  44. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  45. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  46. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  47. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  48. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  49. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  50. package/dist/tengo/tpl/pt.import-dir.plj.gz +0 -0
  51. package/dist/tengo/tpl/pt.workflow-run.plj.gz +0 -0
  52. package/dist/tengo/tpl/v2.export-collection-for-ui.plj.gz +0 -0
  53. package/dist/tengo/tpl/v2.export-for-ui.plj.gz +0 -0
  54. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  55. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  56. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  57. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  58. package/dist/tengo/tpl/workflow.query-context-filter.plj.gz +0 -0
  59. package/package.json +2 -2
@@ -0,0 +1,281 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+ ll := import("@platforma-sdk/workflow-tengo:ll")
40
+ text := import("text")
41
+ smart := import("@platforma-sdk/workflow-tengo:smart")
42
+ sets := import("@platforma-sdk/workflow-tengo:sets")
43
+ oop := import("@platforma-sdk/workflow-tengo:oop")
44
+ bquery := import("@platforma-sdk/workflow-tengo:v2.bquery")
45
+ exports := import("@platforma-sdk/workflow-tengo:v2.exports")
46
+ pBundle := import("@platforma-sdk/workflow-tengo:pframes.bundle")
47
+ pTableBuilder := import("@platforma-sdk/workflow-tengo:pframes.table-builder")
48
+
49
+ self := import("@platforma-sdk/workflow-tengo:tpl")
50
+
51
+ _RESULT_OUTPUT := "result"
52
+ _EXPORTS_OUTPUT := "exports"
53
+ _INPUT_CONTEXT := "context"
54
+
55
+
56
+ _PREPARED_INPUTS_PREFIX := "prepared/"
57
+
58
+
59
+
60
+ self.defineOutputs([_RESULT_OUTPUT, _EXPORTS_OUTPUT])
61
+
62
+
63
+
64
+
65
+ isProduction := func() {
66
+ return self.rawInputs().isProduction.getValueAsJson() == true
67
+ }
68
+
69
+ _args := undefined
70
+
71
+
72
+
73
+
74
+ args := func() {
75
+ if is_undefined(_args) {
76
+ inputs := self.inputs()
77
+
78
+ _args = inputs.args
79
+ if is_undefined(_args) || smart.isReference(_args) {
80
+ ll.panic("Unexpected args type: %v", _args)
81
+ }
82
+
83
+ for k, v in inputs {
84
+ if text.has_prefix(k, _PREPARED_INPUTS_PREFIX) {
85
+ name := text.trim_prefix(k, _PREPARED_INPUTS_PREFIX)
86
+ ll.assert(is_undefined(_args[name]), "prepare name is already in use in inputs: %s", name)
87
+ _args[name] = v
88
+ }
89
+ }
90
+ }
91
+ return _args
92
+ }
93
+
94
+ _blockId := undefined
95
+
96
+
97
+
98
+
99
+ blockId := func() {
100
+ if is_undefined(_blockId) {
101
+ _blockId = self.inputs().blockId
102
+ ll.assert(!is_undefined(_blockId), "block id is not set in workflow inputs")
103
+ }
104
+ return _blockId
105
+ }
106
+
107
+
108
+
109
+
110
+ getBlockId := func() {
111
+ ret := blockId().getDataAsJson()
112
+ ll.assert(is_string(ret), "block id is not a string")
113
+ return ret
114
+ }
115
+
116
+ _parentContext := undefined
117
+
118
+
119
+
120
+
121
+
122
+ getParentBCtx := func() {
123
+ if is_undefined(_parentContext) {
124
+ _parentContext = self.inputs()[_INPUT_CONTEXT]
125
+ if is_undefined(_parentContext) {
126
+ ll.panic("parent context is not set in inputs")
127
+ }
128
+ }
129
+ return _parentContext
130
+ }
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+ query := func(spec, ...options) {
142
+ return bquery.create(spec, getParentBCtx(), options...)
143
+ }
144
+
145
+ _resolveOne := func(r, ...options) {
146
+ res := bquery.resolve(r, getParentBCtx(), options...)
147
+ return ll.toStrict(oop.inherit(res, {
148
+ spec: res.getFutureInputField("spec"),
149
+ data: res.getFutureInputField("data")
150
+ }))
151
+ }
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+ resolve := func(ref, ...options) {
161
+ return _resolveOne(ref, options...)
162
+ }
163
+
164
+
165
+
166
+
167
+
168
+ anchoredQuery := func(anchors, queryMap, ...opts) {
169
+ return bquery.anchoredQuery(getParentBCtx(), anchors, queryMap, opts...)
170
+ }
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+ prepare := func(cb) {
179
+ self.prepare(func(_) {
180
+ raw := cb(args())
181
+ prefixed := {}
182
+ for k, v in raw {
183
+ prefixed[_PREPARED_INPUTS_PREFIX + k] = v
184
+ }
185
+ return prefixed
186
+ })
187
+ }
188
+
189
+
190
+
191
+
192
+ validateArgs := func(argsSchema) {
193
+ self.validateInputs({
194
+ args: argsSchema
195
+ })
196
+ }
197
+
198
+
199
+
200
+
201
+
202
+ createPBundleBuilder := func() {
203
+ return pBundle.createBuilderWith(bquery, getParentBCtx())
204
+ }
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+ tableBuilder := func(format) {
216
+ return pTableBuilder.tableBuilderWith(bquery, format, getParentBCtx())
217
+ }
218
+
219
+
220
+
221
+
222
+ _assertOwnOutputs := func() {
223
+ defined := sets.fromSlice(self.definedOutputs())
224
+ if defined != sets.fromSlice([_RESULT_OUTPUT, _EXPORTS_OUTPUT]) {
225
+ ll.panic("a v2 workflow's outputs are exactly result and exports, but this template defines %v; " +
226
+ "is something it imports using @platforma-sdk/workflow-tengo:workflow?", sets.toSlice(defined))
227
+ }
228
+ }
229
+
230
+ _buildOutputs := func(results) {
231
+ ll.assert(ll.isMap(results) && !smart.isReference(results), "expected to see map result from body function")
232
+ ll.assert(
233
+ sets.fromSlice(["outputs", "exports"]) == sets.fromMapKeys(results),
234
+ "expected only outputs and exports in the returned map, found %v", sets.toSlice(sets.fromMapKeys(results))
235
+ )
236
+ ll.assert(ll.isMap(results.outputs) && !smart.isReference(results.outputs),
237
+ "expected a map in outputs returned from workflow.body")
238
+
239
+ exports.assertNode(results.exports, "exports")
240
+
241
+ resBuilder := smart.mapBuilder()
242
+ for name, value in results.outputs {
243
+ ll.assert(!is_undefined(value), "value is undefined for output %s", name)
244
+ resBuilder.add(name, value)
245
+ }
246
+
247
+ tplOutputs := {}
248
+ tplOutputs[_RESULT_OUTPUT] = resBuilder.build()
249
+ tplOutputs[_EXPORTS_OUTPUT] = results.exports
250
+ return tplOutputs
251
+ }
252
+
253
+
254
+
255
+
256
+
257
+
258
+
259
+ body := func(fn) {
260
+ _assertOwnOutputs()
261
+ self.body(func(_) {
262
+ return _buildOutputs(fn(args()))
263
+ })
264
+ }
265
+
266
+ export ll.toStrict({
267
+ getParentBCtx: getParentBCtx,
268
+ query: query,
269
+ resolve: resolve,
270
+ anchoredQuery: anchoredQuery,
271
+ prepare: prepare,
272
+ args: args,
273
+ rawInputs: self.rawInputs,
274
+ body: body,
275
+ isProduction: isProduction,
276
+ blockId: blockId,
277
+ getBlockId: getBlockId,
278
+ validateArgs: validateArgs,
279
+ createPBundleBuilder: createPBundleBuilder,
280
+ tableBuilder: tableBuilder
281
+ })
@@ -3,6 +3,7 @@ smart := import("@platforma-sdk/workflow-tengo:smart")
3
3
  maps := import("@platforma-sdk/workflow-tengo:maps")
4
4
  constants := import("@platforma-sdk/workflow-tengo:constants")
5
5
  json := import("json")
6
+ text := import("text")
6
7
  assets := import("@platforma-sdk/workflow-tengo:assets")
7
8
  render := import("@platforma-sdk/workflow-tengo:render")
8
9
  validation := import("@platforma-sdk/workflow-tengo:validation")
@@ -13,6 +14,19 @@ queryAnchoredTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:workflo
13
14
  _CONTEXT_FIELD_NAME := "ctx"
14
15
 
15
16
 
17
+
18
+ _FAMILIES := {
19
+ "1": {
20
+ single: constants.RTYPE_BRESOLVE_FIRST,
21
+ choice: constants.RTYPE_BRESOLVE_CHOICE
22
+ },
23
+ "2": {
24
+ single: { Name: "BResolveSingle", Version: "2" },
25
+ choice: { Name: "BResolveChoice", Version: "2" }
26
+ }
27
+ }
28
+
29
+
16
30
  _OPTIONS_SCHEME := {
17
31
  "spec,?": `bool`,
18
32
  "data,?": `bool`,
@@ -113,9 +127,11 @@ _QUERY_MAP_SCHEMA := {
113
127
 
114
128
 
115
129
 
116
- create := func(spec, ctx, ...options) {
130
+ _create := func(family, spec, ctx, options) {
131
+
117
132
 
118
133
 
134
+ types := _FAMILIES[string(family)]
119
135
 
120
136
  ops := copy(_DEFAULT_OPTIONS)
121
137
  if len(options) > 0 {
@@ -136,10 +152,10 @@ create := func(spec, ctx, ...options) {
136
152
 
137
153
  builder := undefined
138
154
  if ops.first {
139
- builder = smart.ephemeralBuilder(constants.RTYPE_BRESOLVE_FIRST, query)
155
+ builder = smart.ephemeralBuilder(types.single, query)
140
156
  } else {
141
157
 
142
- builder = smart.ephemeralBuilder(constants.RTYPE_BRESOLVE_CHOICE, query)
158
+ builder = smart.ephemeralBuilder(types.choice, query)
143
159
  }
144
160
 
145
161
  builder.createInputField(_CONTEXT_FIELD_NAME).set(ctx)
@@ -151,6 +167,9 @@ create := func(spec, ctx, ...options) {
151
167
  rb := smart.structBuilder(constants.RTYPE_QUERY_RESULT)
152
168
 
153
169
 
170
+ if family != 1 {
171
+ ops.family = family
172
+ }
154
173
  rb.createInputField("ops").setJson(ops)
155
174
 
156
175
  if ops.spec {
@@ -171,6 +190,19 @@ create := func(spec, ctx, ...options) {
171
190
  return rb.lockAndBuild()
172
191
  }
173
192
 
193
+ create := func(spec, ctx, ...options) {
194
+ return _create(1, spec, ctx, options)
195
+ }
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
174
206
 
175
207
 
176
208
 
@@ -183,6 +215,28 @@ resultUnmarshaller := func() {
183
215
  parse: func(resource, parser) {
184
216
 
185
217
  ops := resource.get("ops").getDataAsJson()
218
+ isFamily2 := ops.family == 2
219
+
220
+
221
+ isNR := func(r) {
222
+ return r.info().Type.Name == constants.RTYPE_BRESOLVE_NO_RESULT.Name
223
+ }
224
+
225
+
226
+ isNoResultField := func(field) {
227
+ return field.isSet() && !field.isErrorSet() &&
228
+ field.getValue().checkResourceType(constants.RTYPE_BRESOLVE_NO_RESULT)
229
+ }
230
+
231
+
232
+ decodeRef := func(address) {
233
+ if !isFamily2 {
234
+ return address
235
+ }
236
+ parts := text.split_n(address.blockId, "/", 2)
237
+ ll.assert(len(parts) == 2, "unexpected address of a family-2 value: %v", address)
238
+ return { block: parts[0], workflow: parts[1], name: address.name }
239
+ }
186
240
 
187
241
 
188
242
 
@@ -200,22 +254,19 @@ resultUnmarshaller := func() {
200
254
  if ops.first {
201
255
 
202
256
 
203
-
204
- isNR := func(r) {
205
- return r.info().Type.Name == constants.RTYPE_BRESOLVE_NO_RESULT.Name
206
- }
207
-
208
257
  if isNR(resource.get("ref")) {
209
258
  return undefined
210
259
  }
211
260
 
212
261
  result := {
213
- ref: resource.get("ref").getDataAsJson(),
262
+ ref: decodeRef(resource.get("ref").getDataAsJson()),
214
263
  spec: resource.get("spec").getDataAsJson()
215
264
  }
216
265
 
217
266
  if resource.hasInputField("data") {
218
- result.data = getData(resource, "data")
267
+ if !isFamily2 || !isNoResultField(resource.getField("data")) {
268
+ result.data = getData(resource, "data")
269
+ }
219
270
  }
220
271
 
221
272
  return ll.toStrict(result)
@@ -231,13 +282,18 @@ resultUnmarshaller := func() {
231
282
  result := []
232
283
  maps.forEach(specs, func(ref, s) {
233
284
  r := {
234
- ref: json.decode(ref),
285
+ ref: decodeRef(json.decode(ref)),
235
286
  spec: s.getValueAsJson()
236
287
  }
237
288
 
238
289
 
290
+
239
291
  if !is_undefined(datas) {
240
- r.data = getData(datas, ref)
292
+ if !isFamily2 {
293
+ r.data = getData(datas, ref)
294
+ } else if datas.hasInputField(ref) && !isNoResultField(datas.getField(ref)) {
295
+ r.data = getData(datas, ref)
296
+ }
241
297
  }
242
298
 
243
299
  result = append(result, ll.toStrict(r))
@@ -262,23 +318,86 @@ resultUnmarshaller := func() {
262
318
 
263
319
 
264
320
 
265
- resolve := func(ref, ctx, ...options) {
321
+ _FAMILY2_REF_FIELDS := ["block", "workflow", "name"]
322
+
323
+
324
+
325
+ _isFamily2Ref := func(value) {
326
+ if !ll.isMap(value) || smart.isReference(value) || len(value) != len(_FAMILY2_REF_FIELDS) {
327
+ return false
328
+ }
329
+ for f in _FAMILY2_REF_FIELDS {
330
+ if !maps.containsKey(value, f) || !is_string(value[f]) || value[f] == "" {
331
+ return false
332
+ }
333
+ }
334
+ return !text.contains(value.block, "/") && !text.contains(value.workflow, "/")
335
+ }
336
+
337
+ _assertFamily2Ref := func(ref) {
338
+ if !_isFamily2Ref(ref) {
339
+ ll.panic("a ref is {block, workflow, name}: three non-empty strings, block and workflow without \"/\"; got %v", ref)
340
+ }
341
+ }
342
+
343
+
344
+
345
+ _family2Options := func(options, allowed) {
346
+ ll.assert(len(options) <= 1, "expected at most one options map, got %v", options)
347
+ if len(options) == 0 {
348
+ return {}
349
+ }
350
+ o := options[0]
351
+ ll.assert(ll.isMap(o) && !smart.isReference(o), "expected a map of options, got %v", o)
352
+ for k, v in o {
353
+ ok := false
354
+ for a in allowed {
355
+ if a == k {
356
+ ok = true
357
+ }
358
+ }
359
+ if !ok {
360
+ ll.panic("query option %q is not allowed in the v2 query API; allowed: %v", k, allowed)
361
+ }
362
+ ll.assert(is_bool(v), "query option %q must be a boolean, got %v", k, v)
363
+ }
364
+ return copy(o)
365
+ }
366
+
367
+ _resolve := func(family, ref, ctx, options) {
266
368
 
267
- spec := {
268
- type: "Direct",
269
- block_id: ref.blockId, // @TODO use consistent naming in pl
270
- output_name: ref.name // @TODO use consistent naming in pl
369
+ spec := undefined
370
+ if family == 2 {
371
+ _assertFamily2Ref(ref)
372
+ spec = {
373
+ type: "Direct",
374
+ block_id: ref.block + "/" + ref.workflow,
375
+ output_name: ref.name
376
+ }
377
+ } else {
378
+ spec = {
379
+ type: "Direct",
380
+ block_id: ref.blockId, // @TODO use consistent naming in pl
381
+ output_name: ref.name // @TODO use consistent naming in pl
382
+ }
271
383
  }
272
384
 
273
385
  ops := {}
274
386
 
275
387
  if len(options) > 0 {
276
- ops = options[0]
388
+ ops = copy(options[0])
277
389
  }
278
390
 
279
391
  ops.first = true
392
+ if family == 2 {
393
+ ops.errIfMissing = true
394
+ }
395
+
396
+ return _create(family, spec, ctx, [ops])
397
+ }
280
398
 
281
- return create(spec, ctx, ops)
399
+ resolve := func(ref, ctx, ...options) {
400
+ return _resolve(1, ref, ctx, options)
282
401
  }
283
402
 
284
403
 
@@ -310,7 +429,7 @@ _ANCHORED_QUERY_DEFAULT_OPTIONS := {
310
429
 
311
430
 
312
431
 
313
- anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
432
+ _anchoredQuery := func(family, ctx, anchors, queryMap, opts) {
314
433
 
315
434
  validation.assertType(queryMap, _QUERY_MAP_SCHEMA, "invalid query map schema")
316
435
 
@@ -334,7 +453,7 @@ anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
334
453
  }
335
454
  }
336
455
 
337
- resolvedAnchors[anchorId] = resolve(ref, ctx, opts)
456
+ resolvedAnchors[anchorId] = _resolve(family, ref, ctx, [opts])
338
457
  }
339
458
 
340
459
 
@@ -356,14 +475,19 @@ anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
356
475
  }
357
476
  }
358
477
 
478
+ request := {
479
+ queryMap: processedQueryMap,
480
+ opts: normalizedOpts
481
+ }
482
+ if family != 1 {
483
+ request.family = family
484
+ }
485
+
359
486
 
360
487
  queryResult := render.createEphemeral(queryAnchoredTpl, {
361
488
  ctx: ctx,
362
489
  anchorSpecs: smart.createMapResource(maps.mapValues(resolvedAnchors, func(v) { return v.inputs().spec })),
363
- request: {
364
- queryMap: processedQueryMap,
365
- opts: normalizedOpts
366
- }
490
+ request: request
367
491
  })
368
492
 
369
493
 
@@ -422,9 +546,77 @@ anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
422
546
  return self
423
547
  }
424
548
 
549
+ anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
550
+ return _anchoredQuery(1, ctx, anchors, queryMap, opts)
551
+ }
552
+
553
+
554
+
555
+
556
+
557
+
558
+
559
+
560
+
561
+
562
+
563
+
564
+
565
+
566
+
567
+
568
+
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
+
577
+
578
+
579
+
580
+
581
+ forFamily := func(family) {
582
+ ll.assert(family == 1 || family == 2, "unknown resolver family: %v, expected 1 or 2", family)
583
+ if family == 1 {
584
+ return ll.toStrict({
585
+ create: func(spec, ctx, ...options) {
586
+ return _create(1, spec, ctx, options)
587
+ },
588
+ resolve: func(ref, ctx, ...options) {
589
+ return _resolve(1, ref, ctx, options)
590
+ },
591
+ anchoredQuery: func(ctx, anchors, queryMap, ...opts) {
592
+ return _anchoredQuery(1, ctx, anchors, queryMap, opts)
593
+ }
594
+ })
595
+ }
596
+ return ll.toStrict({
597
+ create: func(spec, ctx, ...options) {
598
+ ops := _family2Options(options, ["spec", "data", "single"])
599
+ if ops.single == true {
600
+ ops.first = true
601
+ ops.errIfMissing = true
602
+ }
603
+ delete(ops, "single")
604
+ return _create(2, spec, ctx, [ops])
605
+ },
606
+ resolve: func(ref, ctx, ...options) {
607
+ return _resolve(2, ref, ctx, [_family2Options(options, ["spec", "data"])])
608
+ },
609
+ anchoredQuery: func(ctx, anchors, queryMap, ...opts) {
610
+ return _anchoredQuery(2, ctx, anchors, queryMap, opts)
611
+ },
612
+ isRef: _isFamily2Ref
613
+ })
614
+ }
615
+
425
616
  export ll.toStrict({
426
617
  create: create,
427
618
  resolve: resolve,
428
619
  resultUnmarshaller: resultUnmarshaller,
429
- anchoredQuery: anchoredQuery
620
+ anchoredQuery: anchoredQuery,
621
+ forFamily: forFamily
430
622
  })
Binary file
Binary file