@telorun/sdk 0.77.0 → 0.80.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 (61) hide show
  1. package/dist/cancellation.d.ts +50 -1
  2. package/dist/cancellation.d.ts.map +1 -1
  3. package/dist/contract-errors.d.ts +8 -1
  4. package/dist/contract-errors.d.ts.map +1 -1
  5. package/dist/contract-errors.js +8 -0
  6. package/dist/durable-run.d.ts +310 -0
  7. package/dist/durable-run.d.ts.map +1 -0
  8. package/dist/durable-run.js +223 -0
  9. package/dist/durable-suspension.d.ts +143 -0
  10. package/dist/durable-suspension.d.ts.map +1 -0
  11. package/dist/durable-suspension.js +153 -0
  12. package/dist/durable-target-encoding.d.ts +49 -0
  13. package/dist/durable-target-encoding.d.ts.map +1 -0
  14. package/dist/durable-target-encoding.js +121 -0
  15. package/dist/duration.d.ts +1 -1
  16. package/dist/duration.js +5 -5
  17. package/dist/evaluation-context.d.ts +16 -0
  18. package/dist/evaluation-context.d.ts.map +1 -1
  19. package/dist/index.d.ts +5 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +5 -0
  22. package/dist/invoke-step.d.ts +86 -1
  23. package/dist/invoke-step.d.ts.map +1 -1
  24. package/dist/invoke-step.js +261 -18
  25. package/dist/resource-context.d.ts +37 -0
  26. package/dist/resource-context.d.ts.map +1 -1
  27. package/dist/resource-instance.d.ts +21 -1
  28. package/dist/resource-instance.d.ts.map +1 -1
  29. package/dist/resource-instance.js +6 -2
  30. package/dist/step-engine.d.ts +170 -0
  31. package/dist/step-engine.d.ts.map +1 -0
  32. package/dist/step-engine.js +365 -0
  33. package/dist/zone-attribute.d.ts +101 -0
  34. package/dist/zone-attribute.d.ts.map +1 -0
  35. package/dist/zone-attribute.js +130 -0
  36. package/dist/zone-attributes/entries/atomic.json +7 -0
  37. package/dist/zone-attributes/entries/idempotent.json +6 -0
  38. package/dist/zone-attributes/entries/index.d.ts +3 -0
  39. package/dist/zone-attributes/entries/index.d.ts.map +1 -0
  40. package/dist/zone-attributes/entries/index.js +13 -0
  41. package/dist/zone-attributes/entries/no-suspend.json +6 -0
  42. package/dist/zone-attributes/entries/replayed.json +6 -0
  43. package/package.json +1 -1
  44. package/src/cancellation.ts +50 -1
  45. package/src/contract-errors.ts +9 -0
  46. package/src/durable-run.ts +450 -0
  47. package/src/durable-suspension.ts +188 -0
  48. package/src/durable-target-encoding.ts +181 -0
  49. package/src/duration.ts +5 -5
  50. package/src/evaluation-context.ts +17 -0
  51. package/src/index.ts +5 -1
  52. package/src/invoke-step.ts +378 -24
  53. package/src/resource-context.ts +37 -0
  54. package/src/resource-instance.ts +32 -2
  55. package/src/step-engine.ts +627 -0
  56. package/src/zone-attribute.ts +208 -0
  57. package/src/zone-attributes/entries/atomic.json +7 -0
  58. package/src/zone-attributes/entries/idempotent.json +6 -0
  59. package/src/zone-attributes/entries/index.ts +14 -0
  60. package/src/zone-attributes/entries/no-suspend.json +6 -0
  61. package/src/zone-attributes/entries/replayed.json +6 -0
@@ -1,5 +1,7 @@
1
- import { ERR_INVOKE_CANCELLED, isCancellationError, } from "./cancellation.js";
1
+ import { ERR_INVOKE_CANCELLED, UNCANCELLABLE_CONTEXT, createCancellationSource, deriveContext, isCancellationError, } from "./cancellation.js";
2
2
  import { isAmbientContractErrorCode } from "./contract-errors.js";
3
+ import { durableHandleOf, journalingSuppressed, stepPath, } from "./durable-run.js";
4
+ import { SUSPENDING_BACKOFF_MS, assertMaySuspend, isSuspension, parkRun, } from "./durable-suspension.js";
3
5
  import { tryParseDurationMs } from "./duration.js";
4
6
  import { InvokeError } from "./invoke-error.js";
