@telorun/analyzer 0.14.0 → 0.16.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 (41) hide show
  1. package/dist/analyzer.d.ts.map +1 -1
  2. package/dist/analyzer.js +39 -8
  3. package/dist/builtins.d.ts.map +1 -1
  4. package/dist/builtins.js +64 -1
  5. package/dist/flatten-for-analyzer.d.ts.map +1 -1
  6. package/dist/flatten-for-analyzer.js +8 -4
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -0
  10. package/dist/inline-imports.d.ts +34 -0
  11. package/dist/inline-imports.d.ts.map +1 -0
  12. package/dist/inline-imports.js +106 -0
  13. package/dist/manifest-loader.d.ts +10 -1
  14. package/dist/manifest-loader.d.ts.map +1 -1
  15. package/dist/manifest-loader.js +45 -22
  16. package/dist/resolve-ref-sentinels.d.ts.map +1 -1
  17. package/dist/resolve-ref-sentinels.js +3 -11
  18. package/dist/types.d.ts +9 -0
  19. package/dist/types.d.ts.map +1 -1
  20. package/dist/validate-references.d.ts.map +1 -1
  21. package/dist/validate-references.js +25 -22
  22. package/package.json +5 -4
  23. package/src/alias-resolver.ts +9 -0
  24. package/src/analyzer.ts +64 -5
  25. package/src/builtins.ts +64 -0
  26. package/src/flatten-for-analyzer.ts +20 -0
  27. package/src/index.ts +2 -0
  28. package/src/inline-imports.ts +130 -0
  29. package/src/manifest-loader.ts +52 -21
  30. package/src/resolve-ref-sentinels.ts +89 -44
  31. package/src/types.ts +9 -0
  32. package/src/validate-references.ts +103 -8
  33. package/dist/adapters/http-adapter.d.ts +0 -10
  34. package/dist/adapters/http-adapter.d.ts.map +0 -1
  35. package/dist/adapters/http-adapter.js +0 -18
  36. package/dist/adapters/node-adapter.d.ts +0 -17
  37. package/dist/adapters/node-adapter.d.ts.map +0 -1
  38. package/dist/adapters/node-adapter.js +0 -71
  39. package/dist/adapters/registry-adapter.d.ts +0 -15
  40. package/dist/adapters/registry-adapter.d.ts.map +0 -1
  41. package/dist/adapters/registry-adapter.js +0 -53
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAiB9B,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAuhB/F,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAmmBvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CACP,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,EAI1B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,GACtC,gBAAgB,EAAE;IAqBrB,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAiB9B,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAuhB/F,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAmoBvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CACP,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,EAI1B,kBAAkB,CAAC,EAAE,gBAAgB,EAAE,GACtC,gBAAgB,EAAE;IAqBrB,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}
package/dist/analyzer.js CHANGED
@@ -498,6 +498,11 @@ export class StaticAnalyzer {
498
498
  }
499
499
  }
500
500
  const aliasesByModule = ctx?.aliasesByModule ?? new Map();
