@vortexm/vjt 0.1.11 → 0.1.13

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/index.js CHANGED
@@ -3900,7 +3900,7 @@ var NetworkRuntime = class {
3900
3900
  }
3901
3901
  }
3902
3902
  async executeRequest(requestName, currentValue) {
3903
- const definition = this.requestsMap[requestName];
3903
+ const definition = resolveRequestDefinition(this.requestsMap, requestName);
3904
3904
  if (!definition) {
3905
3905
  return null;
3906
3906
  }
@@ -4125,6 +4125,24 @@ var NetworkRuntime = class {
4125
4125
  await this.rerenderRoot();
4126
4126
  }
4127
4127
  };
4128
+ function isRequestDefinitionLike(value) {
4129
+ return typeof value === "object" && value !== null && "request" in value && "name" in value;
4130
+ }
4131
+ function resolveRequestDefinition(requestsMap, requestName) {
4132
+ const directMatch = requestsMap[requestName];
4133
+ if (isRequestDefinitionLike(directMatch)) {
4134
+ return directMatch;
4135
+ }
4136
+ const segments = requestName.split(".").filter(Boolean);
4137
+ let current = requestsMap;
4138
+ for (const segment of segments) {
4139
+ if (typeof current !== "object" || current === null || !(segment in current)) {
4140
+ return void 0;
4141
+ }
4142
+ current = current[segment];
4143
+ }
4144
+ return isRequestDefinitionLike(current) ? current : void 0;
4145
+ }
4128
4146
 
4129
4147
  // src/lib/references.ts