5
7
  import { getRefIdentity } from "./resource-instance.js";
@@ -13,11 +15,129 @@ export async function executeInvokeStep(step, ctx, state) {
13
15
  const cel = { steps: state.steps, ...state.cel };
14
16
  if (step.when !== undefined && !ctx.expandValue(step.when, cel))
15
17
  return;
16
- const inputs = ctx.expandValue(step.inputs ?? {}, cel);
18
+ const rawHandle = durableHandleOf(state.invokeCtx);
19
+ // Inside a collapsed region the engine records NOTHING of its own: the region
20
+ // re-runs whole on resume, so per-step entries would describe work that is
21
+ // about to happen again. A resource inside it may still journal directly —
22
+ // which is what lets `Durable.Value` pin an impure evaluation there rather
23
+ // than be a prescription with nowhere to write.
24
+ const handle = rawHandle && journalingSuppressed(ctx, state.invokeCtx, rawHandle) ? undefined : rawHandle;
25
+ const path = state.journalPath ?? step.name;
26
+ // The RESOLVED inputs are journaled, not re-derived. They are read from a CEL
27
+ // scope carrying live readings — `resources.<name>.status` is republished on
28
+ // every dispatch by design — so a fresh process can compute different
29
+ // arguments for the same step and hand them to a target the journal will then
30
+ // answer for, with no mismatch to detect.
31
+ const inputs = (handle
32
+ ? await handle.decide(stepPath(path, "inputs"), "inputs", () => ctx.expandValue(step.inputs ?? {}, cel))
33
+ : ctx.expandValue(step.inputs ?? {}, cel));
17
34
  const raw = step.invoke;
18
- const result = await withStepRetry(step, state.invokeCtx, () => dispatch(raw, inputs, ctx, state));
35
+ // The dispatch carries THIS step's path, so anything it reaches that runs a
36
+ // step body of its own hangs those paths under this one rather than starting
37
+ // over at the root. Set only inside a durable run: outside one there is no
38
+ // path to carry, and deriving a context would be a rebuild for nothing.
39
+ // Derived from the RAW handle, not the collapse-suppressed one: collapse
40
+ // suppresses the engine's own per-step entries, never the journal. A
41
+ // `Durable.Value` or a parking kind inside a collapsed region still records
42
+ // directly, and it keys off this path — so dropping it here would give every
43
+ // such resource in the region ONE key inherited from an enclosing level.
44
+ const stepCtx = rawHandle && state.invokeCtx
45
+ ? deriveContext(state.invokeCtx, { durablePath: path })
46
+ : state.invokeCtx;
47
+ const execute = () => withStepRetry(step, stepCtx, ctx, rawHandle, path, (attemptCtx) => withStepTimeout(step, attemptCtx, (dispatchCtx) => dispatch(raw, inputs, ctx, { ...state, invokeCtx: dispatchCtx })));
48
+ // Retry and the timeout sit INSIDE the handed-over effect, not around it: a
49
+ // re-attempt is part of performing this step once, so a backend that ships the
50
+ // step elsewhere ships its policy with it rather than re-attempting a remote
51
+ // dispatch it does not own. This is also what keeps the attempt loop's own
52
+ // rule intact — the journal records the OUTCOME of the step, and a step whose
53
+ // third attempt succeeded completed once.
54
+ const result = handle
55
+ ? await handle.step(path, targetIdentityOf(raw, ctx, state), inputs, execute)
56
+ : await execute();
19
57
  state.steps[step.name] = { result };
20
58
  }