501
+ // Per-module-scope seen aliases for DUPLICATE_IMPORT_ALIAS. Authored
502
+ // Telo.Import docs and synthetic-from-inline-`imports:` share one alias
503
+ // namespace per module, so a repeat — across either form — is an error
504
+ // rather than the silent last-writer-wins the resolver would otherwise do.
505
+ const seenAliasByScope = new Map();
501
506
  for (const m of manifests) {
502
507
  if (isModuleKind(m.kind)) {
503
508
  const namespace = m.metadata.namespace ?? null;
@@ -535,6 +540,34 @@ export class StaticAnalyzer {
535
540
  const resolvedModuleName = m.metadata.resolvedModuleName;
536
541
  const resolvedNamespace = m.metadata.resolvedNamespace;
537
542
  const ownModule = m.metadata?.module;
543
+ if (alias) {
544
+ const scopeKey = ownModule ?? "";
545
+ let seen = seenAliasByScope.get(scopeKey);
546
+ if (!seen) {
547
+ seen = new Set();
548
+ seenAliasByScope.set(scopeKey, seen);
549
+ }
550
+ if (seen.has(alias)) {
551
+ diagnostics.push({
552
+ severity: DiagnosticSeverity.Error,
553
+ code: "DUPLICATE_IMPORT_ALIAS",
554
+ source: SOURCE,
555
+ message: `Duplicate import alias '${alias}'. An alias may be declared once per module — ` +
556
+ `across both inline 'imports:' entries and 'Telo.Import' documents. ` +
557
+ `Rename or remove the duplicate.`,
558
+ data: {
559
+ resource: { kind: "Telo.Import", name: alias },
560
+ filePath: m.metadata?.source,
561
+ path: "metadata.name",
562
+ },
563
+ });
564
+ // Keep the first alias→target mapping intact; don't re-register the
565
+ // duplicate (last-writer-wins would shadow the original and cascade
566
+ // misleading follow-on diagnostics).
567
+ continue;
568
+ }
569
+ seen.add(alias);
570
+ }
538
571
  if (alias && source) {
539
572
  const targetModule = resolvedModuleName ?? source.split("/").filter(Boolean).pop() ?? source;
540
573
  // Module identity is registered globally so x-telo-ref resolution sees
@@ -696,14 +729,12 @@ export class StaticAnalyzer {
696
729
  if (m.kind === "Telo.Abstract") {
697
730
  continue;
698
731
  }
699
- // Forwarded foreign exports (an imported library's exported instances, whose
700
- // metadata.module isn't a root module here) were already validated in their own
701
- // module's standalone analysis, and their `kind`/CEL are authored in that module's
702
- // scope (e.g. `Self.X` resolves to that module, not the consumer). Re-validating them
703
- // against the consumer's scope yields false UNDEFINED_KIND / scope-mismatch errors, so
704
- // skip they participate in this analysis only as cross-module resolution targets.
705
- const mModule = m.metadata?.module;
706
- if (typeof mModule === "string" && !rootModules.has(mModule)) {
732
+ // Forwarded exports (flagged by flattenForAnalyzer) are an imported library's exported
733
+ // instances, already validated in their own module's standalone analysis; their
734
+ // `kind`/CEL are authored in that module's scope (e.g. `Self.X` → that module, not the
735
+ // consumer). Re-validating against the consumer's scope yields false UNDEFINED_KIND /
736
+ // scope-mismatch errors, so skip they participate here only as resolution targets.
737
+ if (m.metadata?.forwardedExport === true) {
707
738
  continue;
708
739
  }
709
740
  const resource = { kind: m.kind, name: m.metadata?.name };
@@ -1 +1 @@
1
- {"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,eAAO,MAAM,eAAe,EAAE,kBAAkB,EAuZ/C,CAAC"}
1
+ {"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../src/builtins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,eAAO,MAAM,eAAe,EAAE,kBAAkB,EAsd/C,CAAC"}
package/dist/builtins.js CHANGED
@@ -299,6 +299,37 @@ export const KERNEL_BUILTINS = [
299
299
  type: "array",
300
300
  items: { type: "string" },
301
301
  },
302
+ // Inline imports — name-keyed map sugar for separate `Telo.Import`
303
+ // documents. The key is the PascalCase alias (the import's
304
+ // `metadata.name`). Each value is either a bare source string
305
+ // (shorthand for `{ source }`) or the full object form. The loader
306
+ // desugars each entry into a synthetic `Telo.Import` before discovery;
307
+ // authored `Telo.Import` docs keep working alongside this. See
308
+ // analyzer/nodejs/src/inline-imports.ts.
309
+ imports: {
310
+ type: "object",
311
+ additionalProperties: {
312
+ oneOf: [
313
+ { type: "string" },
314
+ {
315
+ type: "object",
316
+ required: ["source"],
317
+ properties: {
318
+ source: { type: "string" },
319
+ variables: { type: "object" },
320
+ secrets: { type: "object" },
321
+ runtime: {
322
+ oneOf: [
323
+ { type: "string" },
324
+ { type: "array", items: { type: "string" } },
325
+ ],
326
+ },
327
+ },
328
+ additionalProperties: false,
329
+ },
330
+ ],
331
+ },
332
+ },
302
333
  // Application-level environment contract. Each entry layers `env:`
303
334
  // (required, names the source env var) and `default:` (optional, used
304
335
  // when the env var is unset) on top of an open JSON Schema property
@@ -392,11 +423,43 @@ export const KERNEL_BUILTINS = [
392
423
  type: "array",
393
424
  items: { type: "string" },
394
425
  },
426
+ // Inline imports — same name-keyed map sugar as Telo.Application; the
427
+ // loader desugars each entry into a synthetic Telo.Import. See the
428
+ // Application schema above and analyzer/nodejs/src/inline-imports.ts.
429
+ imports: {
430
+ type: "object",
431
+ additionalProperties: {
432
+ oneOf: [
433
+ { type: "string" },
434
+ {
435
+ type: "object",
436
+ required: ["source"],
437
+ properties: {
438
+ source: { type: "string" },
439
+ variables: { type: "object" },
440
+ secrets: { type: "object" },
441
+ runtime: {
442
+ oneOf: [
443
+ { type: "string" },
444
+ { type: "array", items: { type: "string" } },
445
+ ],
446
+ },
447
+ },
448
+ additionalProperties: false,
449
+ },
450
+ ],
451
+ },
452
+ },
395
453
  exports: {
396
454
  type: "object",
397
455
  properties: {
398
456
  kinds: { type: "array", items: { type: "string" } },
399
- resources: { type: "array", items: { type: "string" } },
457
+ // `variables` / `secrets` are reserved on the resources.<Alias> value-flow
458
+ // surface, so a library may not export instances under those names.
459
+ resources: {
460
+ type: "array",
461
+ items: { type: "string", not: { enum: ["variables", "secrets"] } },
462
+ },
400
463
  },
401
464
  additionalProperties: true,
402
465
  },
@@ -1 +1 @@
1
- {"version":3,"file":"flatten-for-analyzer.d.ts","sourceRoot":"","sources":["../src/flatten-for-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAc,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG/E;;;;;;;;;;;;;;;;;;6EAkB6E;AAC7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,gBAAgB,EAAE,CAyEzE;AAED;;;;;6BAK6B;AAC7B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAEzE"}
1
+ {"version":3,"file":"flatten-for-analyzer.d.ts","sourceRoot":"","sources":["../src/flatten-for-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAc,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAG/E;;;;;;;;;;;;;;;;;;6EAkB6E;AAC7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,gBAAgB,EAAE,CA6EzE;AAED;;;;;6BAK6B;AAC7B,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,gBAAgB,EAAE,CAEzE"}
@@ -52,10 +52,14 @@ export function flattenForAnalyzer(graph) {
52
52
  // Forward instances listed in the library's `exports.resources` so the
53
53
  // consumer's analyzer can resolve, gate, kind-check, and draw topology edges
54
54
  // for cross-module `!ref Alias.name`. The gate IS this forwarding — only
55
- // exported names cross the boundary. `metadata.module` (stamped by
56
- // collectModuleManifests) marks them foreign, so ref validation treats them
57
- // as resolution targets, not as sources to re-validate.
58
- result.push(m);
55
+ // exported names cross the boundary. `metadata.forwardedExport` marks them as
56
+ // cross-module resolution targets only (keyed by `metadata.module`), so ref
57
+ // resolution / validation treats them as targets, never as local sources to
58
+ // re-validate or walk.
59
+ result.push({
60
+ ...m,
61
+ metadata: { ...m.metadata, forwardedExport: true },
62
+ });
59
63
  }
60
64
  }
61
65
  }
package/dist/index.d.ts CHANGED
@@ -9,6 +9,8 @@ export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
9
9
  export type { ModuleKind } from "./module-kinds.js";
10
10
  export { parseLoadedFile } from "./parse-loaded-file.js";
11
11
  export type { ParseOptions } from "./parse-loaded-file.js";
12
+ export { desugarLoadedFile, inlineImportManifests } from "./inline-imports.js";
13
+ export type { SyntheticImport } from "./inline-imports.js";
12
14
  export { residualEntrySchema, residualEntrySchemaMap } from "./residual-schema.js";
13
15
  export { buildDocumentPositions, buildLineOffsets, buildPositionIndex, documentLineOffsets, } from "./position-metadata.js";
14
16
  export type { DocumentPosition } from "./position-metadata.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EACR,cAAc,EACd,UAAU,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,UAAU,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EACR,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EACH,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC3E,YAAY,EACR,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,KAAK,EACR,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EACR,cAAc,EACd,UAAU,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,UAAU,GACb,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EACR,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EACH,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC3E,YAAY,EACR,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,KAAK,EACR,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ export { visitManifest } from "./manifest-visitor.js";
5
5
  export { Loader } from "./manifest-loader.js";
6
6
  export { isModuleKind, MODULE_KINDS } from "./module-kinds.js";
7
7
  export { parseLoadedFile } from "./parse-loaded-file.js";
8
+ export { desugarLoadedFile, inlineImportManifests } from "./inline-imports.js";
8
9
  export { residualEntrySchema, residualEntrySchemaMap } from "./residual-schema.js";
9
10
  export { buildDocumentPositions, buildLineOffsets, buildPositionIndex, documentLineOffsets, } from "./position-metadata.js";
10
11
  export { HttpSource } from "./sources/http-source.js";
@@ -0,0 +1,34 @@
1
+ import type { ResourceManifest } from "@telorun/sdk";
2
+ import type { LoadedFile } from "./loaded-types.js";
3
+ import type { DocumentPosition } from "./position-metadata.js";
4
+ /** A synthetic `Telo.Import` produced by desugaring an `imports:` map entry,
5
+ * paired with the position metadata that pins its diagnostics back to the
6
+ * authoring line in the module document. */
7
+ export interface SyntheticImport {
8
+ manifest: ResourceManifest;
9
+ position: DocumentPosition;
10
+ }
11
+ /**
12
+ * Desugar a module document's inline `imports:` map into synthetic
13
+ * `Telo.Import` manifests. Each entry value is either a bare source string
14
+ * (shorthand for `{ source }`) or the full object form carrying
15
+ * `variables` / `secrets` / `runtime`. Malformed entries (object without a
16
+ * string `source`) are skipped here — the module document's own schema
17
+ * validation reports them against the precise `imports.<Alias>.source` path.
18
+ *
19
+ * The synthetic manifests are indistinguishable from authored `Telo.Import`
20
+ * documents downstream (alias registration, discovery, the kernel's
21
+ * import-controller), so the feature is purely additive at the declaration
22
+ * site. Pure and browser-safe — no I/O, no Node built-ins.
23
+ */
24
+ export declare function inlineImportManifests(moduleManifest: ResourceManifest, modulePosition: DocumentPosition | undefined): SyntheticImport[];
25
+ /** Returns a copy of `file` with synthetic `Telo.Import` manifests (from the
26
+ * module document's inline `imports:` map) appended to `manifests` and
27
+ * `positions`. `documents` is intentionally left untouched: it is the raw
28
+ * YAML-AST array round-trip consumers pair by index, and a synthetic import
29
+ * has no backing node. Every flatten/discovery loop iterates `manifests` and
30
+ * indexes `positions[i]` — never `documents[i]` in lockstep — so the trailing
31
+ * synthetics are visible to resolution while the AST round-trip stays intact.
32
+ * Returns `file` unchanged when there is no module doc or no inline imports. */
33
+ export declare function desugarLoadedFile(file: LoadedFile): LoadedFile;
34
+ //# sourceMappingURL=inline-imports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-imports.d.ts","sourceRoot":"","sources":["../src/inline-imports.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG/D;;6CAE6C;AAC7C,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,cAAc,EAAE,gBAAgB,EAChC,cAAc,EAAE,gBAAgB,GAAG,SAAS,GAC3C,eAAe,EAAE,CA0BnB;AAED;;;;;;;iFAOiF;AACjF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAmB9D"}
@@ -0,0 +1,106 @@
1
+ import { isModuleKind } from "./module-kinds.js";
2
+ /**
3
+ * Desugar a module document's inline `imports:` map into synthetic
4
+ * `Telo.Import` manifests. Each entry value is either a bare source string
5
+ * (shorthand for `{ source }`) or the full object form carrying
6
+ * `variables` / `secrets` / `runtime`. Malformed entries (object without a
7
+ * string `source`) are skipped here — the module document's own schema
8
+ * validation reports them against the precise `imports.<Alias>.source` path.
9
+ *
10
+ * The synthetic manifests are indistinguishable from authored `Telo.Import`
11
+ * documents downstream (alias registration, discovery, the kernel's
12
+ * import-controller), so the feature is purely additive at the declaration
13
+ * site. Pure and browser-safe — no I/O, no Node built-ins.
14
+ */
15
+ export function inlineImportManifests(moduleManifest, modulePosition) {
16
+ const raw = moduleManifest.imports;
17
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
18
+ return [];
19
+ const out = [];
20
+ for (const [alias, value] of Object.entries(raw)) {
21
+ const scalar = typeof value === "string";
22
+ const entry = scalar
23
+ ? { source: value }
24
+ : value && typeof value === "object" && !Array.isArray(value)
25
+ ? value
26
+ : undefined;
27
+ if (!entry || typeof entry.source !== "string")
28
+ continue;
29
+ const manifest = {
30
+ kind: "Telo.Import",
31
+ metadata: { name: alias },
32
+ source: entry.source,
33
+ ...(entry.variables !== undefined ? { variables: entry.variables } : {}),
34
+ ...(entry.secrets !== undefined ? { secrets: entry.secrets } : {}),
35
+ ...(entry.runtime !== undefined ? { runtime: entry.runtime } : {}),
36
+ };
37
+ out.push({ manifest, position: synthPosition(modulePosition, alias, scalar) });
38
+ }
39
+ return out;
40
+ }
41
+ /** Returns a copy of `file` with synthetic `Telo.Import` manifests (from the
42
+ * module document's inline `imports:` map) appended to `manifests` and
43
+ * `positions`. `documents` is intentionally left untouched: it is the raw
44
+ * YAML-AST array round-trip consumers pair by index, and a synthetic import
45
+ * has no backing node. Every flatten/discovery loop iterates `manifests` and
46
+ * indexes `positions[i]` — never `documents[i]` in lockstep — so the trailing
47
+ * synthetics are visible to resolution while the AST round-trip stays intact.
48
+ * Returns `file` unchanged when there is no module doc or no inline imports. */
49
+ export function desugarLoadedFile(file) {
50
+ let moduleIndex = -1;
51
+ for (let i = 0; i < file.manifests.length; i++) {
52
+ const m = file.manifests[i];
53
+ if (m && isModuleKind(m.kind)) {
54
+ moduleIndex = i;
55
+ break;
56
+ }
57
+ }
58
+ if (moduleIndex < 0)
59
+ return file;
60
+ const synthetic = inlineImportManifests(file.manifests[moduleIndex], file.positions[moduleIndex]);
61
+ if (synthetic.length === 0)
62
+ return file;
63
+ return {
64
+ ...file,
65
+ manifests: [...file.manifests, ...synthetic.map((s) => s.manifest)],
66
+ positions: [...file.positions, ...synthetic.map((s) => s.position)],
67
+ };
68
+ }
69
+ /** Build a `DocumentPosition` for a synthetic import by re-rooting the module
70
+ * document's `imports.<Alias>` position subtree at the import manifest's own
71
+ * paths (`source`, `variables.*`, `metadata.name`, …). This makes a
72
+ * diagnostic on the synthetic's `source` land on the `imports:` entry's
73
+ * authoring line rather than a phantom document. */
74
+ function synthPosition(modulePosition, alias, scalar) {
75
+ if (!modulePosition)
76
+ return { sourceLine: 0, positionIndex: new Map() };
77
+ const base = modulePosition.positionIndex;
78
+ const index = new Map();
79
+ const keyRange = base.get(`@key:imports.${alias}`);
80
+ const valueRange = base.get(`imports.${alias}`);
81
+ if (keyRange) {
82
+ index.set("metadata.name", keyRange);
83
+ index.set("@key:metadata.name", keyRange);
84
+ }
85
+ if (scalar) {
86
+ // `Console: std/console@1.2.3` — the entry value IS the source scalar.
87
+ if (valueRange)
88
+ index.set("source", valueRange);
89
+ }
90
+ else {
91
+ const valuePrefix = `imports.${alias}.`;
92
+ const keyPrefix = `@key:imports.${alias}.`;
93
+ for (const [path, range] of base) {
94
+ if (path.startsWith(valuePrefix)) {
95
+ index.set(path.slice(valuePrefix.length), range);
96
+ }
97
+ else if (path.startsWith(keyPrefix)) {
98
+ index.set(`@key:${path.slice(keyPrefix.length)}`, range);
99
+ }
100
+ }
101
+ }
102
+ if (valueRange)
103
+ index.set("", valueRange);
104
+ const sourceLine = (keyRange ?? valueRange)?.start.line ?? modulePosition.sourceLine;
105
+ return { sourceLine, positionIndex: index };
106
+ }
@@ -30,6 +30,15 @@ export declare class Loader {
30
30
  * private mutable copy must call `parseLoadedFile` directly with the
31
31
  * LoadedFile's `text`. */
32
32
  loadFile(url: string, options?: LoadOptions): Promise<LoadedFile>;
33
+ /** Parse `text` into a LoadedFile, then desugar inline `imports:` when the
34
+ * caller opted in. Desugaring lives here, not in the pure `parseLoadedFile`,
35
+ * so round-trip consumers (the editor) keep a raw manifest/AST/position
36
+ * triple they can pair by index; only resolved consumers that pass
37
+ * `desugarImports` see synthetic Telo.Import manifests. */
38
+ private parseAndMaybeDesugar;
39
+ /** Raw text of any already-cached variant for `source`, so a cache miss on
40
+ * one (compile, desugar) variant reparses without a second source read. */
41
+ private findCachedText;
33
42
  /** Load an owner file plus every partial reachable through its `include:`
34
43
  * list. Globs are expanded via the owning source's `expandGlob`. The
35
44
  * partials list is empty when the owner declares no `include:`. */
@@ -57,7 +66,7 @@ export declare class Loader {
57
66
  * owner) and return the `LoadedGraph` rooted at that owner. Returns
58
67
  * `null` only when `fileUrl` is neither an owner nor reachable from one
59
68
  * via parent-directory traversal. */
60
- loadGraphForFile(fileUrl: string): Promise<{
69
+ loadGraphForFile(fileUrl: string, options?: LoadOptions): Promise<{
61
70
  graph: LoadedGraph;
62
71
  ownerUrl: string;
63
72
  } | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,UAAU,EACV,WAAW,EACX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AASpB,qBAAa,MAAM;IACjB;;;yEAGqE;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAE3D;;;;;8BAK0B;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,qBAAqB,GAAE,cAAc,EAAE,GAAG,iBAAsB;IAmB5E,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAKtC,OAAO,CAAC,IAAI;IAMN,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUrD;;;;2CAIuC;IACvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAM7C;;;+BAG2B;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAgDvE;;wEAEoE;IAC9D,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAsB3E;;;qCAGiC;IAC3B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAwG9E;;;;;;;;sBAQkB;IAClB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAOlE,OAAO,CAAC,6BAA6B;IAarC,OAAO,CAAC,mCAAmC;IAc3C,OAAO,CAAC,2BAA2B;YAkCrB,eAAe;IAmB7B;;;0CAGsC;IAChC,gBAAgB,CACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CA0B5D"}
1
+ {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../src/manifest-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,UAAU,EACV,WAAW,EACX,YAAY,EACb,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAiBpB,qBAAa,MAAM;IACjB;;;yEAGqE;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAE3D;;;;;8BAK0B;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IAEzD,SAAS,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,qBAAqB,GAAE,cAAc,EAAE,GAAG,iBAAsB;IAmB5E,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAKtC,OAAO,CAAC,IAAI;IAMN,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUrD;;;;2CAIuC;IACvC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAM7C;;;+BAG2B;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAyCvE;;;;gEAI4D;IAC5D,OAAO,CAAC,oBAAoB;IAa5B;gFAC4E;IAC5E,OAAO,CAAC,cAAc;IAQtB;;wEAEoE;IAC9D,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAsB3E;;;qCAGiC;IAC3B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAwG9E;;;;;;;;sBAQkB;IAClB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM;IAOlE,OAAO,CAAC,6BAA6B;IAarC,OAAO,CAAC,mCAAmC;IAc3C,OAAO,CAAC,2BAA2B;YAkCrB,eAAe;IAmB7B;;;0CAGsC;IAChC,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CA0B5D"}
@@ -1,6 +1,7 @@
1
1
  import { HttpSource } from "./sources/http-source.js";
2
2
  import { RegistrySource } from "./sources/registry-source.js";
3
3
  import { buildCelEnvironment } from "./cel-environment.js";
4
+ import { desugarLoadedFile } from "./inline-imports.js";
4
5
  import { isModuleKind } from "./module-kinds.js";
5
6
  import { parseLoadedFile } from "./parse-loaded-file.js";
6
7
  import { DEFAULT_MANIFEST_FILENAME, } from "./types.js";
@@ -10,6 +11,13 @@ const SYSTEM_KINDS = new Set([
10
11
  "Telo.Import",
11
12
  "Telo.Definition",
12
13
  ]);
14
+ /** File cache variant tags: compile (c/r) × desugarImports (d/n). A desugared
15
+ * and a raw load of the same file are distinct entries so neither sees the
16
+ * wrong manifest tree. */
17
+ const CACHE_VARIANTS = ["rn", "rd", "cn", "cd"];
18
+ function variantKey(options) {
19
+ return `${options?.compile ? "c" : "r"}${options?.desugarImports ? "d" : "n"}`;
20
+ }
13
21
  export class Loader {
14
22
  /** LoadedFile cache keyed by `${compile ? "compiled" : "raw"}:${source}`.
15
23
  * Same dual-keying as the legacy ResourceManifest[] cache: a compile-mode
@@ -74,30 +82,26 @@ export class Loader {
74
82
  * private mutable copy must call `parseLoadedFile` directly with the
75
83
  * LoadedFile's `text`. */
76
84
  async loadFile(url, options) {
77
- const compileKey = options?.compile ? "compiled" : "raw";
85
+ const variant = variantKey(options);
78
86
  const knownSource = this.urlToSource.get(url);
79
87
  if (knownSource) {
80
- const cached = this.fileCache.get(`${compileKey}:${knownSource}`);
88
+ const cached = this.fileCache.get(`${variant}:${knownSource}`);
81
89
  if (cached)
82
90
  return cached;
83
- // The other compile-mode entry is cached — reparse from its text
91
+ // Another variant of this source is cached — reparse from its text
84
92
  // instead of re-reading the source.
85
93
  //
86
94
  // NOTE for watch-mode reactivation (cli/nodejs/src/commands/run.ts
87
95
  // currently has `setupWatchMode` commented out): this branch
88
96
  // assumes file contents don't change underneath a single Loader.
89
97
  // Reviving watch mode will need a public `invalidate(url)` (or
90
- // similar) that drops both `urlToSource[url]` and the cached
91
- // entries for its canonical source before the loader serves the
92
- // file again.
93
- const altKey = `${compileKey === "compiled" ? "raw" : "compiled"}:${knownSource}`;
94
- const alt = this.fileCache.get(altKey);
95
- if (alt) {
96
- const reparsed = parseLoadedFile(knownSource, url, alt.text, {
97
- compile: options?.compile,
98
- celEnv: this.celEnv,
99
- });
100
- this.fileCache.set(`${compileKey}:${knownSource}`, reparsed);
98
+ // similar) that drops both `urlToSource[url]` and every cached
99
+ // variant entry for its canonical source before the loader serves
100
+ // the file again.
101
+ const altText = this.findCachedText(knownSource);
102
+ if (altText !== undefined) {
103
+ const reparsed = this.parseAndMaybeDesugar(knownSource, url, altText, options);
104
+ this.fileCache.set(`${variant}:${knownSource}`, reparsed);
101
105
  return reparsed;
102
106
  }
103
107
  }
@@ -109,16 +113,35 @@ export class Loader {
109
113
  // for that exact URL — hit the urlToSource fast path instead of
110
114
  // falling through to a redundant `pick(url).read(url)`.
111
115
  this.urlToSource.set(source, source);
112
- const cacheKey = `${compileKey}:${source}`;
116
+ const cacheKey = `${variant}:${source}`;
113
117
  const cached = this.fileCache.get(cacheKey);
114
118
  if (cached && cached.text === text)
115
119
  return cached;
116
- const loaded = parseLoadedFile(source, url, text, {
120
+ const loaded = this.parseAndMaybeDesugar(source, url, text, options);
121
+ this.fileCache.set(cacheKey, loaded);
122
+ return loaded;
123
+ }
124
+ /** Parse `text` into a LoadedFile, then desugar inline `imports:` when the
125
+ * caller opted in. Desugaring lives here, not in the pure `parseLoadedFile`,
126
+ * so round-trip consumers (the editor) keep a raw manifest/AST/position
127
+ * triple they can pair by index; only resolved consumers that pass
128
+ * `desugarImports` see synthetic Telo.Import manifests. */
129
+ parseAndMaybeDesugar(source, requestedUrl, text, options) {
130
+ const loaded = parseLoadedFile(source, requestedUrl, text, {
117
131
  compile: options?.compile,
118
132
  celEnv: this.celEnv,
119
133
  });
120
- this.fileCache.set(cacheKey, loaded);
121
- return loaded;
134
+ return options?.desugarImports ? desugarLoadedFile(loaded) : loaded;
135
+ }
136
+ /** Raw text of any already-cached variant for `source`, so a cache miss on
137
+ * one (compile, desugar) variant reparses without a second source read. */
138
+ findCachedText(source) {
139
+ for (const v of CACHE_VARIANTS) {
140
+ const cached = this.fileCache.get(`${v}:${source}`);
141
+ if (cached)
142
+ return cached.text;
143
+ }
144
+ return undefined;
122
145
  }
123
146
  /** Load an owner file plus every partial reachable through its `include:`
124
147
  * list. Globs are expanded via the owning source's `expandGlob`. The
@@ -319,12 +342,12 @@ export class Loader {
319
342
  * owner) and return the `LoadedGraph` rooted at that owner. Returns
320
343
  * `null` only when `fileUrl` is neither an owner nor reachable from one
321
344
  * via parent-directory traversal. */
322
- async loadGraphForFile(fileUrl) {
345
+ async loadGraphForFile(fileUrl, options) {
323
346
  try {
324
- const owner = await this.loadFile(fileUrl);
347
+ const owner = await this.loadFile(fileUrl, options);
325
348
  const isOwner = owner.manifests.some((m) => m && isModuleKind(m.kind));
326
349
  if (isOwner) {
327
- const graph = await this.loadGraph(fileUrl);
350
+ const graph = await this.loadGraph(fileUrl, options);
328
351
  return { graph, ownerUrl: graph.rootSource };
329
352
  }
330
353
  }
@@ -341,7 +364,7 @@ export class Loader {
341
364
  const ownerUrl = await source.resolveOwnerOf(fileUrl);
342
365
  if (!ownerUrl)
343
366
  return null;
344
- const graph = await this.loadGraph(ownerUrl);
367
+ const graph = await this.loadGraph(ownerUrl, options);
345
368
  return { graph, ownerUrl: graph.rootSource };
346
369
  }
347
370
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-ref-sentinels.d.ts","sourceRoot":"","sources":["../src/resolve-ref-sentinels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AASnE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAK5C,kBAAkB,GAAE,gBAAgB,EAAO,GAC1C,IAAI,CA8EN"}
1
+ {"version":3,"file":"resolve-ref-sentinels.d.ts","sourceRoot":"","sources":["../src/resolve-ref-sentinels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,aAAa,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAK5C,kBAAkB,GAAE,gBAAgB,EAAO,GAC1C,IAAI,CAwEN"}
@@ -1,5 +1,4 @@
1
1
  import { isRefSentinel } from "@telorun/templating";
2
- import { isModuleKind } from "./module-kinds.js";
3
2
  import { isRefEntry } from "./reference-field-map.js";
4
3
  import { REF_RESOLUTION_SKIP_KINDS as SYSTEM_KINDS } from "./system-kinds.js";
5
4
  /**
@@ -28,17 +27,10 @@ export function resolveRefSentinels(resources, registry, aliases, aliasesByModul
28
27
  // pass — which loads the entry module only — can still resolve `!ref Alias.name` against
29
28
  // imported libraries' exported instances.
30
29
  crossModuleTargets = []) {
31
- const rootModules = new Set();
32
- for (const r of resources) {
33
- if (isModuleKind(r.kind) && typeof r.metadata?.name === "string") {
34
- rootModules.add(r.metadata.name);
35
- }
36
- }
37
30
  const moduleOf = (r) => r.metadata?.module;
38
- const isForeign = (r) => {
39
- const mod = moduleOf(r);
40
- return typeof mod === "string" && !rootModules.has(mod);
41
- };
31
+ // Forwarded exports are flagged by flattenForAnalyzer (`metadata.forwardedExport`); they're
32
+ // cross-module resolution targets only — never walked as local ref sources here.
33
+ const isForeign = (r) => r.metadata?.forwardedExport === true;
42
34
  // Local resources resolve a bare / `Self.`-qualified name; forwarded foreign exports
43
35
  // resolve an `Alias.`-qualified name keyed by (module, name).
44
36
  const byName = new Map();
package/dist/types.d.ts CHANGED
@@ -57,6 +57,15 @@ export interface LoadOptions {
57
57
  * so the kernel can evaluate them at runtime. Leave unset (false) for static analysis —
58
58
  * the analyzer works on raw strings and does not need compiled values. */
59
59
  compile?: boolean;
60
+ /** When true, each module document's inline `imports:` map is desugared into
61
+ * synthetic `Telo.Import` manifests appended to the file's `manifests` /
62
+ * `positions` (the AST `documents` array is left raw). On for every resolved
63
+ * consumer — the kernel's analysis and runtime loads, and the analyzer — so
64
+ * inline imports participate in discovery, alias resolution, and execution.
65
+ * Off for the editor's round-trip view, which reads the raw `imports:` map and
66
+ * pairs manifests to YAML nodes by index. Folded into the file cache key so a
67
+ * desugared and a raw load of the same file never collide. */
68
+ desugarImports?: boolean;
60
69
  }
61
70
  export interface LoaderInitOptions {
62
71
  /** Sources inserted with highest priority before built-ins. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;qHACqH;AACrH,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9F,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED;;oDAEoD;AACpD,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C;6EAC6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAExD;;qEAEiE;IACjE,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEjE;;qEAEiE;IACjE,cAAc,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,WAAW;IAC1B;;;+EAG2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,yDAAyD;IACzD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;6FACyF;IACzF,WAAW,CAAC,EAAE,OAAO,sBAAsB,EAAE,WAAW,CAAC;CAC1D;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;sDAUkD;IAClD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;gEAKgE;AAChE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;IACtD,WAAW,CAAC,EAAE,OAAO,0BAA0B,EAAE,kBAAkB,CAAC;IACpE;;;;+EAI2E;IAC3E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC,CAAC;CAC5E"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;qHACqH;AACrH,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AACX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9F,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,QAAQ,CAAC;IAChB,GAAG,EAAE,QAAQ,CAAC;CACf;AAED;;oDAEoD;AACpD,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAE/C;6EAC6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAExD;;qEAEiE;IACjE,UAAU,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEjE;;qEAEiE;IACjE,cAAc,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,WAAW;IAC1B;;;+EAG2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;mEAO+D;IAC/D,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;IAChC,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,yDAAyD;IACzD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;6FACyF;IACzF,WAAW,CAAC,EAAE,OAAO,sBAAsB,EAAE,WAAW,CAAC;CAC1D;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;;;;;;sDAUkD;IAClD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;gEAKgE;AAChE,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC;IACtD,WAAW,CAAC,EAAE,OAAO,0BAA0B,EAAE,kBAAkB,CAAC;IACpE;;;;+EAI2E;IAC3E,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,qBAAqB,EAAE,aAAa,CAAC,CAAC;CAC5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate-references.d.ts","sourceRoot":"","sources":["../src/validate-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMrD,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA6C/F;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,EAAE,eAAe,GACvB,kBAAkB,EAAE,CA2etB"}
1
+ {"version":3,"file":"validate-references.d.ts","sourceRoot":"","sources":["../src/validate-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMrD,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AA4C/F;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,EAAE,eAAe,GACvB,kBAAkB,EAAE,CAgftB"}