@bluelibs/runner-dev 5.3.0 → 6.0.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 (139) hide show
  1. package/AI.md +25 -3
  2. package/README.md +153 -18
  3. package/dist/cli/generators/scaffold/templates/package.json.d.ts +2 -2
  4. package/dist/cli/generators/scaffold/templates/package.json.js +2 -2
  5. package/dist/cli/generators/scaffold.js +1 -135
  6. package/dist/cli/generators/scaffold.js.map +1 -1
  7. package/dist/cli/generators/templates.js +2 -1
  8. package/dist/cli/generators/templates.js.map +1 -1
  9. package/dist/generated/resolvers-types.d.ts +376 -144
  10. package/dist/index.d.ts +39 -43
  11. package/dist/resources/cli.config.resource.d.ts +1 -1
  12. package/dist/resources/cli.config.resource.js +2 -2
  13. package/dist/resources/cli.config.resource.js.map +1 -1
  14. package/dist/resources/coverage.resource.d.ts +2 -2
  15. package/dist/resources/coverage.resource.js +3 -3
  16. package/dist/resources/coverage.resource.js.map +1 -1
  17. package/dist/resources/dev.resource.d.ts +1 -1
  18. package/dist/resources/dev.resource.js +2 -2
  19. package/dist/resources/dev.resource.js.map +1 -1
  20. package/dist/resources/docs.generator.resource.d.ts +4 -4
  21. package/dist/resources/docs.generator.resource.js +2 -2
  22. package/dist/resources/docs.generator.resource.js.map +1 -1
  23. package/dist/resources/graphql-accumulator.resource.d.ts +2 -2
  24. package/dist/resources/graphql-accumulator.resource.js +6 -3
  25. package/dist/resources/graphql-accumulator.resource.js.map +1 -1
  26. package/dist/resources/graphql.cli.resource.d.ts +1 -1
  27. package/dist/resources/graphql.cli.resource.js +2 -2
  28. package/dist/resources/graphql.cli.resource.js.map +1 -1
  29. package/dist/resources/graphql.query.cli.task.d.ts +14 -16
  30. package/dist/resources/graphql.query.cli.task.js +3 -3
  31. package/dist/resources/graphql.query.cli.task.js.map +1 -1
  32. package/dist/resources/graphql.query.task.d.ts +18 -20
  33. package/dist/resources/graphql.query.task.js +4 -4
  34. package/dist/resources/graphql.query.task.js.map +1 -1
  35. package/dist/resources/http.tag.d.ts +1 -1
  36. package/dist/resources/http.tag.js +2 -2
  37. package/dist/resources/http.tag.js.map +1 -1
  38. package/dist/resources/introspector.cli.resource.d.ts +2 -2
  39. package/dist/resources/introspector.cli.resource.js +14 -6
  40. package/dist/resources/introspector.cli.resource.js.map +1 -1
  41. package/dist/resources/introspector.resource.d.ts +3 -3
  42. package/dist/resources/introspector.resource.js +4 -5
  43. package/dist/resources/introspector.resource.js.map +1 -1
  44. package/dist/resources/live.resource.d.ts +4 -6
  45. package/dist/resources/live.resource.js +38 -25
  46. package/dist/resources/live.resource.js.map +1 -1
  47. package/dist/resources/models/Introspector.d.ts +28 -14
  48. package/dist/resources/models/Introspector.js +334 -161
  49. package/dist/resources/models/Introspector.js.map +1 -1
  50. package/dist/resources/models/durable.runtime.js +36 -10
  51. package/dist/resources/models/durable.runtime.js.map +1 -1
  52. package/dist/resources/models/durable.tools.d.ts +1 -1
  53. package/dist/resources/models/durable.tools.js +6 -3
  54. package/dist/resources/models/durable.tools.js.map +1 -1
  55. package/dist/resources/models/initializeFromStore.js +54 -21
  56. package/dist/resources/models/initializeFromStore.js.map +1 -1
  57. package/dist/resources/models/initializeFromStore.utils.d.ts +7 -6
  58. package/dist/resources/models/initializeFromStore.utils.js +302 -25
  59. package/dist/resources/models/initializeFromStore.utils.js.map +1 -1
  60. package/dist/resources/models/introspector.tools.js +18 -6
  61. package/dist/resources/models/introspector.tools.js.map +1 -1
  62. package/dist/resources/routeHandlers/getDocsData.d.ts +4 -0
  63. package/dist/resources/routeHandlers/getDocsData.js +28 -0
  64. package/dist/resources/routeHandlers/getDocsData.js.map +1 -1
  65. package/dist/resources/routeHandlers/registerHttpRoutes.hook.d.ts +26 -25
  66. package/dist/resources/routeHandlers/registerHttpRoutes.hook.js +10 -9
  67. package/dist/resources/routeHandlers/registerHttpRoutes.hook.js.map +1 -1
  68. package/dist/resources/server.resource.d.ts +20 -22
  69. package/dist/resources/server.resource.js +6 -6
  70. package/dist/resources/server.resource.js.map +1 -1
  71. package/dist/resources/swap.cli.resource.d.ts +4 -4
  72. package/dist/resources/swap.cli.resource.js +2 -2
  73. package/dist/resources/swap.cli.resource.js.map +1 -1
  74. package/dist/resources/swap.resource.d.ts +7 -7
  75. package/dist/resources/swap.resource.js +188 -38
  76. package/dist/resources/swap.resource.js.map +1 -1
  77. package/dist/resources/swap.tools.d.ts +3 -2
  78. package/dist/resources/swap.tools.js +27 -27
  79. package/dist/resources/swap.tools.js.map +1 -1
  80. package/dist/resources/telemetry.resource.d.ts +1 -1
  81. package/dist/resources/telemetry.resource.js +46 -43
  82. package/dist/resources/telemetry.resource.js.map +1 -1
  83. package/dist/runner-compat.d.ts +85 -0
  84. package/dist/runner-compat.js +178 -0
  85. package/dist/runner-compat.js.map +1 -0
  86. package/dist/runner-node-compat.d.ts +2 -0
  87. package/dist/runner-node-compat.js +28 -0
  88. package/dist/runner-node-compat.js.map +1 -0
  89. package/dist/schema/index.js +4 -8
  90. package/dist/schema/index.js.map +1 -1
  91. package/dist/schema/model.d.ts +80 -23
  92. package/dist/schema/model.js.map +1 -1
  93. package/dist/schema/query.js +2 -1
  94. package/dist/schema/query.js.map +1 -1
  95. package/dist/schema/types/AllType.js +6 -3
  96. package/dist/schema/types/AllType.js.map +1 -1
  97. package/dist/schema/types/BaseElementCommon.js +2 -2
  98. package/dist/schema/types/ErrorType.js +1 -1
  99. package/dist/schema/types/ErrorType.js.map +1 -1
  100. package/dist/schema/types/EventType.js +19 -2
  101. package/dist/schema/types/EventType.js.map +1 -1
  102. package/dist/schema/types/LaneSummaryTypes.d.ts +3 -0
  103. package/dist/schema/types/LaneSummaryTypes.js +19 -0
  104. package/dist/schema/types/LaneSummaryTypes.js.map +1 -0
  105. package/dist/schema/types/LiveType.js +67 -0
  106. package/dist/schema/types/LiveType.js.map +1 -1
  107. package/dist/schema/types/ResourceType.js +100 -19
  108. package/dist/schema/types/ResourceType.js.map +1 -1
  109. package/dist/schema/types/RunOptionsType.js +41 -5
  110. package/dist/schema/types/RunOptionsType.js.map +1 -1
  111. package/dist/schema/types/TagType.js +35 -4
  112. package/dist/schema/types/TagType.js.map +1 -1
  113. package/dist/schema/types/TaskType.js +5 -0
  114. package/dist/schema/types/TaskType.js.map +1 -1
  115. package/dist/schema/types/index.d.ts +2 -2
  116. package/dist/schema/types/index.js +6 -7
  117. package/dist/schema/types/index.js.map +1 -1
  118. package/dist/schema/types/middleware/common.d.ts +3 -2
  119. package/dist/schema/types/middleware/common.js +19 -13
  120. package/dist/schema/types/middleware/common.js.map +1 -1
  121. package/dist/ui/.vite/manifest.json +2 -2
  122. package/dist/ui/assets/docs-Btkv97Ls.js +302 -0
  123. package/dist/ui/assets/docs-Btkv97Ls.js.map +1 -0
  124. package/dist/ui/assets/docs-CipvKUxZ.css +1 -0
  125. package/dist/utils/lane-resources.d.ts +55 -0
  126. package/dist/utils/lane-resources.js +143 -0
  127. package/dist/utils/lane-resources.js.map +1 -0
  128. package/dist/utils/zod.js +36 -3
  129. package/dist/utils/zod.js.map +1 -1
  130. package/dist/version.d.ts +1 -1
  131. package/dist/version.js +1 -1
  132. package/package.json +4 -4
  133. package/readmes/runner-AI.md +740 -0
  134. package/readmes/runner-durable-workflows.md +2247 -0
  135. package/readmes/runner-full-guide.md +5869 -0
  136. package/readmes/runner-remote-lanes.md +909 -0
  137. package/dist/ui/assets/docs-BhRuaJ5l.css +0 -1
  138. package/dist/ui/assets/docs-H4oDZj7p.js +0 -302
  139. package/dist/ui/assets/docs-H4oDZj7p.js.map +0 -1