59
+ /**
60
+ * The target's DECLARATION-SITE identity, for a backend that may execute the
61
+ * step somewhere the instance does not exist.
62
+ *
63
+ * Derived from the `!ref` identity the kernel stamps at Phase-5 injection, which
64
+ * is the only declaration-site fact a resolved target carries — instance
65
+ * identity is process-local by construction. Undefined when the step dispatches
66
+ * something with no stamp (a truly anonymous instance), which a local backend
67
+ * handles by simply running `execute` and a relocating one must refuse rather
68
+ * than guess.
69
+ */
70
+ function targetIdentityOf(raw, ctx, state) {
71
+ if (!raw || typeof raw !== "object")
72
+ return undefined;
73
+ // A pre-injected instance carries the stamp already.
74
+ const behind = getRefIdentity(raw) ? undefined : instanceBehind(raw, ctx, state);
75
+ const stamped = getRefIdentity(raw) ?? (behind && getRefIdentity(behind.instance));
76
+ const ref = raw;
77
+ const kind = stamped?.kind ?? (typeof ref.kind === "string" ? ref.kind : undefined);
78
+ const name = stamped?.name ?? (typeof ref.name === "string" ? ref.name : undefined);
79
+ if (!kind || !name)
80
+ return undefined;
81
+ return {
82
+ kind,
83
+ name,
84
+ // Whether the name resolved inside a `with:` scope, which is knowable HERE
85
+ // and only here — the resolution is what answers it. The tuple identifying
86
+ // which scope RUN is not derivable yet, so this is what stops such a target
87
+ // being encoded as the module-level resource that shares its name.
88
+ ...(behind?.scoped ? { scoped: true } : {}),
89
+ // Carried through verbatim: the kernel derived it at the declaration site,
90
+ // which is the only place it is knowable, and a consumer that must name this
91
+ // target elsewhere has nothing else to name it with.
92
+ ...(stamped?.origin?.module === undefined ? {} : { module: stamped.origin.module }),
93
+ ...(stamped?.origin?.pointer === undefined ? {} : { pointer: stamped.origin.pointer }),
94
+ };
95
+ }
96
+ /**
97
+ * The live instance behind a step's `invoke:` REF, when this host can name one.
98
+ *
99
+ * A step's slot is not a Phase-5 injection site — it resolves at dispatch — so a
100
+ * step target arrives as a `{kind, name, alias?}` reference and carries no stamp
101
+ * of its own. Reading the instance's is what recovers the declaration site, and
102
+ * the resolution mirrors `dispatch`'s branches exactly so the identity describes
103
+ * the resource the step will actually reach.
104
+ *
105
+ * Reports whether the name resolved inside a `with:` SCOPE as well as what it
106
+ * resolved to, because that is a fact only the resolution knows and it changes
107
+ * what the identity means: a scoped name and a module-level one can be the same
108
+ * string and different resources.
109
+ *
110
+ * Best-effort by design: every resolver here is optional, and a host that
111
+ * supplies none yields an identity of kind and name alone — enough for a local
112
+ * backend, and refused by a relocating one rather than guessed at.
113
+ */
114
+ function instanceBehind(raw, ctx, state) {
115
+ const ref = raw;
116
+ if (typeof ref.name !== "string")
117
+ return undefined;
118
+ try {
119
+ if (ref.alias && ref.alias !== "Self") {
120
+ const imported = ctx.resolveImportedInstance?.(ref.alias, ref.name);
121
+ return imported && { instance: imported, scoped: false };
122
+ }
123
+ if (state.scope) {
124
+ // Scope-local FIRST, enclosing module as the fallback — the order
125
+ // `ScopeContext.getInstance` and the CEL `resources` layering already use,
126
+ // so what this reports a name to mean is what the dispatch will reach.
127
+ const scoped = state.scope.getInstance(ref.name);
128
+ if (scoped)
129
+ return { instance: scoped, scoped: true };
130
+ }
131
+ const local = ctx.resolveLocalInstance?.(ref.name);
132
+ return local && { instance: local, scoped: false };
133
+ }
134
+ catch {
135
+ // A resolver that throws is answering "not here", and the dispatch below is
136
+ // where that becomes an error with a message about the dispatch. Recovering
137
+ // provenance must not be the thing that reports it.
138
+ return undefined;
139
+ }
140
+ }
21
141
  /**
22
142
  * Re-attempt a step's dispatch while its policy allows.
23
143
  *
@@ -48,39 +168,156 @@ export async function executeInvokeStep(step, ctx, state) {
48
168
  * for a caller that assembled a policy in code rather than from a manifest — not
49
169
  * a second, competing statement of what a default is.
50
170
  */