4130
4148
  function isPlainObject2(value) {
@@ -4256,24 +4274,89 @@ var ReferenceRuntime = class {
4256
4274
  constructor(host) {
4257
4275
  this.host = host;
4258
4276
  }
4259
- isEmptyReference(reference, currentValue, responseValue) {
4260
- return isReferenceValueEmpty(this.resolveReference(reference, currentValue, responseValue));
4277
+ resolveScopedRootReference(scope, path, currentValue, responseValue, inputValue) {
4278
+ if (scope === "current") {
4279
+ if (path.length === 0) {
4280
+ return currentValue;
4281
+ }
4282
+ return this.resolveCurrentReference(path.join("."), currentValue);
4283
+ }
4284
+ if (scope === "input") {
4285
+ return path.length === 0 ? inputValue : readPath(inputValue, path);
4286
+ }
4287
+ if (scope === "message" || scope === "response") {
4288
+ return path.length === 0 ? responseValue : readPath(responseValue, path);
4289
+ }
4290
+ if (path.length === 0) {
4291
+ return this.host.getVarsSnapshot();
4292
+ }
4293
+ return this.readVarReference(path.join("."));
4261
4294
  }
4262
- resolveReference(reference, currentValue, responseValue) {
4263
- if (reference === "current") {
4264
- return currentValue;
4295
+ readVarReference(path) {
4296
+ const [rootKey, ...rest] = path.split(".").filter(Boolean);
4297
+ if (!rootKey) {
4298
+ return void 0;
4299
+ }
4300
+ const rootValue = this.host.getVarValue(rootKey);
4301
+ if (rest.length === 0) {
4302
+ return rootValue;
4265
4303
  }
4266
- if (reference === "message") {
4267
- return responseValue;
4304
+ return readPath(rootValue, rest);
4305
+ }
4306
+ writeVarReference(path, value) {
4307
+ const [rootKey, ...rest] = path.split(".").filter(Boolean);
4308
+ if (!rootKey) {
4309
+ return;
4268
4310
  }
4269
- if (reference.startsWith("message.")) {
4270
- return readPath(responseValue, reference.slice(8).split("."));
4311
+ if (rest.length === 0) {
4312
+ this.host.setVarValue(rootKey, value);
4313
+ return;
4271
4314
  }
4272
- if (reference.startsWith("response.")) {
4273
- return readPath(responseValue, reference.slice(9).split("."));
4315
+ const currentRoot = this.host.getVarValue(rootKey);
4316
+ const nextRoot = isPlainObject2(currentRoot) ? structuredClone(currentRoot) : {};
4317
+ if (writePath(nextRoot, rest, value)) {
4318
+ this.host.setVarValue(rootKey, nextRoot);
4274
4319
  }
4275
- if (reference.startsWith("current.")) {
4276
- return this.resolveCurrentReference(reference.slice(8), currentValue);
4320
+ }
4321
+ isEmptyReference(reference, currentValue, responseValue, inputValue) {
4322
+ return isReferenceValueEmpty(this.resolveReference(reference, currentValue, responseValue, inputValue));
4323
+ }
4324
+ resolveReference(reference, currentValue, responseValue, inputValue = currentValue) {
4325
+ if (reference === "current" || reference.startsWith("current.")) {
4326
+ return this.resolveScopedRootReference(
4327
+ "current",
4328
+ reference === "current" ? [] : reference.slice(8).split(".").filter(Boolean),
4329
+ currentValue,
4330
+ responseValue,
4331
+ inputValue
4332
+ );
4333
+ }
4334
+ if (reference === "input" || reference.startsWith("input.")) {
4335
+ return this.resolveScopedRootReference(
4336
+ "input",
4337
+ reference === "input" ? [] : reference.slice(6).split(".").filter(Boolean),
4338
+ currentValue,
4339
+ responseValue,
4340
+ inputValue
4341
+ );
4342
+ }
4343
+ if (reference === "message" || reference.startsWith("message.")) {
4344
+ return this.resolveScopedRootReference(
4345
+ "message",
4346
+ reference === "message" ? [] : reference.slice(8).split(".").filter(Boolean),
4347
+ currentValue,
4348
+ responseValue,
4349
+ inputValue
4350
+ );
4351
+ }
4352
+ if (reference === "response" || reference.startsWith("response.")) {
4353
+ return this.resolveScopedRootReference(
4354
+ "response",
4355
+ reference === "response" ? [] : reference.slice(9).split(".").filter(Boolean),
4356
+ currentValue,
4357
+ responseValue,
4358
+ inputValue
4359
+ );
4277
4360
  }
4278
4361
  if (reference.startsWith("cookies.")) {
4279
4362
  return getCookieValue(reference.slice(8));
@@ -4284,8 +4367,14 @@ var ReferenceRuntime = class {
4284
4367
  if (reference.startsWith("url.")) {
4285
4368
  return getUrlParamValue(reference.slice(4));
4286
4369
  }
4287
- if (reference.startsWith("vars.")) {
4288
- return this.host.getVarValue(reference.slice(5));
4370
+ if (reference === "vars" || reference.startsWith("vars.")) {
4371
+ return this.resolveScopedRootReference(
4372
+ "vars",
4373
+ reference === "vars" ? [] : reference.slice(5).split(".").filter(Boolean),
4374
+ currentValue,
4375
+ responseValue,
4376
+ inputValue
4377
+ );
4289
4378
  }
4290
4379
  const [widgetId, ...rest] = reference.split(".");
4291
4380
  const state = this.host.stateById.get(widgetId);
@@ -4424,7 +4513,7 @@ var ReferenceRuntime = class {
4424
4513
  return;
4425
4514
  }
4426
4515
  if (reference.startsWith("vars.")) {
4427
- this.host.setVarValue(reference.slice(5), inputValue);
4516
+ this.writeVarReference(reference.slice(5), inputValue);
4428
4517
  return;
4429
4518
  }
4430
4519
  const [widgetId, ...rest] = reference.split(".");
@@ -4513,20 +4602,20 @@ var ReferenceRuntime = class {
4513
4602
  }
4514
4603
  }
4515
4604
  }
4516
- resolveMappedValue(template, currentValue, responseValue) {
4605
+ resolveMappedValue(template, currentValue, responseValue, inputValue = currentValue) {
4517
4606
  if (typeof template === "string") {
4518
4607
  if (template.startsWith("$ref:")) {
4519
- return this.resolveReference(template.slice(5), currentValue, responseValue);
4608
+ return this.resolveReference(template.slice(5), currentValue, responseValue, inputValue);
4520
4609
  }
4521
4610
  if (template.includes("$ref:")) {
4522
4611
  return template.replaceAll(/\$ref:([A-Za-z0-9_.]+)/g, (_match, ref) => {
4523
- const resolved = this.resolveReference(ref, currentValue, responseValue);
4612
+ const resolved = this.resolveReference(ref, currentValue, responseValue, inputValue);
4524
4613
  return stringifyReferenceValue(resolved);
4525
4614
  });
4526
4615
  }
4527
4616
  }
4528
4617
  if (Array.isArray(template)) {
4529
- return template.map((entry) => this.resolveMappedValue(entry, currentValue, responseValue));
4618
+ return template.map((entry) => this.resolveMappedValue(entry, currentValue, responseValue, inputValue));
4530
4619
  }
4531
4620
  if (isPlainObject2(template)) {
4532
4621
  const result = {};
@@ -4537,7 +4626,7 @@ var ReferenceRuntime = class {
4537
4626
  if (isTrustedConfigOnlyKey(key) && templateValueUsesReference(value)) {
4538
4627
  continue;
4539
4628
  }
4540
- result[key] = this.resolveMappedValue(value, currentValue, responseValue);
4629
+ result[key] = this.resolveMappedValue(value, currentValue, responseValue, inputValue);
4541
4630
  }
4542
4631
  return result;
4543
4632
  }
@@ -4794,8 +4883,9 @@ var ActionRuntime = class {
4794
4883
  responseValue: context.responseValue,
4795
4884
  pointer: context.pointer ?? null
4796
4885
  });
4797
- if (this.actionsMap[name]) {
4798
- return this.runActions(this.actionsMap[name], inputValue, context);
4886
+ const customAction = resolveActionDefinition(this.actionsMap, name);
4887
+ if (customAction) {
4888
+ return this.runActions(customAction, inputValue, context);
4799
4889
  }
4800
4890
  if (name.startsWith("refresh ")) {
4801
4891
  await this.refreshWidgetTree(name.slice(8));
@@ -4822,7 +4912,7 @@ var ActionRuntime = class {
4822
4912
  return null;
4823
4913
  }
4824
4914
  if (name.startsWith("play ")) {
4825
- await this.playAudio(this.resolveReference(name.slice(5), context.currentValue, context.responseValue));
4915
+ await this.playAudio(this.resolveReference(name.slice(5), context.currentValue, context.responseValue, inputValue));
4826
4916
  return null;
4827
4917
  }
4828
4918
  if (name === "copyToClipboard") {
@@ -4935,18 +5025,18 @@ var ActionRuntime = class {
4935
5025
  if (name.startsWith("get ")) {
4936
5026
  const reference = name.slice(4);
4937
5027
  if (Array.isArray(inputValue) && this.isCurrentScopedReference(reference)) {
4938
- return inputValue.map((entry) => this.resolveReference(reference, entry, context.responseValue)).filter((entry) => entry !== null && entry !== void 0);
5028
+ return inputValue.map((entry) => this.resolveReference(reference, entry, context.responseValue, entry)).filter((entry) => entry !== null && entry !== void 0);
4939
5029
  }
4940
- return this.resolveReference(reference, context.currentValue, context.responseValue);
5030
+ return this.resolveReference(reference, context.currentValue, context.responseValue, inputValue);
4941
5031
  }
4942
5032
  if (name.startsWith("getFirst ")) {
4943
- return this.getCollectionBoundary(name.slice(9), "first");
5033
+ return this.getCollectionBoundaryByReference(name.slice(9), inputValue, context, "first");
4944
5034
  }
4945
5035
  if (name.startsWith("getLast ")) {
4946
- return this.getCollectionBoundary(name.slice(8), "last");
5036
+ return this.getCollectionBoundaryByReference(name.slice(8), inputValue, context, "last");
4947
5037
  }
4948
5038
  if (name.startsWith("count ")) {
4949
- return this.countValue(this.resolveReference(name.slice(6), context.currentValue, context.responseValue));
5039
+ return this.countValue(this.resolveReference(name.slice(6), context.currentValue, context.responseValue, inputValue));
4950
5040
  }
4951
5041
  if (name === "indexOf") {
4952
5042
  if (isListElementLike(context.currentValue)) {
@@ -4985,25 +5075,25 @@ var ActionRuntime = class {
4985
5075
  return this.stringifyValue(inputValue).replaceAll(/\r\n/g, "\n").replaceAll(/\n{3,}/g, "\n\n");
4986
5076
  }
4987
5077
  if (name.startsWith("equals ")) {
4988
- return this.resolveReference(name.slice(7), context.currentValue, context.responseValue) === action.args;
5078
+ return this.resolveReference(name.slice(7), context.currentValue, context.responseValue, inputValue) === action.args;
4989
5079
  }
4990
5080
  if (name.startsWith("greaterThan ")) {
4991
- return this.toNumber(inputValue) > this.toNumber(this.resolveReference(name.slice(12), context.currentValue, context.responseValue));
5081
+ return this.toNumber(inputValue) > this.toNumber(this.resolveReference(name.slice(12), context.currentValue, context.responseValue, inputValue));
4992
5082
  }
4993
5083
  if (name.startsWith("greaterThanOrEquals ")) {
4994
- return this.toNumber(inputValue) >= this.toNumber(this.resolveReference(name.slice(20), context.currentValue, context.responseValue));
5084
+ return this.toNumber(inputValue) >= this.toNumber(this.resolveReference(name.slice(20), context.currentValue, context.responseValue, inputValue));
4995
5085
  }
4996
5086
  if (name.startsWith("lessThan ")) {
4997
- return this.toNumber(inputValue) < this.toNumber(this.resolveReference(name.slice(9), context.currentValue, context.responseValue));
5087
+ return this.toNumber(inputValue) < this.toNumber(this.resolveReference(name.slice(9), context.currentValue, context.responseValue, inputValue));
4998
5088
  }
4999
5089
  if (name.startsWith("lessThanOrEquals ")) {
5000
- return this.toNumber(inputValue) <= this.toNumber(this.resolveReference(name.slice(17), context.currentValue, context.responseValue));
5090
+ return this.toNumber(inputValue) <= this.toNumber(this.resolveReference(name.slice(17), context.currentValue, context.responseValue, inputValue));
5001
5091
  }
5002
5092
  if (name.startsWith("and ")) {
5003
- return Boolean(inputValue) && Boolean(this.resolveReference(name.slice(4), context.currentValue, context.responseValue));
5093
+ return Boolean(inputValue) && Boolean(this.resolveReference(name.slice(4), context.currentValue, context.responseValue, inputValue));
5004
5094
  }
5005
5095
  if (name.startsWith("isEmpty ")) {
5006
- return this.isEmptyReference(name.slice(8), context.currentValue, context.responseValue);
5096
+ return this.isEmptyReference(name.slice(8), context.currentValue, context.responseValue, inputValue);
5007
5097
  }
5008
5098
  if (name.startsWith("set ")) {
5009
5099
  const args = typeof action.args === "object" && action.args !== null && !Array.isArray(action.args) ? action.args : void 0;
@@ -5011,14 +5101,14 @@ var ActionRuntime = class {
5011
5101
  return inputValue;
5012
5102
  }
5013
5103
  if (name.startsWith("setFirst ")) {
5014
- return this.setCollectionBoundary(name.slice(9), inputValue, "first");
5104
+ return this.setCollectionBoundaryByReference(name.slice(9), inputValue, context, "first");
5015
5105
  }
5016
5106
  if (name.startsWith("setLast ")) {
5017
- return this.setCollectionBoundary(name.slice(8), inputValue, "last");
5107
+ return this.setCollectionBoundaryByReference(name.slice(8), inputValue, context, "last");
5018
5108
  }
5019
5109
  if (name.startsWith("append ")) {
5020
5110
  const reference = name.slice(7);
5021
- const currentText = this.resolveReference(reference, context.currentValue, context.responseValue);
5111
+ const currentText = this.resolveReference(reference, context.currentValue, context.responseValue, inputValue);
5022
5112
  const nextValue = `${this.stringifyValue(currentText)}${this.stringifyValue(action.args)}`;
5023
5113
  this.assignReference(reference, nextValue, context.currentValue);
5024
5114
  return nextValue;
@@ -5026,9 +5116,9 @@ var ActionRuntime = class {
5026
5116
  if (name.startsWith("filter ")) {
5027
5117
  const reference = name.slice(7);
5028
5118
  if (Array.isArray(inputValue) && this.isCurrentScopedReference(reference)) {
5029
- return inputValue.filter((entry) => this.resolveReference(reference, entry, context.responseValue));
5119
+ return inputValue.filter((entry) => this.resolveReference(reference, entry, context.responseValue, entry));
5030
5120
  }
5031
- const value = this.resolveReference(reference, context.currentValue, context.responseValue);
5121
+ const value = this.resolveReference(reference, context.currentValue, context.responseValue, inputValue);
5032
5122
  return value ? inputValue : null;
5033
5123
  }
5034
5124
  if (name === "remove") {
@@ -5044,7 +5134,7 @@ var ActionRuntime = class {
5044
5134
  return null;
5045
5135
  }
5046
5136
  if (name.startsWith("add ")) {
5047
- const valueToAdd = this.cloneValue(this.unwrapListValue(this.resolveReference(name.slice(4), context.currentValue, context.responseValue)));
5137
+ const valueToAdd = this.cloneValue(this.unwrapListValue(this.resolveReference(name.slice(4), context.currentValue, context.responseValue, inputValue)));
5048
5138
  const listState = this.getCurrentListState(context.currentValue);
5049
5139
  if (listState && Array.isArray(listState.elements)) {
5050
5140
  listState.elements.push(valueToAdd);
@@ -5071,7 +5161,7 @@ var ActionRuntime = class {
5071
5161
  return inputValue;
5072
5162
  }
5073
5163
  if (name.startsWith("insert ")) {
5074
- const valueToInsert = this.cloneValue(this.unwrapListValue(this.resolveReference(name.slice(7), context.currentValue, context.responseValue)));
5164
+ const valueToInsert = this.cloneValue(this.unwrapListValue(this.resolveReference(name.slice(7), context.currentValue, context.responseValue, inputValue)));
5075
5165
  const listState = this.getCurrentListState(context.currentValue);
5076
5166
  if (listState && Array.isArray(listState.elements) && typeof context.currentValue === "object" && context.currentValue !== null && "index" in context.currentValue) {
5077
5167
  const index = context.currentValue.index;
@@ -5102,9 +5192,12 @@ var ActionRuntime = class {
5102
5192
  }
5103
5193
  if (name === "map") {
5104
5194
  if (Array.isArray(inputValue)) {
5105
- return inputValue.map((entry) => this.resolveMappedValue(action.args, entry, context.responseValue));
5195
+ return inputValue.map((entry) => this.resolveMappedValue(action.args, entry, context.responseValue, entry));
5106
5196
  }
5107
- return this.resolveMappedValue(action.args, inputValue, context.responseValue);
5197
+ return this.resolveMappedValue(action.args, inputValue, context.responseValue, inputValue);
5198
+ }
5199
+ if (name === "setInput") {
5200
+ return this.resolveMappedValue(action.args, context.currentValue, context.responseValue, inputValue);
5108
5201
  }
5109
5202
  if (name === "ifelse") {
5110
5203
  const branches = isIfElseArgs(action.args) ? action.args : null;
@@ -5146,32 +5239,42 @@ var ActionRuntime = class {
5146
5239
  }
5147
5240
  return JSON.stringify(value);
5148
5241
  }
5149
- getCollectionBoundary(widgetId, boundary) {
5150
- const state = this.stateById.get(widgetId) ?? this.stateByKey.get(widgetId);
5151
- const collection = this.getWidgetCollection(state);
5242
+ getCollectionBoundaryByReference(reference, inputValue, context, boundary) {
5243
+ const collection = this.resolveCollectionReference(reference, inputValue, context);
5152
5244
  if (!collection || collection.length === 0) {
5153
5245
  return null;
5154
5246
  }
5155
- const index = boundary === "first" ? 0 : collection.length - 1;
5156
- const value = collection[index];
5157
- return isListElementLike(value) ? this.unwrapListValue(value) : value;
5247
+ return collection[boundary === "first" ? 0 : collection.length - 1];
5158
5248
  }
5159
- setCollectionBoundary(widgetId, inputValue, boundary) {
5160
- const state = this.stateById.get(widgetId) ?? this.stateByKey.get(widgetId);
5161
- if (!state) {
5249
+ setCollectionBoundaryByReference(reference, inputValue, context, boundary) {
5250
+ const state = this.resolveReference(reference, context.currentValue, context.responseValue, inputValue);
5251
+ const directCollection = this.getWidgetCollection(this.asWidgetState(state));
5252
+ if (directCollection && directCollection.length > 0) {
5253
+ directCollection[boundary === "first" ? 0 : directCollection.length - 1] = this.cloneValue(this.unwrapListValue(inputValue));
5254
+ const widgetState = this.asWidgetState(state);
5255
+ if (widgetState && (widgetState.widget === "list" || widgetState.widget === "grid-view")) {
5256
+ this.clearListElementState(widgetState.key);
5257
+ }
5162
5258
  return inputValue;
5163
5259
  }
5164
- const collection = this.getWidgetCollection(state);
5260
+ const collection = this.resolveCollectionReference(reference, inputValue, context);
5165
5261
  if (!collection || collection.length === 0) {
5166
5262
  return inputValue;
5167
5263
  }
5168
- const index = boundary === "first" ? 0 : collection.length - 1;
5169
- collection[index] = this.cloneValue(this.unwrapListValue(inputValue));
5170
- if (state.widget === "list" || state.widget === "grid-view") {
5171
- this.clearListElementState(state.key);
5172
- }
5264
+ const nextCollection = collection.map((entry) => this.cloneValue(this.unwrapListValue(entry)));
5265
+ nextCollection[boundary === "first" ? 0 : nextCollection.length - 1] = this.cloneValue(this.unwrapListValue(inputValue));
5266
+ this.assignReference(reference, nextCollection, context.currentValue);
5173
5267
  return inputValue;
5174
5268
  }
5269
+ resolveCollectionReference(reference, inputValue, context) {
5270
+ const resolved = this.resolveReference(reference, context.currentValue, context.responseValue, inputValue);
5271
+ const widgetCollection = this.getWidgetCollection(this.asWidgetState(resolved));
5272
+ const collection = Array.isArray(resolved) ? resolved : widgetCollection;
5273
+ if (!collection) {
5274
+ return null;
5275
+ }
5276
+ return collection.map((entry) => this.unwrapListValue(entry));
5277
+ }
5175
5278
  getWidgetCollection(state) {
5176
5279
  if (!state) {
5177
5280
  return null;
@@ -5187,6 +5290,12 @@ var ActionRuntime = class {
5187
5290
  }
5188
5291
  return null;
5189
5292
  }
5293
+ asWidgetState(value) {
5294
+ if (!value || typeof value !== "object") {
5295
+ return null;
5296
+ }
5297
+ return value;
5298
+ }
5190
5299
  isCurrentScopedReference(reference) {
5191
5300
  return reference === "current" || reference.startsWith("current.") || reference.startsWith("this.") || reference === "this";
5192
5301
  }
@@ -5234,6 +5343,21 @@ var ActionRuntime = class {
5234
5343
  function isIfElseArgs(value) {
5235
5344
  return typeof value === "object" && value !== null && !Array.isArray(value);
5236
5345
  }
5346
+ function resolveActionDefinition(actionsMap, actionName) {
5347
+ const directMatch = actionsMap[actionName];
5348
+ if (Array.isArray(directMatch)) {
5349
+ return directMatch;
5350
+ }
5351
+ const segments = actionName.split(".").filter(Boolean);
5352
+ let current = actionsMap;
5353
+ for (const segment of segments) {
5354
+ if (typeof current !== "object" || current === null || !(segment in current)) {
5355
+ return void 0;
5356
+ }
5357
+ current = current[segment];
5358
+ }
5359
+ return Array.isArray(current) ? current : void 0;
5360
+ }
5237
5361
  function isListElementLike(value) {
5238
5362
  return typeof value === "object" && value !== null && "kind" in value && value.kind === "list-element" && "listId" in value && typeof value.listId === "string" && "index" in value && typeof value.index === "number" && "descriptor" in value;
5239
5363
  }
@@ -7416,6 +7540,7 @@ var RuntimeRenderer = class {
7416
7540
  }
7417
7541
  },
7418
7542
  getVarValue: (name) => this.vars.get(name),
7543
+ getVarsSnapshot: () => Object.fromEntries(this.vars.entries()),
7419
7544
  setVarValue: (name, value) => {
7420
7545
  this.vars.set(name, value);
7421
7546
  },
@@ -7446,10 +7571,10 @@ var RuntimeRenderer = class {
7446
7571
  rerenderRoot: () => this.rerenderRoot(),
7447
7572
  dispatchWidgetEvent: (node, eventName, key, inputValue, pointer) => this.actionRuntime.dispatchWidgetEvent(node, eventName, key, inputValue, pointer),
7448
7573
  executeRequest: (requestName, currentValue) => this.networkRuntime.executeRequest(requestName, currentValue),
7449
- resolveReference: (reference, currentValue, responseValue) => this.referenceRuntime.resolveReference(reference, currentValue, responseValue),
7450
- isEmptyReference: (reference, currentValue, responseValue) => this.referenceRuntime.isEmptyReference(reference, currentValue, responseValue),
7574
+ resolveReference: (reference, currentValue, responseValue, inputValue) => this.referenceRuntime.resolveReference(reference, currentValue, responseValue, inputValue),
7575
+ isEmptyReference: (reference, currentValue, responseValue, inputValue) => this.referenceRuntime.isEmptyReference(reference, currentValue, responseValue, inputValue),
7451
7576
  assignReference: (reference, inputValue, currentValue, options2) => this.referenceRuntime.assignReference(reference, inputValue, currentValue, options2),
7452
- resolveMappedValue: (template, currentValue, responseValue) => this.referenceRuntime.resolveMappedValue(template, currentValue, responseValue),
7577
+ resolveMappedValue: (template, currentValue, responseValue, inputValue) => this.referenceRuntime.resolveMappedValue(template, currentValue, responseValue, inputValue),
7453
7578
  setWidgetEnabled: (widgetId, enabled) => this.setWidgetEnabled(widgetId, enabled),
7454
7579
  setWidgetVisible: (widgetId, visible) => this.setWidgetVisible(widgetId, visible),
7455
7580
  clearWidget: (widgetId) => this.clearWidget(widgetId),
@@ -9144,6 +9269,39 @@ function renderApp(root, description, options = {}) {
9144
9269
  }
9145
9270
 
9146
9271
  // src/lib/resource-manager.ts
9272
+ function isRequestDefinitionLike2(value) {
9273
+ return typeof value === "object" && value !== null && "request" in value && "name" in value;
9274
+ }
9275
+ function flattenActionMap(input, prefix = "") {
9276
+ const result = {};
9277
+ if (!input) {
9278
+ return result;
9279
+ }
9280
+ for (const [key, value] of Object.entries(input)) {
9281
+ const qualifiedName = prefix ? `${prefix}.${key}` : key;
9282
+ if (Array.isArray(value)) {
9283
+ result[qualifiedName] = value;
9284
+ continue;
9285
+ }
9286
+ Object.assign(result, flattenActionMap(value, qualifiedName));
9287
+ }
9288
+ return result;
9289
+ }
9290
+ function flattenRequestMap(input, prefix = "") {
9291
+ const result = {};
9292
+ if (!input) {
9293
+ return result;
9294
+ }
9295
+ for (const [key, value] of Object.entries(input)) {
9296
+ const qualifiedName = prefix ? `${prefix}.${key}` : key;
9297
+ if (isRequestDefinitionLike2(value)) {
9298
+ result[qualifiedName] = value;
9299
+ continue;
9300
+ }
9301
+ Object.assign(result, flattenRequestMap(value, qualifiedName));
9302
+ }
9303
+ return result;
9304
+ }
9147
9305
  var ResourceManager = class {
9148
9306
  ui = /* @__PURE__ */ new Map();
9149
9307
  actions = {};
@@ -9157,8 +9315,8 @@ var ResourceManager = class {
9157
9315
  for (const [key, value] of Object.entries(input.ui ?? {})) {
9158
9316
  this.ui.set(key, value);
9159
9317
  }
9160
- this.actions = { ...input.actions ?? {} };
9161
- this.requests = { ...input.requests ?? {} };
9318
+ this.actions = flattenActionMap(input.actions);
9319
+ this.requests = flattenRequestMap(input.requests);
9162
9320
  this.routes = Array.isArray(input.routes) ? input.routes.map((route) => ({ ...route })) : Array.isArray(input.routes?.routes) ? input.routes.routes.map((route) => ({ ...route })) : [];
9163
9321
  this.sse = { ...input.sse ?? {} };
9164
9322
  this.systemEvents = { ...input.systemEvents ?? {} };
@@ -1,4 +1,4 @@
1
- import type { ActionDefinition, ActionMap, DescriptionNode, WidgetEventName, WidgetState } from './types.js';
1
+ import type { ActionDefinition, ActionMapInput, DescriptionNode, WidgetEventName, WidgetState } from './types.js';
2
2
  export type ActionExecutionContext = {
3
3
  currentValue: unknown;
4
4
  responseValue?: unknown;
@@ -11,7 +11,7 @@ export type ActionExecutionContext = {
11
11
  };
12
12
  type ActionRuntimeOptions = {
13
13
  debugLogging: boolean;
14
- actionsMap: ActionMap;
14
+ actionsMap: ActionMapInput;
15
15
  actionFunctions: Record<string, () => unknown>;
16
16
  nodeById: Map<string, DescriptionNode>;
17
17
  stateById: Map<string, WidgetState>;
@@ -22,12 +22,12 @@ type ActionRuntimeOptions = {
22
22
  y: number;
23
23
  } | null) => Promise<void>;
24
24
  executeRequest: (requestName: string, currentValue: unknown) => Promise<unknown>;
25
- resolveReference: (reference: string, currentValue: unknown, responseValue: unknown) => unknown;
26
- isEmptyReference: (reference: string, currentValue: unknown, responseValue: unknown) => boolean;
25
+ resolveReference: (reference: string, currentValue: unknown, responseValue: unknown, inputValue?: unknown) => unknown;
26
+ isEmptyReference: (reference: string, currentValue: unknown, responseValue: unknown, inputValue?: unknown) => boolean;
27
27
  assignReference: (reference: string, inputValue: unknown, currentValue: unknown, options?: {
28
28
  cookieTtl?: unknown;
29
29
  }) => void;
30
- resolveMappedValue: (template: unknown, currentValue: unknown, responseValue: unknown) => unknown;
30
+ resolveMappedValue: (template: unknown, currentValue: unknown, responseValue: unknown, inputValue?: unknown) => unknown;
31
31
  setWidgetEnabled: (widgetId: string, enabled: boolean) => void;
32
32
  setWidgetVisible: (widgetId: string, visible: boolean) => void;
33
33
  clearWidget: (widgetId: string) => void;
@@ -124,9 +124,11 @@ export declare class ActionRuntime {
124
124
  private getCurrentListState;
125
125
  private cloneValue;
126
126
  private stringifyValue;
127
- private getCollectionBoundary;
128
- private setCollectionBoundary;
127
+ private getCollectionBoundaryByReference;
128
+ private setCollectionBoundaryByReference;
129
+ private resolveCollectionReference;
129
130
  private getWidgetCollection;
131
+ private asWidgetState;
130
132
  private isCurrentScopedReference;
131
133
  private countValue;
132
134
  private toNumber;
@@ -1,11 +1,11 @@
1
- import type { ActionDefinition, PrimitiveRequestType, RequestMap, RequestSchema, SseConfig } from './types.js';
1
+ import type { ActionDefinition, PrimitiveRequestType, RequestMapInput, RequestSchema, SseConfig } from './types.js';
2
2
  type ActionRunner = (actions: ActionDefinition[], inputValue: unknown, context: {
3
3
  currentValue: unknown;
4
4
  responseValue?: unknown;
5
5
  }) => Promise<unknown>;
6
6
  type NetworkRuntimeOptions = {
7
7
  debugLogging: boolean;
8
- requestsMap: RequestMap;
8
+ requestsMap: RequestMapInput;
9
9
  sseConfigs: SseConfig[];
10
10
  backendUrl?: string;
11
11
  eventSources: EventSource[];
@@ -8,6 +8,7 @@ type ReferenceRuntimeHost = {
8
8
  getAppValue: (name: string) => unknown;
9
9
  setAppValue: (name: string, value: unknown) => void;
10
10
  getVarValue: (name: string) => unknown;
11
+ getVarsSnapshot: () => Record<string, unknown>;
11
12
  setVarValue: (name: string, value: unknown) => void;
12
13
  ensureWidgetState: (node: DescriptionNode, key: string) => WidgetState;
13
14
  resolveItemNodeKey: (node: DescriptionNode, listKey: string, index: number, fallbackPath: string) => string;
@@ -16,8 +17,11 @@ type ReferenceRuntimeHost = {
16
17
  export declare class ReferenceRuntime {
17
18
  private readonly host;
18
19
  constructor(host: ReferenceRuntimeHost);
19
- isEmptyReference(reference: string, currentValue: unknown, responseValue: unknown): boolean;
20
- resolveReference(reference: string, currentValue: unknown, responseValue: unknown): unknown;
20
+ private resolveScopedRootReference;
21
+ private readVarReference;
22
+ private writeVarReference;
23
+ isEmptyReference(reference: string, currentValue: unknown, responseValue: unknown, inputValue?: unknown): boolean;
24
+ resolveReference(reference: string, currentValue: unknown, responseValue: unknown, inputValue?: unknown): unknown;
21
25
  resolveCurrentReference(reference: string, currentValue: unknown): unknown;
22
26
  readWidgetField(state: WidgetState, field: string): unknown;
23
27
  assignReference(reference: string, inputValue: unknown, currentValue: unknown, options?: {
@@ -25,7 +29,7 @@ export declare class ReferenceRuntime {
25
29
  }): void;
26
30
  private assignCurrentReference;
27
31
  clearListElementState(listKey: string): void;
28
- resolveMappedValue(template: unknown, currentValue: unknown, responseValue: unknown): unknown;
32
+ resolveMappedValue(template: unknown, currentValue: unknown, responseValue: unknown, inputValue?: unknown): unknown;
29
33
  isListElementContext(value: unknown): value is ListElementContext;
30
34
  findNamedWidget(node: DescriptionNode | undefined, name: string, currentValue?: unknown): DescriptionNode | null;
31
35
  private resolveListDescriptorNode;
@@ -1,8 +1,8 @@
1
- import type { ActionMap, DescriptionNode, I18nMap, RequestMap, RouteDefinition, RoutesConfigInput, SseConfig, SystemEventsMap, StyleMap } from './types.js';
1
+ import type { ActionMap, ActionMapInput, DescriptionNode, I18nMap, RequestMap, RequestMapInput, RouteDefinition, RoutesConfigInput, SseConfig, SystemEventsMap, StyleMap } from './types.js';
2
2
  export type ResourceManagerInput = {
3
3
  ui?: Record<string, DescriptionNode>;
4
- actions?: ActionMap;
5
- requests?: RequestMap;
4
+ actions?: ActionMapInput;
5
+ requests?: RequestMapInput;
6
6
  routes?: RoutesConfigInput;
7
7
  sse?: Record<string, SseConfig>;
8
8
  systemEvents?: SystemEventsMap;
@@ -93,6 +93,12 @@ export type StyleMap = Record<string, string>;
93
93
  export type I18nMap = Record<string, Record<string, string>>;
94
94
  export type ActionMap = Record<string, ActionDefinition[]>;
95
95
  export type RequestMap = Record<string, RequestDefinition>;
96
+ export type ActionMapInput = {
97
+ [key: string]: ActionDefinition[] | ActionMapInput;
98
+ };
99
+ export type RequestMapInput = {
100
+ [key: string]: RequestDefinition | RequestMapInput;
101
+ };
96
102
  export type SseConfigInput = SseConfig | SseConfig[];
97
103
  export type SystemEventsMap = Partial<Record<SystemEventName, ActionDefinition[]>>;
98
104
  export type WidgetState = {
@@ -145,8 +151,8 @@ export type RenderJsonOptions = {
145
151
  language?: string;
146
152
  theme?: Theme;
147
153
  debugLogging?: boolean;
148
- actionsMap?: ActionMap;
149
- requestsMap?: RequestMap;
154
+ actionsMap?: ActionMapInput;
155
+ requestsMap?: RequestMapInput;
150
156
  sseConfigs?: SseConfigInput;
151
157
  systemEvents?: SystemEventsMap;
152
158
  routes?: RoutesConfigInput;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vortexm/vjt",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",