@@ -3,8 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Introspector = void 0;
4
4
  const introspector_tools_1 = require("./introspector.tools");
5
5
  const durable_tools_1 = require("./durable.tools");
6
- const extractTunnelInfo_1 = require("./extractTunnelInfo");
7
- const tunnel_tools_1 = require("./tunnel.tools");
6
+ const lane_resources_1 = require("../../utils/lane-resources");
8
7
  class Introspector {
9
8
  tasks = [];
10
9
  hooks = [];
@@ -49,18 +48,135 @@ class Introspector {
49
48
  this.initializeFromData(input.data);
50
49
  }
51
50
  }
51
+ idsMatch(candidateId, referenceId) {
52
+ return (candidateId === referenceId || candidateId.endsWith(`.${referenceId}`));
53
+ }
54
+ resolveCanonicalId(referenceId, candidateIds) {
55
+ const direct = candidateIds.find((candidateId) => candidateId === referenceId);
56
+ if (direct)
57
+ return direct;
58
+ const suffixMatch = candidateIds.find((candidateId) => this.idsMatch(candidateId, referenceId));
59
+ return suffixMatch ?? referenceId;
60
+ }
61
+ canonicalizeReferenceArray(ids, candidateIds) {
62
+ return (0, introspector_tools_1.ensureStringArray)(ids).map((referenceId) => this.resolveCanonicalId(referenceId, candidateIds));
63
+ }
64
+ findByIdLike(collection, id) {
65
+ return collection.find((entry) => this.idsMatch(entry.id, id)) ?? null;
66
+ }
67
+ idsContainLike(ids, candidateId) {
68
+ return (0, introspector_tools_1.ensureStringArray)(ids).some((id) => this.idsMatch(candidateId, id));
69
+ }
70
+ normalizeMetaTags(node, tagIds) {
71
+ const meta = node.meta;
72
+ if (!meta)
73
+ return;
74
+ const normalizedDetailed = Array.isArray(meta.tagsDetailed)
75
+ ? meta.tagsDetailed.map((entry) => ({
76
+ ...entry,
77
+ id: this.resolveCanonicalId(entry.id, tagIds),
78
+ }))
79
+ : meta.tagsDetailed;
80
+ node.meta = {
81
+ ...meta,
82
+ tags: this.canonicalizeReferenceArray(meta.tags, tagIds),
83
+ tagsDetailed: normalizedDetailed,
84
+ };
85
+ }
86
+ normalizeRelationIds() {
87
+ const taskIds = this.tasks.map((entry) => entry.id);
88
+ const hookIds = this.hooks.map((entry) => entry.id);
89
+ const resourceIds = this.resources.map((entry) => entry.id);
90
+ const eventIds = this.events.map((entry) => entry.id);
91
+ const middlewareIds = this.middlewares.map((entry) => entry.id);
92
+ const tagIds = this.tags.map((entry) => entry.id);
93
+ const errorIds = this.errors.map((entry) => entry.id);
94
+ const asyncContextIds = this.asyncContexts.map((entry) => entry.id);
95
+ const allDependencyIds = [
96
+ ...taskIds,
97
+ ...hookIds,
98
+ ...resourceIds,
99
+ ...eventIds,
100
+ ...middlewareIds,
101
+ ...tagIds,
102
+ ...errorIds,
103
+ ...asyncContextIds,
104
+ ];
105
+ const taskLikeIds = [...taskIds, ...hookIds];
106
+ const taskHookResourceMiddlewareIds = [
107
+ ...taskIds,
108
+ ...hookIds,
109
+ ...resourceIds,
110
+ ...middlewareIds,
111
+ ];
112
+ for (const task of this.tasks) {
113
+ task.dependsOn = this.canonicalizeReferenceArray(task.dependsOn, allDependencyIds);
114
+ task.tags = this.canonicalizeReferenceArray(task.tags, tagIds);
115
+ task.emits = this.canonicalizeReferenceArray(task.emits, eventIds);
116
+ task.middleware = this.canonicalizeReferenceArray(task.middleware, middlewareIds);
117
+ this.normalizeMetaTags(task, tagIds);
118
+ }
119
+ for (const hook of this.hooks) {
120
+ hook.dependsOn = this.canonicalizeReferenceArray(hook.dependsOn, allDependencyIds);
121
+ hook.tags = this.canonicalizeReferenceArray(hook.tags, tagIds);
122
+ hook.emits = this.canonicalizeReferenceArray(hook.emits, eventIds);
123
+ hook.events = this.canonicalizeReferenceArray(hook.events, eventIds);
124
+ const hookWithMiddleware = hook;
125
+ hookWithMiddleware.middleware = this.canonicalizeReferenceArray(hookWithMiddleware.middleware, middlewareIds);
126
+ this.normalizeMetaTags(hook, tagIds);
127
+ }
128
+ for (const resource of this.resources) {
129
+ resource.dependsOn = this.canonicalizeReferenceArray(resource.dependsOn, allDependencyIds);
130
+ resource.tags = this.canonicalizeReferenceArray(resource.tags, tagIds);
131
+ resource.emits = this.canonicalizeReferenceArray(resource.emits, eventIds);
132
+ resource.middleware = this.canonicalizeReferenceArray(resource.middleware, middlewareIds);
133
+ resource.overrides = this.canonicalizeReferenceArray(resource.overrides, taskHookResourceMiddlewareIds);
134
+ resource.registers = this.canonicalizeReferenceArray(resource.registers, taskHookResourceMiddlewareIds);
135
+ this.normalizeMetaTags(resource, tagIds);
136
+ }
137
+ for (const middleware of this.middlewares) {
138
+ middleware.tags = this.canonicalizeReferenceArray(middleware.tags, tagIds);
139
+ const middlewareWithEmits = middleware;
140
+ middlewareWithEmits.emits = this.canonicalizeReferenceArray(middlewareWithEmits.emits, eventIds);
141
+ middleware.usedByTasks = this.canonicalizeReferenceArray(middleware.usedByTasks, taskLikeIds);
142
+ middleware.usedByResources = this.canonicalizeReferenceArray(middleware.usedByResources, resourceIds);
143
+ this.normalizeMetaTags(middleware, tagIds);
144
+ }
145
+ for (const event of this.events) {
146
+ event.tags = this.canonicalizeReferenceArray(event.tags, tagIds);
147
+ event.listenedToBy = this.canonicalizeReferenceArray(event.listenedToBy, hookIds);
148
+ this.normalizeMetaTags(event, tagIds);
149
+ }
150
+ for (const error of this.errors) {
151
+ error.tags = this.canonicalizeReferenceArray(error.tags, tagIds);
152
+ error.thrownBy = this.canonicalizeReferenceArray(error.thrownBy, taskHookResourceMiddlewareIds);
153
+ this.normalizeMetaTags(error, tagIds);
154
+ }
155
+ for (const asyncContext of this.asyncContexts) {
156
+ asyncContext.usedBy = this.canonicalizeReferenceArray(asyncContext.usedBy, taskHookResourceMiddlewareIds);
157
+ asyncContext.requiredBy = this.canonicalizeReferenceArray(asyncContext.requiredBy, taskIds);
158
+ asyncContext.providedBy = this.canonicalizeReferenceArray(asyncContext.providedBy, resourceIds);
159
+ this.normalizeMetaTags(asyncContext, tagIds);
160
+ }
161
+ }
162
+ finalizeDerivedState() {
163
+ this.normalizeRelationIds();
164
+ this.populateErrorThrownBy();
165
+ }
52
166
  initializeFromData(data) {
53
167
  this.tasks = Array.isArray(data.tasks) ? data.tasks : [];
54
168
  this.hooks = Array.isArray(data.hooks) ? data.hooks : [];
55
169
  this.resources = Array.isArray(data.resources) ? data.resources : [];
56
170
  this.events = Array.isArray(data.events) ? data.events : [];
57
- this.taskMiddlewares = [];
58
- this.resourceMiddlewares = [];
59
171
  this.middlewares = Array.isArray(data.middlewares) ? data.middlewares : [];
172
+ const splitMiddlewares = this.splitMiddlewaresByType(this.middlewares);
173
+ this.taskMiddlewares = splitMiddlewares.taskMiddlewares;
174
+ this.resourceMiddlewares = splitMiddlewares.resourceMiddlewares;
60
175
  this.errors = Array.isArray(data.errors) ? data.errors : [];
61
176
  this.asyncContexts = Array.isArray(data.asyncContexts)
62
177
  ? data.asyncContexts
63
178
  : [];
179
+ this.tags = Array.isArray(data.tags) ? data.tags : [];
64
180
  this.rootId = data.rootId ?? null;
65
181
  this.runOptions = data.runOptions
66
182
  ? this.normalizeRunOptions(data.runOptions)
@@ -74,20 +190,39 @@ class Introspector {
74
190
  this.middlewareMap = (0, introspector_tools_1.buildIdMap)(this.middlewares);
75
191
  this.errorMap = (0, introspector_tools_1.buildIdMap)(this.errors);
76
192
  this.asyncContextMap = (0, introspector_tools_1.buildIdMap)(this.asyncContexts);
77
- // Populate thrownBy for errors based on dependencies (after maps are built)
78
- this.populateErrorThrownBy();
79
- // Tags
80
- const _getTasksWithTag = (tagId) => this.tasks.filter((t) => (0, introspector_tools_1.ensureStringArray)(t.tags).includes(tagId));
81
- const _getHooksWithTag = (tagId) => this.hooks.filter((h) => (0, introspector_tools_1.ensureStringArray)(h.tags).includes(tagId));
82
- const _getResourcesWithTag = (tagId) => this.resources.filter((r) => (0, introspector_tools_1.ensureStringArray)(r.tags).includes(tagId));
83
- const _getMiddlewaresWithTag = (tagId) => this.middlewares.filter((m) => (0, introspector_tools_1.ensureStringArray)(m.tags).includes(tagId));
84
- const _getEventsWithTag = (tagId) => this.events.filter((e) => (0, introspector_tools_1.ensureStringArray)(e.tags).includes(tagId));
85
- this.tags = data.tags;
193
+ this.finalizeDerivedState();
86
194
  this.tagMap = new Map();
87
195
  for (const tag of this.tags) {
88
196
  this.tagMap.set(tag.id, tag);
89
197
  }
90
198
  }
199
+ splitMiddlewaresByType(middlewares) {
200
+ const taskMiddlewares = [];
201
+ const resourceMiddlewares = [];
202
+ for (const middleware of middlewares) {
203
+ if (middleware.type === "task") {
204
+ taskMiddlewares.push(middleware);
205
+ continue;
206
+ }
207
+ if (middleware.type === "resource") {
208
+ resourceMiddlewares.push(middleware);
209
+ continue;
210
+ }
211
+ const usedByTasksLength = Array.isArray(middleware.usedByTasks)
212
+ ? middleware.usedByTasks.length
213
+ : 0;
214
+ const usedByResourcesLength = Array.isArray(middleware.usedByResources)
215
+ ? middleware.usedByResources.length
216
+ : 0;
217
+ if (usedByTasksLength > 0 || usedByResourcesLength === 0) {
218
+ taskMiddlewares.push(middleware);
219
+ }
220
+ else {
221
+ resourceMiddlewares.push(middleware);
222
+ }
223
+ }
224
+ return { taskMiddlewares, resourceMiddlewares };
225
+ }
91
226
  // Helper function for building runs options
92
227
  buildRunsOptions(nodeId, args) {
93
228
  const opts = {};
@@ -111,9 +246,8 @@ class Introspector {
111
246
  }
112
247
  // API Methods
113
248
  getRoot() {
114
- const s = this.store;
115
- const idFromStore = s?.root?.resource?.id
116
- ? String(s.root.resource.id)
249
+ const idFromStore = this.store?.root?.resource?.id
250
+ ? String(this.store.root.resource.id)
117
251
  : null;
118
252
  const id = idFromStore ?? this.rootId ?? this.resources[0]?.id;
119
253
  return (0, introspector_tools_1.stampElementKind)(this.resourceMap.get(String(id)), "RESOURCE");
@@ -124,12 +258,30 @@ class Introspector {
124
258
  * the previously serialized snapshot is used.
125
259
  */
126
260
  normalizeRunOptions(runOptions) {
261
+ const legacyRunOptions = runOptions;
127
262
  const mode = runOptions.mode ?? "dev";
128
263
  const debug = Boolean(runOptions.debug);
129
264
  const rootId = runOptions.rootId ?? this.rootId ?? "";
130
265
  const logsPrintThreshold = runOptions.logsPrintThreshold !== undefined
131
266
  ? runOptions.logsPrintThreshold
132
267
  : "info";
268
+ const dispose = runOptions.dispose ??
269
+ {
270
+ totalBudgetMs: typeof legacyRunOptions.disposeBudgetMs === "number"
271
+ ? legacyRunOptions.disposeBudgetMs
272
+ : null,
273
+ drainingBudgetMs: typeof legacyRunOptions.disposeDrainBudgetMs === "number"
274
+ ? legacyRunOptions.disposeDrainBudgetMs
275
+ : null,
276
+ cooldownWindowMs: null,
277
+ };
278
+ const executionContext = runOptions.executionContext ??
279
+ {
280
+ enabled: false,
281
+ cycleDetection: typeof legacyRunOptions.runtimeEventCycleDetection === "boolean"
282
+ ? legacyRunOptions.runtimeEventCycleDetection
283
+ : null,
284
+ };
133
285
  return {
134
286
  mode,
135
287
  debug,
@@ -150,22 +302,20 @@ class Introspector {
150
302
  : null,
151
303
  dryRun: Boolean(runOptions.dryRun),
152
304
  lazy: Boolean(runOptions.lazy),
153
- initMode: runOptions.initMode === "parallel" ? "parallel" : "sequential",
154
- runtimeEventCycleDetection: runOptions.runtimeEventCycleDetection !== undefined
155
- ? runOptions.runtimeEventCycleDetection
156
- : null,
305
+ lifecycleMode: runOptions.lifecycleMode === "parallel" ? "parallel" : "sequential",
306
+ dispose,
307
+ executionContext,
157
308
  hasOnUnhandledError: Boolean(runOptions.hasOnUnhandledError),
158
309
  rootId,
159
310
  };
160
311
  }
161
312
  getRunOptions() {
162
313
  if (this.store) {
163
- const sAny = this.store;
164
- const rootId = sAny.root?.resource?.id != null
165
- ? String(sAny.root.resource.id)
314
+ const rootId = this.store.root?.resource?.id != null
315
+ ? String(this.store.root.resource.id)
166
316
  : this.rootId ?? "";
167
- const hasDebug = !!sAny.resources?.has?.("globals.resources.debug");
168
- const debugResource = sAny.resources?.get?.("globals.resources.debug");
317
+ const hasDebug = this.store.resources.has("runner.debug");
318
+ const debugResource = this.store.resources.get("runner.debug");
169
319
  const debugConfig = debugResource?.config;
170
320
  const debugMode = !hasDebug
171
321
  ? "disabled"
@@ -176,7 +326,7 @@ class Introspector {
176
326
  : debugConfig && typeof debugConfig === "object"
177
327
  ? "custom"
178
328
  : "normal";
179
- const loggerResource = sAny.resources?.get?.("globals.resources.logger");
329
+ const loggerResource = this.store.resources.get("runner.logger");
180
330
  const logger = loggerResource?.value;
181
331
  const logsPrintThresholdRaw = logger?.printThreshold;
182
332
  const logsPrintStrategyRaw = logger?.printStrategy;
@@ -184,31 +334,50 @@ class Introspector {
184
334
  const logsPrintThreshold = logsPrintThresholdRaw == null ? null : String(logsPrintThresholdRaw);
185
335
  const logsPrintStrategy = logsPrintStrategyRaw == null ? null : String(logsPrintStrategyRaw);
186
336
  const logsBuffer = Boolean(logsBufferRaw);
187
- const initMode = sAny.preferInitOrderDisposal ? "sequential" : "parallel";
188
- const runtimeAny = this.runtime;
189
- const lazy = Boolean(runtimeAny?.lazyOptions?.lazyMode);
190
- const runtimeEventCycleDetection = runtimeAny?.eventManager?.runtimeEventCycleDetection;
191
- return {
192
- mode: sAny.mode ?? "dev",
337
+ const runtimeRunOptions = this.runtime?.runOptions;
338
+ return this.normalizeRunOptions({
339
+ mode: this.store.mode ?? "dev",
193
340
  debug: hasDebug,
194
341
  debugMode,
195
342
  logsEnabled: logsPrintThreshold !== null,
196
343
  logsPrintThreshold,
197
344
  logsPrintStrategy,
198
345
  logsBuffer,
199
- errorBoundary: null,
200
- shutdownHooks: null,
201
- dryRun: Boolean(this.runOptions?.dryRun),
202
- lazy,
203
- initMode,
204
- runtimeEventCycleDetection: typeof runtimeEventCycleDetection === "boolean"
205
- ? runtimeEventCycleDetection
346
+ errorBoundary: typeof runtimeRunOptions?.errorBoundary === "boolean"
347
+ ? runtimeRunOptions.errorBoundary
348
+ : null,
349
+ shutdownHooks: typeof runtimeRunOptions?.shutdownHooks === "boolean"
350
+ ? runtimeRunOptions.shutdownHooks
206
351
  : null,
207
- hasOnUnhandledError: typeof sAny.onUnhandledError === "function",
352
+ dryRun: Boolean(runtimeRunOptions?.dryRun),
353
+ lazy: Boolean(runtimeRunOptions?.lazy),
354
+ lifecycleMode: runtimeRunOptions?.lifecycleMode === "parallel"
355
+ ? "parallel"
356
+ : "sequential",
357
+ dispose: {
358
+ totalBudgetMs: typeof runtimeRunOptions?.dispose?.totalBudgetMs === "number"
359
+ ? runtimeRunOptions.dispose.totalBudgetMs
360
+ : null,
361
+ drainingBudgetMs: typeof runtimeRunOptions?.dispose?.drainingBudgetMs === "number"
362
+ ? runtimeRunOptions.dispose.drainingBudgetMs
363
+ : null,
364
+ cooldownWindowMs: typeof runtimeRunOptions?.dispose?.cooldownWindowMs === "number"
365
+ ? runtimeRunOptions.dispose.cooldownWindowMs
366
+ : null,
367
+ },
368
+ executionContext: {
369
+ enabled: runtimeRunOptions?.executionContext != null,
370
+ cycleDetection: runtimeRunOptions?.executionContext == null
371
+ ? null
372
+ : typeof runtimeRunOptions.executionContext.cycleDetection ===
373
+ "boolean"
374
+ ? runtimeRunOptions.executionContext.cycleDetection
375
+ : runtimeRunOptions.executionContext.cycleDetection != null,
376
+ },
377
+ hasOnUnhandledError: typeof this.store.onUnhandledError === "function",
208
378
  rootId,
209
- };
379
+ });
210
380
  }
211
- // Fallback to serialized data
212
381
  if (this.runOptions)
213
382
  return this.normalizeRunOptions(this.runOptions);
214
383
  return this.normalizeRunOptions({
@@ -231,9 +400,9 @@ class Introspector {
231
400
  populateErrorThrownBy() {
232
401
  // Create error ID map for quick lookup
233
402
  const errorIds = new Set(this.errors.map((e) => e.id));
234
- // Clear existing thrownBy arrays
403
+ // Preserve preloaded producer data and only append derived dependencies.
235
404
  this.errors.forEach((error) => {
236
- error.thrownBy = [];
405
+ error.thrownBy = (0, introspector_tools_1.ensureStringArray)(error.thrownBy);
237
406
  });
238
407
  // Check tasks
239
408
  this.tasks.forEach((task) => {
@@ -296,29 +465,28 @@ class Introspector {
296
465
  return this.resources;
297
466
  }
298
467
  getEvent(id) {
299
- return this.eventMap.get(id) ?? null;
468
+ return this.eventMap.get(id) ?? this.findByIdLike(this.events, id);
300
469
  }
301
470
  getTask(id) {
302
- return this.taskMap.get(id) ?? null;
471
+ return this.taskMap.get(id) ?? this.findByIdLike(this.tasks, id);
303
472
  }
304
473
  getHook(id) {
305
- return this.hookMap.get(id) ?? null;
474
+ return this.hookMap.get(id) ?? this.findByIdLike(this.hooks, id);
306
475
  }
307
476
  getMiddleware(id) {
308
- return this.middlewareMap.get(id) ?? null;
477
+ return (this.middlewareMap.get(id) ?? this.findByIdLike(this.middlewares, id));
309
478
  }
310
479
  getResource(id) {
311
- return this.resourceMap.get(id) ?? null;
480
+ return this.resourceMap.get(id) ?? this.findByIdLike(this.resources, id);
312
481
  }
313
482
  getDependencies(node) {
314
483
  const depends = (0, introspector_tools_1.ensureStringArray)(node.dependsOn);
315
- const tasksDeps = this.tasks.filter((t) => depends.includes(t.id));
316
- const hooksDeps = this.hooks.filter((l) => depends.includes(l.id));
317
- const resourcesDeps = this.resources.filter((r) => depends.includes(r.id));
318
- const errorDeps = this.errors.filter((e) => depends.includes(e.id));
319
- // Only Task and Hook have emits, Resource doesn't
484
+ const tasksDeps = this.tasks.filter((t) => this.idsContainLike(depends, t.id));
485
+ const hooksDeps = this.hooks.filter((l) => this.idsContainLike(depends, l.id));
486
+ const resourcesDeps = this.resources.filter((r) => this.idsContainLike(depends, r.id));
487
+ const errorDeps = this.errors.filter((e) => this.idsContainLike(depends, e.id));
320
488
  const emitIds = (0, introspector_tools_1.ensureStringArray)(node.emits);
321
- const emitEvents = this.events.filter((e) => emitIds.includes(e.id));
489
+ const emitEvents = this.events.filter((e) => this.idsContainLike(emitIds, e.id));
322
490
  return {
323
491
  tasks: tasksDeps,
324
492
  hooks: hooksDeps,
@@ -329,33 +497,28 @@ class Introspector {
329
497
  }
330
498
  getEmittedEvents(node) {
331
499
  const emits = (0, introspector_tools_1.ensureStringArray)(node.emits);
332
- return this.events.filter((e) => emits.includes(e.id));
500
+ return this.events.filter((e) => this.idsContainLike(emits, e.id));
333
501
  }
334
502
  getMiddlewaresByIds(ids) {
335
- const set = new Set((0, introspector_tools_1.ensureStringArray)(ids));
336
- return this.middlewares.filter((m) => set.has(m.id));
503
+ return this.middlewares.filter((m) => this.idsContainLike(ids, m.id));
337
504
  }
338
505
  getResourcesByIds(ids) {
339
- const set = new Set((0, introspector_tools_1.ensureStringArray)(ids));
340
- return this.resources.filter((r) => set.has(r.id));
506
+ return this.resources.filter((r) => this.idsContainLike(ids, r.id));
341
507
  }
342
508
  getTasksByIds(ids) {
343
- const set = new Set((0, introspector_tools_1.ensureStringArray)(ids));
344
- return this.tasks.filter((t) => set.has(t.id));
509
+ return this.tasks.filter((t) => this.idsContainLike(ids, t.id));
345
510
  }
346
511
  getHooksByIds(ids) {
347
- const set = new Set((0, introspector_tools_1.ensureStringArray)(ids));
348
- return this.hooks.filter((l) => set.has(l.id));
512
+ return this.hooks.filter((l) => this.idsContainLike(ids, l.id));
349
513
  }
350
514
  getEventsByIds(ids) {
351
- const set = new Set((0, introspector_tools_1.ensureStringArray)(ids));
352
- return this.events.filter((e) => set.has(e.id));
515
+ return this.events.filter((e) => this.idsContainLike(ids, e.id));
353
516
  }
354
517
  getTasksUsingResource(resourceId) {
355
- return [...this.tasks, ...this.hooks].filter((t) => (0, introspector_tools_1.ensureStringArray)(t.dependsOn).includes(resourceId));
518
+ return [...this.tasks, ...this.hooks].filter((t) => this.idsContainLike(t.dependsOn, resourceId));
356
519
  }
357
520
  getTasksUsingMiddleware(middlewareId) {
358
- return this.tasks.filter((t) => (0, introspector_tools_1.ensureStringArray)(t.middleware).includes(middlewareId));
521
+ return this.tasks.filter((t) => this.idsContainLike(t.middleware, middlewareId));
359
522
  }
360
523
  // Backward-compat for schema fields expecting this name
361
524
  // Returns only task-like nodes (tasks and hooks)
@@ -363,10 +526,10 @@ class Introspector {
363
526
  return this.getTasksUsingMiddleware(middlewareId);
364
527
  }
365
528
  getEmittersOfEvent(eventId) {
366
- return [...this.tasks, ...this.hooks, ...this.resources].filter((t) => (0, introspector_tools_1.ensureStringArray)(t.emits).includes(eventId));
529
+ return [...this.tasks, ...this.hooks, ...this.resources].filter((t) => this.idsContainLike(t.emits, eventId));
367
530
  }
368
531
  getHooksOfEvent(eventId) {
369
- return this.hooks.filter((l) => l.events.includes(eventId));
532
+ return this.hooks.filter((l) => this.idsContainLike(l.events, eventId));
370
533
  }
371
534
  getMiddlewareEmittedEvents(middlewareId) {
372
535
  const taskLikes = this.getTasksUsingMiddleware(middlewareId);
@@ -380,8 +543,12 @@ class Introspector {
380
543
  }
381
544
  getMiddlewareUsagesForTask(taskId) {
382
545
  const task = this.taskMap.get(taskId);
383
- if (!task)
384
- return [];
546
+ if (!task) {
547
+ const resolvedTask = this.getTask(taskId);
548
+ if (!resolvedTask)
549
+ return [];
550
+ return this.getMiddlewareUsagesForTask(resolvedTask.id);
551
+ }
385
552
  const detailed = task.middlewareDetailed ?? [];
386
553
  return detailed
387
554
  .map((d) => ({
@@ -393,8 +560,12 @@ class Introspector {
393
560
  }
394
561
  getMiddlewareUsagesForResource(resourceId) {
395
562
  const res = this.resourceMap.get(resourceId);
396
- if (!res)
397
- return [];
563
+ if (!res) {
564
+ const resolvedResource = this.getResource(resourceId);
565
+ if (!resolvedResource)
566
+ return [];
567
+ return this.getMiddlewareUsagesForResource(resolvedResource.id);
568
+ }
398
569
  const detailed = res.middlewareDetailed ?? [];
399
570
  return detailed
400
571
  .map((d) => ({
@@ -408,9 +579,8 @@ class Introspector {
408
579
  const result = [];
409
580
  const addFrom = (arr) => {
410
581
  for (const tl of arr) {
411
- if ((tl.middleware || []).includes(middlewareId)) {
412
- const conf = (tl.middlewareDetailed || []).find((m) => m.id === middlewareId)
413
- ?.config ?? null;
582
+ if (this.idsContainLike(tl.middleware, middlewareId)) {
583
+ const conf = (tl.middlewareDetailed || []).find((m) => this.idsMatch(this.resolveCanonicalId(m.id, this.middlewares.map((entry) => entry.id)), middlewareId))?.config ?? null;
414
584
  result.push({ id: tl.id, config: conf ?? null, node: tl });
415
585
  }
416
586
  }
@@ -421,9 +591,8 @@ class Introspector {
421
591
  getResourcesUsingMiddlewareDetailed(middlewareId) {
422
592
  const result = [];
423
593
  for (const r of this.resources) {
424
- if ((r.middleware || []).includes(middlewareId)) {
425
- const conf = (r.middlewareDetailed || []).find((m) => m.id === middlewareId)
426
- ?.config ?? null;
594
+ if (this.idsContainLike(r.middleware, middlewareId)) {
595
+ const conf = (r.middlewareDetailed || []).find((m) => this.idsMatch(this.resolveCanonicalId(m.id, this.middlewares.map((entry) => entry.id)), middlewareId))?.config ?? null;
427
596
  result.push({ id: r.id, config: conf ?? null, node: r });
428
597
  }
429
598
  }
@@ -440,25 +609,44 @@ class Introspector {
440
609
  }
441
610
  // Tags API
442
611
  getTasksWithTag(tagId) {
443
- return this.tasks.filter((t) => (0, introspector_tools_1.ensureStringArray)(t.tags).includes(tagId));
612
+ return this.tasks.filter((t) => this.idsContainLike(t.tags, tagId));
444
613
  }
445
614
  getHooksWithTag(tagId) {
446
- return this.hooks.filter((h) => (0, introspector_tools_1.ensureStringArray)(h.tags).includes(tagId));
615
+ return this.hooks.filter((h) => this.idsContainLike(h.tags, tagId));
447
616
  }
448
617
  getResourcesWithTag(tagId) {
449
- return this.resources.filter((r) => (0, introspector_tools_1.ensureStringArray)(r.tags).includes(tagId));
618
+ return this.resources.filter((r) => this.idsContainLike(r.tags, tagId));
450
619
  }
451
620
  getMiddlewaresWithTag(tagId) {
452
- return this.middlewares.filter((m) => (0, introspector_tools_1.ensureStringArray)(m.tags).includes(tagId));
621
+ return this.middlewares.filter((m) => this.idsContainLike(m.tags, tagId));
622
+ }
623
+ getTaskMiddlewaresWithTag(tagId) {
624
+ return this.taskMiddlewares.filter((m) => this.idsContainLike(m.tags, tagId));
625
+ }
626
+ getResourceMiddlewaresWithTag(tagId) {
627
+ return this.resourceMiddlewares.filter((m) => this.idsContainLike(m.tags, tagId));
453
628
  }
454
629
  getEventsWithTag(tagId) {
455
- return this.events.filter((e) => (0, introspector_tools_1.ensureStringArray)(e.tags).includes(tagId));
630
+ return this.events.filter((e) => this.idsContainLike(e.tags, tagId));
631
+ }
632
+ getErrorsWithTag(tagId) {
633
+ return this.errors
634
+ .filter((e) => this.idsContainLike(e.tags, tagId))
635
+ .map((error) => (0, introspector_tools_1.stampElementKind)(error, "ERROR"));
636
+ }
637
+ getTagHandlers(tagId) {
638
+ const dependsOnTag = (item) => this.idsContainLike(item.dependsOn, tagId);
639
+ return {
640
+ tasks: this.tasks.filter(dependsOnTag),
641
+ hooks: this.hooks.filter(dependsOnTag),
642
+ resources: this.resources.filter(dependsOnTag),
643
+ };
456
644
  }
457
645
  getAllTags() {
458
646
  return this.tags;
459
647
  }
460
648
  getTag(id) {
461
- return this.tagMap.get(id) ?? null;
649
+ return this.tagMap.get(id) ?? this.findByIdLike(this.tags, id);
462
650
  }
463
651
  getTagsByIds(ids) {
464
652
  return ids
@@ -495,34 +683,35 @@ class Introspector {
495
683
  }
496
684
  // Error-related methods
497
685
  getErrors() {
498
- return this.errors;
686
+ return this.errors.map((error) => (0, introspector_tools_1.stampElementKind)(error, "ERROR"));
499
687
  }
500
688
  getError(id) {
501
- return this.errorMap.get(id) ?? null;
689
+ const error = this.errorMap.get(id) ?? this.findByIdLike(this.errors, id);
690
+ return error ? (0, introspector_tools_1.stampElementKind)(error, "ERROR") : null;
502
691
  }
503
692
  getTasksUsingError(errorId) {
504
- const error = this.errorMap.get(errorId);
693
+ const error = this.getError(errorId);
505
694
  if (!error?.thrownBy)
506
695
  return [];
507
- return this.tasks.filter((task) => error.thrownBy.includes(task.id));
696
+ return this.tasks.filter((task) => this.idsContainLike(error.thrownBy, task.id));
508
697
  }
509
698
  getResourcesUsingError(errorId) {
510
- const error = this.errorMap.get(errorId);
699
+ const error = this.getError(errorId);
511
700
  if (!error?.thrownBy)
512
701
  return [];
513
- return this.resources.filter((resource) => error.thrownBy.includes(resource.id));
702
+ return this.resources.filter((resource) => this.idsContainLike(error.thrownBy, resource.id));
514
703
  }
515
704
  getHooksUsingError(errorId) {
516
- const error = this.errorMap.get(errorId);
705
+ const error = this.getError(errorId);
517
706
  if (!error?.thrownBy)
518
707
  return [];
519
- return this.hooks.filter((hook) => error.thrownBy.includes(hook.id));
708
+ return this.hooks.filter((hook) => this.idsContainLike(error.thrownBy, hook.id));
520
709
  }
521
710
  getMiddlewaresUsingError(errorId) {
522
- const error = this.errorMap.get(errorId);
711
+ const error = this.getError(errorId);
523
712
  if (!error?.thrownBy)
524
713
  return [];
525
- return this.middlewares.filter((middleware) => error.thrownBy.includes(middleware.id));
714
+ return this.middlewares.filter((middleware) => this.idsContainLike(error.thrownBy, middleware.id));
526
715
  }
527
716
  getAllUsingError(errorId) {
528
717
  return [
@@ -537,37 +726,37 @@ class Introspector {
537
726
  return this.asyncContexts;
538
727
  }
539
728
  getAsyncContext(id) {
540
- return this.asyncContextMap.get(id) ?? null;
729
+ return (this.asyncContextMap.get(id) ?? this.findByIdLike(this.asyncContexts, id));
541
730
  }
542
731
  getTasksUsingContext(contextId) {
543
- const context = this.asyncContextMap.get(contextId);
732
+ const context = this.getAsyncContext(contextId);
544
733
  if (!context?.usedBy)
545
734
  return [];
546
- return this.tasks.filter((task) => context.usedBy.includes(task.id));
735
+ return this.tasks.filter((task) => this.idsContainLike(context.usedBy, task.id));
547
736
  }
548
737
  getResourcesUsingContext(contextId) {
549
- const context = this.asyncContextMap.get(contextId);
738
+ const context = this.getAsyncContext(contextId);
550
739
  if (!context?.usedBy)
551
740
  return [];
552
- return this.resources.filter((resource) => context.usedBy.includes(resource.id));
741
+ return this.resources.filter((resource) => this.idsContainLike(context.usedBy, resource.id));
553
742
  }
554
743
  getResourcesProvidingContext(contextId) {
555
- const context = this.asyncContextMap.get(contextId);
744
+ const context = this.getAsyncContext(contextId);
556
745
  if (!context?.providedBy)
557
746
  return [];
558
- return this.resources.filter((resource) => context.providedBy.includes(resource.id));
747
+ return this.resources.filter((resource) => this.idsContainLike(context.providedBy, resource.id));
559
748
  }
560
749
  getHooksUsingContext(contextId) {
561
- const context = this.asyncContextMap.get(contextId);
750
+ const context = this.getAsyncContext(contextId);
562
751
  if (!context?.usedBy)
563
752
  return [];
564
- return this.hooks.filter((hook) => context.usedBy.includes(hook.id));
753
+ return this.hooks.filter((hook) => this.idsContainLike(context.usedBy, hook.id));
565
754
  }
566
755
  getMiddlewaresUsingContext(contextId) {
567
- const context = this.asyncContextMap.get(contextId);
756
+ const context = this.getAsyncContext(contextId);
568
757
  if (!context?.usedBy)
569
758
  return [];
570
- return this.middlewares.filter((middleware) => context.usedBy.includes(middleware.id));
759
+ return this.middlewares.filter((middleware) => this.idsContainLike(context.usedBy, middleware.id));
571
760
  }
572
761
  getAllUsingContext(contextId) {
573
762
  return [
@@ -581,73 +770,57 @@ class Introspector {
581
770
  * Returns tasks that use `.require()` for a given async context.
582
771
  */
583
772
  getTasksRequiringContext(contextId) {
584
- const context = this.asyncContextMap.get(contextId);
773
+ const context = this.getAsyncContext(contextId);
585
774
  if (!context?.requiredBy)
586
775
  return [];
587
- return this.tasks.filter((task) => context.requiredBy.includes(task.id));
776
+ return this.tasks.filter((task) => this.idsContainLike(context.requiredBy, task.id));
588
777
  }
589
778
  /**
590
779
  * Checks whether a given element uses `.require()` for a specific async context.
591
780
  */
592
781
  isContextRequiredBy(contextId, elementId) {
593
- const context = this.asyncContextMap.get(contextId);
594
- return context?.requiredBy?.includes(elementId) ?? false;
782
+ const context = this.getAsyncContext(contextId);
783
+ return this.idsContainLike(context?.requiredBy, elementId);
595
784
  }
596
- // Tunnel-related methods (enhance existing methods)
597
- getTunnelResources() {
598
- // Resources with populated tunnelInfo (set during store initialization)
599
- return this.resources.filter((resource) => resource.tunnelInfo != null);
785
+ // RPC lane-related methods
786
+ getRpcLanesResources() {
787
+ return this.resources.filter((resource) => (0, lane_resources_1.isRpcLanesResource)(resource));
600
788
  }
601
- getTunneledTasks(tunnelResourceId) {
602
- const tunnel = this.getResource(tunnelResourceId);
603
- if (!tunnel?.tunnelInfo?.tasks)
604
- return [];
605
- return this.getTasksByIds(tunnel.tunnelInfo.tasks);
789
+ getTasksByRpcLane(rpcLaneId) {
790
+ return this.tasks.filter((task) => task.rpcLane?.laneId === rpcLaneId);
606
791
  }
607
- getTunneledEvents(tunnelResourceId) {
608
- const tunnel = this.getResource(tunnelResourceId);
609
- if (!tunnel?.tunnelInfo?.events)
610
- return [];
611
- return this.getEventsByIds(tunnel.tunnelInfo.events);
792
+ getEventsByRpcLane(rpcLaneId) {
793
+ return this.events.filter((event) => event.rpcLane?.laneId === rpcLaneId);
612
794
  }
613
- getTunnelForTask(taskId) {
614
- const task = this.getTask(taskId);
615
- if (!task)
795
+ getRpcLaneForTask(taskId) {
796
+ return this.getTask(taskId)?.rpcLane?.laneId ?? null;
797
+ }
798
+ getRpcLaneForEvent(eventId) {
799
+ return this.getEvent(eventId)?.rpcLane?.laneId ?? null;
800
+ }
801
+ getRpcLaneResourceForTask(taskId) {
802
+ const laneId = this.getRpcLaneForTask(taskId);
803
+ if (!laneId)
616
804
  return null;
617
- // Find tunnel resource that owns this task
618
- return (this.getTunnelResources().find((tunnel) => tunnel.tunnelInfo?.tasks?.includes(taskId)) ?? null);
805
+ return this.findRpcLanesResourceByLaneId(laneId);
619
806
  }
620
- getTunnelForEvent(eventId) {
621
- // Find tunnel resource that tunnels this event
622
- return (this.getTunnelResources().find((tunnel) => tunnel.tunnelInfo?.events?.includes(eventId)) ?? null);
807
+ getRpcLaneResourceForEvent(eventId) {
808
+ const laneId = this.getRpcLaneForEvent(eventId);
809
+ if (!laneId)
810
+ return null;
811
+ return this.findRpcLanesResourceByLaneId(laneId);
623
812
  }
624
- /**
625
- * Populates tunnelInfo for resources with the tunnel tag.
626
- * Call this method after all resources have been initialized to ensure
627
- * tunnel resource values are available.
628
- */
629
- populateTunnelInfo() {
630
- const s = this.store;
631
- if (!s?.resources)
632
- return;
633
- const allTaskIds = this.tasks.map((t) => t.id);
634
- const allEventIds = this.events.map((e) => e.id);
635
- for (const storeEntry of s.resources.values()) {
636
- const resourceDef = storeEntry.resource;
637
- const resourceValue = storeEntry.value;
638
- const resourceId = String(resourceDef.id);
639
- // Find the corresponding model resource
640
- const modelResource = this.resources.find((r) => r.id === resourceId);
641
- if (!modelResource)
642
- continue;
643
- // Check if resource has tunnel tag using the already-normalized tags
644
- if ((0, tunnel_tools_1.hasTunnelTag)(modelResource.tags) && resourceValue) {
645
- const tunnelInfo = (0, extractTunnelInfo_1.extractTunnelInfo)(resourceValue, allTaskIds, allEventIds);
646
- if (tunnelInfo) {
647
- modelResource.tunnelInfo = tunnelInfo;
648
- }
649
- }
813
+ findRpcLanesResourceByLaneId(laneId) {
814
+ const rpcLanesResources = this.getRpcLanesResources();
815
+ if (rpcLanesResources.length === 0)
816
+ return null;
817
+ for (const resource of rpcLanesResources) {
818
+ const laneIds = (0, lane_resources_1.collectRpcLaneIdsFromResourceConfig)(resource.config);
819
+ if (laneIds.has(laneId))
820
+ return resource;
650
821
  }
822
+ // Fallback: if exactly one rpcLanes resource exists, prefer it.
823
+ return rpcLanesResources.length === 1 ? rpcLanesResources[0] : null;
651
824
  }
652
825
  // Durable workflow-related methods
653
826
  /**
@@ -655,7 +828,7 @@ class Introspector {
655
828
  * A task is durable if it has the durable workflow tag (current: `globals.tags.durableWorkflow`, legacy: `durable.workflow`).
656
829
  */
657
830
  isDurableTask(taskId) {
658
- const task = this.taskMap.get(taskId);
831
+ const task = this.getTask(taskId);
659
832
  if (!task)
660
833
  return false;
661
834
  return (0, durable_tools_1.hasDurableWorkflowTag)(task.tags);
@@ -670,7 +843,7 @@ class Introspector {
670
843
  * Returns the durable resource a task depends on, if any.
671
844
  */
672
845
  getDurableResourceForTask(taskId) {
673
- const task = this.taskMap.get(taskId);
846
+ const task = this.getTask(taskId);
674
847
  if (!task)
675
848
  return null;
676
849
  if (!this.isDurableTask(taskId))