51
- async function withStepRetry(step, invokeCtx, dispatch) {
171
+ async function withStepRetry(step, invokeCtx, ctx, handle, path, dispatch) {
52
172
  const policy = step.retry;
53
173
  const attempts = policy?.attempts ?? 0;
54
174
  if (!policy || attempts <= 0)
55
- return dispatch();
56
- const initial = policy.initialDelay ?? parseDuration(policy.delay) ?? 250;
57
- const factor = policy.factor ?? 2;
58
- const maxDelay = policy.maxDelay ?? 32_000;
175
+ return dispatch(invokeCtx);
59
176
  const jitter = policy.jitter ?? "full";
60
177
  for (let resend = 0;; resend++) {
61
178
  try {
62
- return await dispatch();
179
+ return await dispatch(invokeCtx);
63
180
  }
64
181
  catch (err) {
65
- if (resend >= attempts || !isRetryable(err))
182
+ if (resend >= attempts || !isRetryable(err, policy.nonRetryable))
66
183
  throw err;
67
- const backoff = Math.min(maxDelay, initial * Math.pow(factor, resend));
68
- await waitBeforeResend(jitter === "full" ? Math.random() * backoff : backoff, invokeCtx?.cancellation, step, err);
184
+ // The UN-JITTERED backoff, which is a pure function of the declared policy
185
+ // and the attempt index and which is therefore what the park decision
186
+ // below turns on. Deciding on the jittered value instead would put
187
+ // `Math.random()` on a control-flow branch inside a determinism contract:
188
+ // the same attempt could sleep on one pass and park on the next, for no
189
+ // reason a reader of the manifest could see. It would also make the static
190
+ // check unstateable, since the analyzer cannot know which way a coin
191
+ // landed. Jitter still does its whole job — spreading re-attempts — on the
192
+ // duration itself, in both branches.
193
+ const backoff = retryBackoffMs(policy, resend);
194
+ const delay = jitter === "full" ? Math.random() * backoff : backoff;
195
+ // A LONG backoff inside a durable run suspends rather than sleeps, and the
196
+ // attempt state is journaled with it. The obvious reading — only the
197
+ // outcome matters, so journal once — is wrong the moment a backoff
198
+ // suspends: a run that parks mid-retry and resumes in another process must
199
+ // know which attempt it was on, or it restarts the policy from zero and a
200
+ // three-attempt cap becomes unbounded.
201
+ //
202
+ // ONE DECISION PER ATTEMPT, holding when that attempt was due, is the
203
+ // whole mechanism. It needs nothing beyond `decide`: on resume the loop
204
+ // re-runs from attempt zero, each recorded attempt hands back a due time
205
+ // already in the past and is therefore consumed without waiting, and the
206
+ // first UNRECORDED attempt computes a fresh one and parks. The budget is
207
+ // preserved because the replayed attempts still count against it.
208
+ if (handle && backoff >= SUSPENDING_BACKOFF_MS) {
209
+ const attemptPath = stepPath(path, "retry", resend);
210
+ const dueAt = (await handle.decide(attemptPath, "value", () => Date.now() + delay));
211
+ if (Date.now() < dueAt) {
212
+ // Refused inside a region that promised nothing in it suspends. The
213
+ // check is here rather than at the policy, because a short backoff
214
+ // never suspends and rejecting one would forbid a retry that is
215
+ // perfectly safe in a lease.
216
+ assertMaySuspend(ctx, invokeCtx, { resource: step.name ?? path });
217
+ await parkRun(handle, { path: attemptPath, resource: step.name ?? path }, { at: dueAt });
218
+ }
219
+ continue;
220
+ }
221
+ await waitBeforeResend(delay, invokeCtx?.cancellation, step, err);
69
222
  }
70
223
  }
71
224
  }
225
+ /**
226
+ * The backoff before attempt `resend + 1`, before jitter.
227
+ *
228
+ * ONE formula, exported because the analyzer needs the same number: it decides
229
+ * statically whether a step's declared policy would park inside a region that
230
+ * cannot be held open, and a second copy of exponential-backoff arithmetic in
231
+ * the analyzer would be a rule that drifts from the behaviour it describes the
232
+ * first time either side gains a knob.
233
+ *
234
+ * Jitter is deliberately NOT applied here. It belongs to the duration, not to
235
+ * the shape of the policy, and the two consumers want the shape: the runtime
236
+ * branches on it (see `withStepRetry`) and the analyzer reports on it.
237
+ *
238
+ * The `??` fallbacks are the floor for a caller that assembled a policy in code;
239
+ * a manifest gets its defaults from the schema.
240
+ */
241
+ export function retryBackoffMs(policy, resend) {
242
+ const initial = policy.initialDelay ?? parseDuration(policy.delay) ?? 250;
243
+ const factor = policy.factor ?? 2;
244
+ const maxDelay = policy.maxDelay ?? 32_000;
245
+ return Math.min(maxDelay, initial * Math.pow(factor, resend));
246
+ }
72
247
  /** Kernel verdicts on the CALL rather than on the work, beyond the ambient
73
248
  * contract set. A dispatch that cannot resolve its target is a manifest defect;
74
249
  * re-issuing it re-resolves the same name against the same registry. */
75
250
  const UNRETRYABLE_CODES = new Set(["ERR_RESOURCE_NOT_FOUND", "ERR_RESOURCE_NOT_INVOKABLE"]);
76
- function isRetryable(err) {
251
+ function isRetryable(err, nonRetryable) {
77
252
  if (isCancellationError(err))
78
253
  return false;
254
+ // A suspension is not a failure — it is the run leaving. Re-attempting it
255
+ // would park again under the same policy until the budget ran out, and the
256
+ // last attempt would propagate a park the earlier ones had already recorded.
257
+ if (isSuspension(err))
258
+ return false;
79
259
  const code = err?.code;
80
260
  if (typeof code !== "string")
81
261
  return true;
262
+ // The author's own exclusions, checked beside the built-in ones rather than
263
+ // before or after them: they are the same question — is re-issuing this call
264
+ // capable of a different answer — asked about a domain failure the leaf has no
265
+ // way to classify. A step timeout is never in this set by default; whether a
266
+ // slow call is worth re-attempting is exactly the judgement an author makes.
267
+ if (nonRetryable?.includes(code))
268
+ return false;
82
269
  return !isAmbientContractErrorCode(code) && !UNRETRYABLE_CODES.has(code);
83
270
  }
271
+ /**
272
+ * Bound ONE attempt, by cancellation rather than by abandonment.
273
+ *
274
+ * A `Promise.race` that simply rejects would leave the call running, holding its
275
+ * connection and eventually completing a side effect nobody is waiting on — the
276
+ * failure mode a timeout is usually adopted to prevent. So a timeout mints a
277
+ * cancellation source, LINKS it to the caller's token (or the caller's
278
+ * cancellation would stop propagating the moment a step declared a bound), and
279
+ * threads its context into the dispatch. A target that honours cancellation
280
+ * stops; one that does not is no worse off than before.
281
+ *
282
+ * The elapse is reported as `ERR_STEP_TIMEOUT` rather than as a cancellation,
283
+ * because the two want opposite follow-ups: a cancelled run was asked to stop,
284
+ * while a timed-out step is a target that is too slow for this call site — and
285
+ * `catches:` can only tell them apart if they carry different codes.
286
+ */
287
+ async function withStepTimeout(step, invokeCtx, dispatch) {
288
+ const ms = step.timeout;
289
+ if (ms === undefined || !(ms > 0))
290
+ return dispatch(invokeCtx);
291
+ const source = createCancellationSource();
292
+ const base = invokeCtx ?? UNCANCELLABLE_CONTEXT;
293
+ // Everything else on the context — zones, tracing, and whatever a later
294
+ // member adds — rides across unchanged. Rebuilding it as a literal here is
295
+ // the drop `deriveContext` exists to prevent.
296
+ const scoped = deriveContext(base, { cancellation: source.token });
297
+ const unlink = invokeCtx?.cancellation.onCancelled((reason) => source.cancel(reason));
298
+ let elapsed = false;
299
+ source.cancelAfter(ms);
300
+ const timedOut = source.token.onCancelled(() => {
301
+ if (!invokeCtx?.cancellation.isCancelled)
302
+ elapsed = true;
303
+ });
304
+ try {
305
+ return await dispatch(scoped);
306
+ }
307
+ catch (err) {
308
+ if (elapsed && isCancellationError(err)) {
309
+ throw new InvokeError("ERR_STEP_TIMEOUT", `Step '${step.name}' exceeded its timeout of ${ms}ms and was cancelled`, { step: step.name, timeout: ms });
310
+ }
311
+ throw err;
312
+ }
313
+ finally {
314
+ timedOut();
315
+ unlink?.();
316
+ // Releases the pending deadline timer, so a step that finished early does
317
+ // not pin a timer alive until its bound elapses.
318
+ source.dispose();
319
+ }
320
+ }
84
321
  /**
85
322
  * Wait out the backoff, or give up the moment the invocation is cancelled.
86
323
  *
@@ -134,6 +371,12 @@ function parseDuration(value) {
134
371
  }
135
372
  async function dispatch(raw, inputs, ctx, state) {
136
373
  let result;
374
+ // The context this attempt runs under: the step's timeout scope when it
375
+ // declares one, else whatever the composer forwarded. Threaded explicitly
376
+ // rather than installed as ambient because the SDK leaf has no ambient store
377
+ // to install into — that is one runtime's mechanism, and a second-language
378
+ // leaf has no `AsyncLocalStorage`.
379
+ const attemptCtx = state.invokeCtx;
137
380
  if (raw && typeof raw.invoke === "function") {
138
381
  // A pre-injected live instance (a `!ref` resolved at Phase 5). Route it
139
382
  // through the traced chokepoint using the identity the kernel stamped at
@@ -141,8 +384,8 @@ async function dispatch(raw, inputs, ctx, state) {
141
384
  // A truly anonymous instance (no stamp) falls back to a direct call.
142
385
  const identity = getRefIdentity(raw);
143
386
  result = identity
144
- ? await ctx.invokeResolved(identity.kind, identity.name, raw, inputs)
145
- : await raw.invoke(inputs);
387
+ ? await ctx.invokeResolved(identity.kind, identity.name, raw, inputs, attemptCtx)
388
+ : await raw.invoke(inputs, attemptCtx);
146
389
  }
147
390
  else {
148
391
  const ref = raw;
@@ -154,14 +397,14 @@ async function dispatch(raw, inputs, ctx, state) {
154
397
  if (!instance) {
155
398
  throw new Error(`Cross-module reference '${ref.alias}.${ref.name}' did not resolve to an exported instance.`);
156
399
  }
157
- result = await ctx.invokeResolved(ref.kind, ref.name, instance, inputs);
400
+ result = await ctx.invokeResolved(ref.kind, ref.name, instance, inputs, attemptCtx);
158
401
  }
159
402
  else if (state.scope) {
160
403
  const instance = state.scope.getInstance(ref.name);
161
- result = await ctx.invokeResolved(ref.kind, ref.name, instance, inputs);
404
+ result = await ctx.invokeResolved(ref.kind, ref.name, instance, inputs, attemptCtx);
162
405
  }
163
406
  else {
164
- result = await ctx.invoke(ref.kind, ref.name, inputs);
407
+ result = await ctx.invoke(ref.kind, ref.name, inputs, { ctx: attemptCtx });
165
408
  }
166
409
  }
167
410
  return result;
@@ -11,6 +11,7 @@ import { ResourceInstance } from "./resource-instance.js";
11
11
  import { ResourceManifest } from "./resource-manifest.js";
12
12
  import { RuntimeResource } from "./runtime-resource.js";
13
13
  import type { RuntimeSeam } from "./runtime-seam.js";
14
+ import type { OpenZoneAttributes } from "./zone-attribute.js";
14
15
  export interface LoadOptions {
15
16
  /** When true, `${{ }}` templates are replaced with CompiledValue wrappers
16
17
  * so they can be evaluated at runtime. Leave unset for static analysis. */
@@ -130,6 +131,28 @@ export interface ResourceContext extends ControllerContext {
130
131
  * one). No kind parameter: the provider's own per-instance map already
131
132
  * discriminates — a zone this instance's owner did not open simply misses. */
132
133
  zonesFor(instance: ResourceInstance, ctx?: InvokeContext): readonly ZoneEntry[];
134
+ /**
135
+ * Every open zone with what it DECLARES about its contents, innermost first —
136
+ * the runtime half of `x-telo-provides-zone`'s attributes.
137
+ *
138
+ * Read off the declaring kind's schema, never off the entry: a
139
+ * {@link ZoneEntry} is three identities *because* that keeps it
140
+ * ABI-serializable and stops any module reading another's private state off
141
+ * the stack, and hanging attributes on it would trade that away for every
142
+ * zone. The kernel resolves the schema instead — the one place that lookup is
143
+ * already available — and hands the attributes over WITHOUT branching on a
144
+ * name, exactly as `readRefSlot` returns `use` without acting on it.
145
+ *
146
+ * The vocabulary is closed (`sdk/zone-attributes/`), which is what lets this
147
+ * be a typed record rather than a string-keyed bag. That is a readability
148
+ * gain and not a semantic one: interpreting an attribute is entirely the
149
+ * caller's — the step engine reads `atomic` to decide collapse, a parking kind
150
+ * reads `noSuspend` to refuse, and the kernel reads neither.
151
+ *
152
+ * Each value is the author's REASON, so a controller refusing on an attribute
153
+ * quotes the manifest's own sentence instead of inventing a generic message.
154
+ */
155
+ zoneAttributes(ctx?: InvokeContext): readonly OpenZoneAttributes[];
133
156
  /** The root context for runtime-driven inbound work (request, timer, queue
134
157
  * message): inherits nothing from whatever ambient happens to be live at the
135
158
  * registration site — no zones, no trace parent, no caller token. An inbound
@@ -191,6 +214,20 @@ export interface ResourceContext extends ControllerContext {
191
214
  * says what was missing.
192
215
  */
193
216
  resolveRef<T>(value: unknown, guard: (candidate: unknown) => candidate is T, describe: () => string, expects?: string): T;
217
+ /**
218
+ * The manifest a name was DECLARED with, resolved in the context that OWNS
219
+ * this resource — the same order {@link resolveRef} uses, so a declaration
220
+ * lookup cannot disagree with an instance lookup about what a name means.
221
+ *
222
+ * The counterpart to {@link resolveRef} for a slot that wants a FACT about its
223
+ * target rather than the target itself. A declaration is readable whether or
224
+ * not the resource has been constructed, which is what lets such a slot avoid
225
+ * an ordering edge — and what lets a resource read a slot pointing at itself.
226
+ *
227
+ * Optional because a third-party context implementation must keep compiling;
228
+ * absent reads as "no declaration in scope".
229
+ */
230
+ resolveDeclaredManifest?(name: string, alias?: string): ResourceManifest | undefined;
194
231
  validateSchema(value: any, schema: any): void;
195
232
  /** Compile an author-written JSON Schema from a resource field into a
196
233
  * reusable validator, through the runtime's own engine — so its formats and
@@ -1 +1 @@
1
- {"version":3,"file":"resource-context.d.ts","sourceRoot":"","sources":["../src/resource-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resource-context.d.ts","sourceRoot":"","sources":["../src/resource-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,QAAQ,EACR,eAAe,EACf,SAAS,EACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B;gFAC4E;IAC5E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;4EAGwE;IACxE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;4CAIwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAc,YAAW,aAAa;IACjD,OAAO;IAIP,QAAQ;CAGT;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC,GAAG;IAAE,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEhG;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,mBAAmB;IAClC,2DAA2D;IAC3D,GAAG,CAAC,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;;;;;4EAKwE;IACxE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACzC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;iCAE6B;IAC7B,wBAAwB,IAAI,kBAAkB,CAAC;IAC/C;+EAC2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,CAAC,EACR,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,EACxD,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,CAAC,CAAC,CAAC;IACd;kFAC8E;IAC9E,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC3D,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;IACpE;;;mFAG+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,SAAS,SAAS,EAAE,CAAC;IAChF;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,cAAc,CAAC,GAAG,CAAC,EAAE,aAAa,GAAG,SAAS,kBAAkB,EAAE,CAAC;IACnE;;;;sCAIkC;IAClC,WAAW,CAAC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,kBAAkB,CAAA;KAAE,GAAG,aAAa,CAAC;IACzE;;;;;2EAKuE;IACvE,WAAW,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9C;;;;;kBAKc;IACd,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpF;;;qCAGiC;IACjC,MAAM,CAAC,OAAO,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,GAAG,CAAC,CAAC;IAChB,cAAc,CAAC,OAAO,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,OAAO,EACf,GAAG,CAAC,EAAE,aAAa,GAClB,OAAO,CAAC,GAAG,CAAC,CAAC;IAChB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAAC;IACvE,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,CAAC;IACtC,iBAAiB,IAAI,iBAAiB,CAAC;IACvC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,iBAAiB,CAAC;IAChE,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IACnD;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1D;kFAC8E;IAC9E,eAAe,CAAC,QAAQ,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtF;;;;;;OAMG;IACH,UAAU,CAAC,CAAC,EACV,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,SAAS,IAAI,CAAC,EAC7C,QAAQ,EAAE,MAAM,MAAM,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,CAAC,CAAC;IACL;;;;;;;;;;;;OAYG;IACH,uBAAuB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACrF,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;IAC9C;;;;;yEAKqE;IACrE,qBAAqB,CAAC,MAAM,EAAE,GAAG,GAAG,aAAa,CAAC;IAClD,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACnD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/C,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACzD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC;IACtD,kFAAkF;IAClF,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,aAAa,CAAC;IACtF,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjG,kBAAkB,CAAC,UAAU,EAAE,GAAG,GAAG,IAAI,CAAC;IAC1C;yDACqD;IACrD,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3F;;;;OAIG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,SAAS,CAAC;IACpD;;;;;;;;;;;OAWG;IACH,WAAW,IAAI,MAAM,GAAG,SAAS,CAAC;IAClC;;;;iEAI6D;IAC7D,cAAc,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD;wDACoD;IACpD,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAC5E;;;sBAGkB;IAClB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACxD;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CACxC"}
@@ -28,6 +28,26 @@ export declare const TEARDOWN_LAST = 1000;
28
28
  export interface RefIdentity {
29
29
  kind: string;
30
30
  name: string;
31
+ /**
32
+ * Where the instance was DECLARED, for a consumer that must name it somewhere
33
+ * the instance does not exist — a durable step shipped to another process.
34
+ *
35
+ * Optional because it is derived from the declaration and an instance stamped
36
+ * by a path that has none is still dispatchable; a consumer that genuinely
37
+ * needs it refuses rather than guessing (see `encodeDurableTarget`). Kept ON
38
+ * the identity rather than in a second table because it answers the same
39
+ * question the identity does — *which declaration is this* — one level more
40
+ * precisely.
41
+ */
42
+ origin?: RefOrigin;
43
+ }
44
+ /** The declaration site behind a live instance. `module` is the source of the
45
+ * module that declared it, which is what tells two libraries' same-named
46
+ * resources apart; `pointer` is set when the declaration is inline, and is a
47
+ * JSON pointer into its declaring resource. */
48
+ export interface RefOrigin {
49
+ module?: string;
50
+ pointer?: string;
31
51
  }
32
52
  /**
33
53
  * Kernel-minted, unique per LIVE instance, stable for its lifetime. Distinct
@@ -59,7 +79,7 @@ export declare const sameResource: (a: ResourceHandle, b: ResourceHandle) => boo
59
79
  export declare const REF_IDENTITY: unique symbol;
60
80
  /** Stamp the resolved kind+name onto an injected instance. Idempotent — an
61
81
  * instance has exactly one identity, so re-injection into other slots is a no-op. */
62
- export declare function stampRefIdentity(instance: object, kind: string, name: string): void;
82
+ export declare function stampRefIdentity(instance: object, kind: string, name: string, origin?: RefOrigin): void;
63
83
  /** Read the identity stamped by {@link stampRefIdentity}, if any. */
64
84
  export declare function getRefIdentity(instance: object): RefIdentity | undefined;
65
85
  //# sourceMappingURL=resource-instance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource-instance.d.ts","sourceRoot":"","sources":["../src/resource-instance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG,IAAI,OAAO,CACjF,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3B,GACC,OAAO,CAAC,QAAQ,CAAC,GACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG;IAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAChE;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEJ;;mBAEmB;AACnB,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAErF;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,kBAAkB,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;CAC3B;AAED,eAAO,MAAM,YAAY,GAAI,GAAG,cAAc,EAAE,GAAG,cAAc,KAAG,OAAwB,CAAC;AAE7F;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,MAAuC,CAAC;AAE1E;sFACsF;AACtF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CASnF;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAExE"}
1
+ {"version":3,"file":"resource-instance.d.ts","sourceRoot":"","sources":["../src/resource-instance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,gBAAgB,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,GAAG,IAAI,OAAO,CACjF,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3B,GACC,OAAO,CAAC,QAAQ,CAAC,GACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG;IAC3B,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,QAAQ,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAChE;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEJ;;mBAEmB;AACnB,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED;;;gDAGgD;AAChD,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAErF;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,kBAAkB,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;CAC3B;AAED,eAAO,MAAM,YAAY,GAAI,GAAG,cAAc,EAAE,GAAG,cAAc,KAAG,OAAwB,CAAC;AAE7F;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,EAAE,OAAO,MAAuC,CAAC;AAE1E;sFACsF;AACtF,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,SAAS,GACjB,IAAI,CAaN;AAED,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAExE"}
@@ -13,10 +13,14 @@ export const sameResource = (a, b) => a.id === b.id;
13
13
  export const REF_IDENTITY = Symbol.for("telo.refIdentity");
14
14
  /** Stamp the resolved kind+name onto an injected instance. Idempotent — an
15
15
  * instance has exactly one identity, so re-injection into other slots is a no-op. */
16
- export function stampRefIdentity(instance, kind, name) {
16
+ export function stampRefIdentity(instance, kind, name, origin) {
17
17
  if (!(REF_IDENTITY in instance)) {
18
18
  Object.defineProperty(instance, REF_IDENTITY, {
19
- value: { kind, name },
19
+ value: {
20
+ kind,
21
+ name,
22
+ ...(origin && (origin.module || origin.pointer) ? { origin } : {}),
23
+ },
20
24
  enumerable: false,
21
25
  configurable: true,
22
26
  writable: false,