@ttsc/playground 0.30.4 → 0.31.1

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 (180) hide show
  1. package/README.md +6 -4
  2. package/lib/src/compiler/buildTsconfigJSON.d.ts +5 -0
  3. package/lib/src/compiler/buildTsconfigJSON.js +5 -0
  4. package/lib/src/compiler/buildTsconfigJSON.js.map +1 -1
  5. package/lib/src/compiler/createTypiaSourcePackMount.d.ts +9 -3
  6. package/lib/src/compiler/createTypiaSourcePackMount.js +9 -3
  7. package/lib/src/compiler/createTypiaSourcePackMount.js.map +1 -1
  8. package/lib/src/compiler/createWorkerCompiler.d.ts +5 -0
  9. package/lib/src/compiler/createWorkerCompiler.js +5 -0
  10. package/lib/src/compiler/createWorkerCompiler.js.map +1 -1
  11. package/lib/src/compiler/installDependenciesIntoMemFS.d.ts +5 -0
  12. package/lib/src/compiler/installDependenciesIntoMemFS.js +5 -0
  13. package/lib/src/compiler/installDependenciesIntoMemFS.js.map +1 -1
  14. package/lib/src/compiler/installTypiaSourcePack.d.ts +7 -2
  15. package/lib/src/compiler/installTypiaSourcePack.js +7 -2
  16. package/lib/src/compiler/installTypiaSourcePack.js.map +1 -1
  17. package/lib/src/compiler/internal/createWorkerCompilerService.d.ts +31 -0
  18. package/lib/src/compiler/internal/createWorkerCompilerService.js +22 -4
  19. package/lib/src/compiler/internal/createWorkerCompilerService.js.map +1 -1
  20. package/lib/src/compiler/internal/joinUnder.d.ts +5 -0
  21. package/lib/src/compiler/internal/joinUnder.js +5 -0
  22. package/lib/src/compiler/internal/joinUnder.js.map +1 -1
  23. package/lib/src/compiler/internal/parseLintDiagnostics.d.ts +5 -0
  24. package/lib/src/compiler/internal/parseLintDiagnostics.js +8 -3
  25. package/lib/src/compiler/internal/parseLintDiagnostics.js.map +1 -1
  26. package/lib/src/compiler/internal/safeParseTypiaTransform.d.ts +14 -1
  27. package/lib/src/compiler/internal/safeParseTypiaTransform.js +12 -1
  28. package/lib/src/compiler/internal/safeParseTypiaTransform.js.map +1 -1
  29. package/lib/src/compiler/lineColumnOf.d.ts +9 -1
  30. package/lib/src/compiler/lineColumnOf.js +23 -7
  31. package/lib/src/compiler/lineColumnOf.js.map +1 -1
  32. package/lib/src/compiler/loadTypiaSourcePack.d.ts +23 -1
  33. package/lib/src/compiler/loadTypiaSourcePack.js +48 -12
  34. package/lib/src/compiler/loadTypiaSourcePack.js.map +1 -1
  35. package/lib/src/compiler/mapDiagnostic.d.ts +7 -2
  36. package/lib/src/compiler/mapDiagnostic.js +53 -6
  37. package/lib/src/compiler/mapDiagnostic.js.map +1 -1
  38. package/lib/src/compiler/normalizeError.d.ts +9 -1
  39. package/lib/src/compiler/normalizeError.js +9 -1
  40. package/lib/src/compiler/normalizeError.js.map +1 -1
  41. package/lib/src/compiler/normalizeNodeModulePath.d.ts +5 -0
  42. package/lib/src/compiler/normalizeNodeModulePath.js +5 -0
  43. package/lib/src/compiler/normalizeNodeModulePath.js.map +1 -1
  44. package/lib/src/compiler/pickEmittedJS.d.ts +9 -2
  45. package/lib/src/compiler/pickEmittedJS.js +23 -6
  46. package/lib/src/compiler/pickEmittedJS.js.map +1 -1
  47. package/lib/src/npm/collectExternalPackageNames.d.ts +17 -0
  48. package/lib/src/npm/collectExternalPackageNames.js +51 -11
  49. package/lib/src/npm/collectExternalPackageNames.js.map +1 -1
  50. package/lib/src/npm/installPlaygroundDependencies.d.ts +10 -2
  51. package/lib/src/npm/installPlaygroundDependencies.js +18 -4
  52. package/lib/src/npm/installPlaygroundDependencies.js.map +1 -1
  53. package/lib/src/npm/internal/npmRegistry.d.ts +149 -2
  54. package/lib/src/npm/internal/npmRegistry.js +95 -4
  55. package/lib/src/npm/internal/npmRegistry.js.map +1 -1
  56. package/lib/src/npm/packageNameFromSpecifier.d.ts +5 -0
  57. package/lib/src/npm/packageNameFromSpecifier.js +7 -0
  58. package/lib/src/npm/packageNameFromSpecifier.js.map +1 -1
  59. package/lib/src/react/ConsoleViewer.d.ts +9 -0
  60. package/lib/src/react/ConsoleViewer.js +11 -2
  61. package/lib/src/react/ConsoleViewer.js.map +1 -1
  62. package/lib/src/react/DependencyProgressModal.d.ts +9 -0
  63. package/lib/src/react/DependencyProgressModal.js +9 -0
  64. package/lib/src/react/DependencyProgressModal.js.map +1 -1
  65. package/lib/src/react/DiagnosticsPanel.d.ts +9 -0
  66. package/lib/src/react/DiagnosticsPanel.js +9 -0
  67. package/lib/src/react/DiagnosticsPanel.js.map +1 -1
  68. package/lib/src/react/ExamplePicker.d.ts +9 -0
  69. package/lib/src/react/ExamplePicker.js +14 -2
  70. package/lib/src/react/ExamplePicker.js.map +1 -1
  71. package/lib/src/react/LintPane.d.ts +5 -0
  72. package/lib/src/react/LintPane.js +5 -0
  73. package/lib/src/react/LintPane.js.map +1 -1
  74. package/lib/src/react/OptionsPanel.d.ts +10 -0
  75. package/lib/src/react/OptionsPanel.js +19 -4
  76. package/lib/src/react/OptionsPanel.js.map +1 -1
  77. package/lib/src/react/PlaygroundShell.d.ts +13 -0
  78. package/lib/src/react/PlaygroundShell.js +17 -5
  79. package/lib/src/react/PlaygroundShell.js.map +1 -1
  80. package/lib/src/react/ResultViewer.d.ts +5 -0
  81. package/lib/src/react/ResultViewer.js +27 -7
  82. package/lib/src/react/ResultViewer.js.map +1 -1
  83. package/lib/src/react/SourceEditor.d.ts +10 -0
  84. package/lib/src/react/SourceEditor.js +10 -0
  85. package/lib/src/react/SourceEditor.js.map +1 -1
  86. package/lib/src/react/createCompilerClient.d.ts +5 -0
  87. package/lib/src/react/createCompilerClient.js +5 -0
  88. package/lib/src/react/createCompilerClient.js.map +1 -1
  89. package/lib/src/react/internal/PlaygroundCompilerLifecycle.d.ts +64 -1
  90. package/lib/src/react/internal/PlaygroundCompilerLifecycle.js +48 -0
  91. package/lib/src/react/internal/PlaygroundCompilerLifecycle.js.map +1 -1
  92. package/lib/src/react/internal/PlaygroundExecutionLifecycle.d.ts +42 -2
  93. package/lib/src/react/internal/PlaygroundExecutionLifecycle.js +18 -0
  94. package/lib/src/react/internal/PlaygroundExecutionLifecycle.js.map +1 -1
  95. package/lib/src/react/internal/recoverTerminalCompilerWorker.d.ts +46 -4
  96. package/lib/src/react/internal/recoverTerminalCompilerWorker.js +14 -1
  97. package/lib/src/react/internal/recoverTerminalCompilerWorker.js.map +1 -1
  98. package/lib/src/sandbox/createSandboxRequire.d.ts +12 -3
  99. package/lib/src/sandbox/createSandboxRequire.js +26 -12
  100. package/lib/src/sandbox/createSandboxRequire.js.map +1 -1
  101. package/lib/src/sandbox/loadTypiaRuntimePack.d.ts +22 -0
  102. package/lib/src/sandbox/loadTypiaRuntimePack.js +30 -1
  103. package/lib/src/sandbox/loadTypiaRuntimePack.js.map +1 -1
  104. package/lib/src/structures/IBuildTsconfigOptions.d.ts +9 -1
  105. package/lib/src/structures/ICompilerService.d.ts +112 -2
  106. package/lib/src/structures/IConsoleMessage.d.ts +5 -0
  107. package/lib/src/structures/ICreateCompilerClientOptions.d.ts +9 -2
  108. package/lib/src/structures/ICreateWorkerCompilerOptions.d.ts +11 -3
  109. package/lib/src/structures/IInstallTypiaSourcePackOptions.d.ts +7 -1
  110. package/lib/src/structures/ILintPluginConfig.d.ts +8 -1
  111. package/lib/src/structures/ILoadTypiaRuntimePackOptions.d.ts +8 -1
  112. package/lib/src/structures/IOptionToggle.d.ts +5 -0
  113. package/lib/src/structures/IPlaygroundDependencyInstallOptions.d.ts +41 -6
  114. package/lib/src/structures/IPlaygroundDependencyInstallResult.d.ts +8 -1
  115. package/lib/src/structures/IPlaygroundDependencyPackage.d.ts +9 -1
  116. package/lib/src/structures/IPlaygroundDependencyProgress.d.ts +9 -1
  117. package/lib/src/structures/IPlaygroundDependencyProgressPhase.d.ts +7 -2
  118. package/lib/src/structures/IPlaygroundDependencyRequest.d.ts +8 -1
  119. package/lib/src/structures/IPlaygroundExample.d.ts +5 -0
  120. package/lib/src/structures/IPlaygroundInstalledDependency.d.ts +8 -1
  121. package/lib/src/structures/IPlaygroundShellProps.d.ts +53 -19
  122. package/lib/src/structures/ISourceEditorProps.d.ts +16 -1
  123. package/lib/src/structures/ITransformOptions.d.ts +5 -0
  124. package/lib/src/structures/ITypiaPluginConfig.d.ts +25 -7
  125. package/package.json +6 -4
  126. package/src/compiler/buildTsconfigJSON.ts +5 -0
  127. package/src/compiler/createTypiaSourcePackMount.ts +9 -3
  128. package/src/compiler/createWorkerCompiler.ts +5 -0
  129. package/src/compiler/installDependenciesIntoMemFS.ts +5 -0
  130. package/src/compiler/installTypiaSourcePack.ts +7 -2
  131. package/src/compiler/internal/createWorkerCompilerService.ts +47 -4
  132. package/src/compiler/internal/joinUnder.ts +5 -0
  133. package/src/compiler/internal/parseLintDiagnostics.ts +8 -3
  134. package/src/compiler/internal/safeParseTypiaTransform.ts +25 -2
  135. package/src/compiler/lineColumnOf.ts +24 -8
  136. package/src/compiler/loadTypiaSourcePack.ts +57 -14
  137. package/src/compiler/mapDiagnostic.ts +67 -7
  138. package/src/compiler/normalizeError.ts +9 -1
  139. package/src/compiler/normalizeNodeModulePath.ts +5 -0
  140. package/src/compiler/pickEmittedJS.ts +22 -5
  141. package/src/npm/collectExternalPackageNames.ts +54 -13
  142. package/src/npm/installPlaygroundDependencies.ts +18 -6
  143. package/src/npm/internal/npmRegistry.ts +156 -4
  144. package/src/npm/packageNameFromSpecifier.ts +6 -0
  145. package/src/react/ConsoleViewer.tsx +10 -1
  146. package/src/react/DependencyProgressModal.tsx +9 -0
  147. package/src/react/DiagnosticsPanel.tsx +9 -0
  148. package/src/react/ExamplePicker.tsx +22 -6
  149. package/src/react/LintPane.tsx +5 -0
  150. package/src/react/OptionsPanel.tsx +22 -4
  151. package/src/react/PlaygroundShell.tsx +17 -5
  152. package/src/react/ResultViewer.tsx +28 -7
  153. package/src/react/SourceEditor.tsx +10 -0
  154. package/src/react/createCompilerClient.ts +5 -0
  155. package/src/react/internal/PlaygroundCompilerLifecycle.ts +64 -1
  156. package/src/react/internal/PlaygroundExecutionLifecycle.ts +44 -2
  157. package/src/react/internal/recoverTerminalCompilerWorker.ts +48 -4
  158. package/src/sandbox/createSandboxRequire.ts +28 -15
  159. package/src/sandbox/loadTypiaRuntimePack.ts +35 -2
  160. package/src/structures/IBuildTsconfigOptions.ts +13 -1
  161. package/src/structures/ICompilerService.ts +119 -2
  162. package/src/structures/IConsoleMessage.ts +5 -0
  163. package/src/structures/ICreateCompilerClientOptions.ts +9 -2
  164. package/src/structures/ICreateWorkerCompilerOptions.ts +15 -3
  165. package/src/structures/IInstallTypiaSourcePackOptions.ts +11 -1
  166. package/src/structures/ILintPluginConfig.ts +8 -1
  167. package/src/structures/ILoadTypiaRuntimePackOptions.ts +8 -1
  168. package/src/structures/IOptionToggle.ts +5 -0
  169. package/src/structures/IPlaygroundDependencyInstallOptions.ts +56 -6
  170. package/src/structures/IPlaygroundDependencyInstallResult.ts +12 -1
  171. package/src/structures/IPlaygroundDependencyPackage.ts +11 -1
  172. package/src/structures/IPlaygroundDependencyProgress.ts +9 -1
  173. package/src/structures/IPlaygroundDependencyProgressPhase.ts +7 -2
  174. package/src/structures/IPlaygroundDependencyRequest.ts +10 -1
  175. package/src/structures/IPlaygroundExample.ts +6 -0
  176. package/src/structures/IPlaygroundInstalledDependency.ts +11 -1
  177. package/src/structures/IPlaygroundShellProps.ts +62 -22
  178. package/src/structures/ISourceEditorProps.ts +20 -1
  179. package/src/structures/ITransformOptions.ts +7 -0
  180. package/src/structures/ITypiaPluginConfig.ts +31 -7
@@ -1,10 +1,32 @@
1
1
  import type { IInstallTypiaSourcePackOptions } from "../structures/IInstallTypiaSourcePackOptions";
2
2
  /**
3
- * Fetch the typia source pack JSON once per URL.
3
+ * Fetch the typia source pack JSON once per URL and transport identity.
4
4
  *
5
5
  * Concurrent callers share one load. A caller abort cancels that shared
6
6
  * attempt; rejection removes it from the cache so the next call retries from
7
7
  * scratch. Nothing else ends the load: how long a fetch takes belongs to the
8
8
  * network, not to a number chosen here.
9
+ *
10
+ * @evidence contracts/common.md#principled-implementation
11
+ * The source-pack loader uses fetch/AbortController and Promise sharing,
12
+ * with an explicit fetch injection seam for the same transport contract. It
13
+ * supplies source records to the existing mounting operation rather than
14
+ * coupling network loading to compiler execution.
15
+ *
16
+ * @evidence contracts/common.md#clear-and-simple-design
17
+ * One transport-specific URL map owns attempt sharing; cancellation helpers
18
+ * keep event ownership separate from response decoding and source mounting.
19
+ *
20
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
21
+ * The site supplies the URL and transport; no package name, test case or
22
+ * fixed deadline decides success. The injected transport leaves global fetch
23
+ * intact. Rejection evicts only this attempt, preserving the real failure
24
+ * instead of inventing a successful empty source pack.
25
+ *
26
+ * @evidence contracts/common.md#meaningful-documentation
27
+ * JSDoc explains the once-per-URL purpose, shared cancellation, rejection
28
+ * eviction and why an arbitrary timeout is not the network policy. Purpose
29
+ * and reasons use separate native paragraphs under the documentation skill;
30
+ * IInstallTypiaSourcePackOptions owns option documentation.
9
31
  */
10
32
  export declare function loadTypiaSourcePack(options: IInstallTypiaSourcePackOptions): Promise<Record<string, string>>;
@@ -1,46 +1,82 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadTypiaSourcePack = loadTypiaSourcePack;
4
- const packCache = new Map();
4
+ const packCaches = new WeakMap();
5
5
  /**
6
- * Fetch the typia source pack JSON once per URL.
6
+ * Fetch the typia source pack JSON once per URL and transport identity.
7
7
  *
8
8
  * Concurrent callers share one load. A caller abort cancels that shared
9
9
  * attempt; rejection removes it from the cache so the next call retries from
10
10
  * scratch. Nothing else ends the load: how long a fetch takes belongs to the
11
11
  * network, not to a number chosen here.
12
+ *
13
+ * @evidence contracts/common.md#principled-implementation
14
+ * The source-pack loader uses fetch/AbortController and Promise sharing,
15
+ * with an explicit fetch injection seam for the same transport contract. It
16
+ * supplies source records to the existing mounting operation rather than
17
+ * coupling network loading to compiler execution.
18
+ *
19
+ * @evidence contracts/common.md#clear-and-simple-design
20
+ * One transport-specific URL map owns attempt sharing; cancellation helpers
21
+ * keep event ownership separate from response decoding and source mounting.
22
+ *
23
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts
24
+ * The site supplies the URL and transport; no package name, test case or
25
+ * fixed deadline decides success. The injected transport leaves global fetch
26
+ * intact. Rejection evicts only this attempt, preserving the real failure
27
+ * instead of inventing a successful empty source pack.
28
+ *
29
+ * @evidence contracts/common.md#meaningful-documentation
30
+ * JSDoc explains the once-per-URL purpose, shared cancellation, rejection
31
+ * eviction and why an arbitrary timeout is not the network policy. Purpose
32
+ * and reasons use separate native paragraphs under the documentation skill;
33
+ * IInstallTypiaSourcePackOptions owns option documentation.
12
34
  */
13
35
  function loadTypiaSourcePack(options) {
14
- const cached = packCache.get(options.url);
36
+ const fetchImpl = options.fetch ?? globalThis.fetch;
37
+ if (!fetchImpl) {
38
+ throw new Error("loadTypiaSourcePack: no fetch implementation available in this environment.");
39
+ }
40
+ let packCache = packCaches.get(fetchImpl);
41
+ if (!packCache) {
42
+ packCache = new Map();
43
+ packCaches.set(fetchImpl, packCache);
44
+ }
45
+ const cache = packCache;
46
+ const cached = cache.get(options.url);
15
47
  if (cached) {
16
48
  attachSourcePackCancellation(cached, options.signal);
17
49
  return cached.promise;
18
50
  }
19
- const fetchImpl = options.fetch ?? globalThis.fetch?.bind(globalThis);
20
- if (!fetchImpl) {
21
- throw new Error("loadTypiaSourcePack: no fetch implementation available in this environment.");
22
- }
23
51
  const url = options.url;
52
+ const fetchPack = options.fetch ? fetchImpl : fetchImpl.bind(globalThis);
24
53
  const controller = new AbortController();
25
54
  let phase = `fetching ${url}`;
26
55
  const cancellation = createSourcePackCancellation(controller.signal, () => phase);
27
56
  let entry;
28
57
  const promise = (async () => {
29
- const response = await raceSourcePackCancellation(fetchImpl(url, { signal: controller.signal }), cancellation.promise, controller.signal, () => phase);
58
+ const response = await raceSourcePackCancellation(fetchPack(url, { signal: controller.signal }), cancellation.promise, controller.signal, () => phase);
30
59
  if (!response.ok) {
31
60
  throw new Error(`loadTypiaSourcePack: failed to fetch ${url}: ${response.status}`);
32
61
  }
33
62
  phase = `reading JSON from ${url}`;
34
- return (await raceSourcePackCancellation(response.json(), cancellation.promise, controller.signal, () => phase));
63
+ const pack = await raceSourcePackCancellation(response.json(), cancellation.promise, controller.signal, () => phase);
64
+ if (!pack ||
65
+ typeof pack !== "object" ||
66
+ Array.isArray(pack) ||
67
+ !Object.values(pack).every((value) => typeof value === "string")) {
68
+ throw new Error("loadTypiaSourcePack: expected a source-text record map.");
69
+ }
70
+ return pack;
35
71
  })()
36
72
  .catch((error) => {
37
- if (packCache.get(url) === entry)
38
- packCache.delete(url);
73
+ if (cache.get(url) === entry)
74
+ cache.delete(url);
39
75
  throw error;
40
76
  })
41
77
  .finally(cancellation.dispose);
42
78
  entry = { controller, promise };
43
- packCache.set(url, entry);
79
+ cache.set(url, entry);
44
80
  attachSourcePackCancellation(entry, options.signal);
45
81
  return promise;
46
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"loadTypiaSourcePack.js","sourceRoot":"","sources":["../../../src/compiler/loadTypiaSourcePack.ts"],"names":[],"mappings":";;;AAiBA,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;AAErD;;;;;;;GAOG;AACH,6BACE,OAAuC;IAEvC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,MAAM,EAAE,CAAC;QACX,4BAA4B,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACtE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACxB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,IAAI,KAAK,GAAG,YAAY,GAAG,EAAE,CAAC;IAC9B,MAAM,YAAY,GAAG,4BAA4B,CAC/C,UAAU,CAAC,MAAM,EACjB,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC;IACF,IAAI,KAAuB,CAAC;IAC5B,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;QAC1B,MAAM,QAAQ,GAAG,MAAM,0BAA0B,CAC/C,SAAS,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,EAC7C,YAAY,CAAC,OAAO,EACpB,UAAU,CAAC,MAAM,EACjB,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,wCAAwC,GAAG,KAAK,QAAQ,CAAC,MAAM,EAAE,CAClE,CAAC;QACJ,CAAC;QAED,KAAK,GAAG,qBAAqB,GAAG,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,0BAA0B,CACtC,QAAQ,CAAC,IAAI,EAAE,EACf,YAAY,CAAC,OAAO,EACpB,UAAU,CAAC,MAAM,EACjB,GAAG,EAAE,CAAC,KAAK,CACZ,CAA2B,CAAC;IAC/B,CAAC,CAAC,EAAE;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK;YAAE,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxD,MAAM,KAAK,CAAC;IACd,CAAC,CAAC;SACD,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAEjC,KAAK,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IAChC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1B,4BAA4B,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,4BAA4B,CACnC,KAAsB,EACtB,YAAqC;IAErC,MAAM,eAAe,GAAG,GAAS,EAAE;QACjC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;gBACrB,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,YAAY,EAAE,MAAM;aACU,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC;IACF,IAAI,YAAY,EAAE,OAAO;QAAE,eAAe,EAAE,CAAC;;QACxC,YAAY,EAAE,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9E,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,YAAY,EAAE,mBAAmB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAC9D,CAAC,CAAC;IACF,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,4BAA4B,CACnC,MAAmB,EACnB,QAAsB;IAEtB,IAAI,kBAA2C,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;QACtD,kBAAkB,GAAG,MAAM,CAAC;IAC9B,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,kBAAkB,CAAC,2BAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC,CAAC;IACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAC9B,OAAO;QACL,OAAO;QACP,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,IAAgB,EAChB,YAA4B,EAC5B,MAAmB,EACnB,QAAsB;IAEtB,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,2BAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAClC,MAAmB,EACnB,KAAa;IAEb,MAAM,MAAM,GAAG,MAAM,CAAC,MAAkD,CAAC;IACzE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,sCAAsC,KAAK,GAAG,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,MAAM,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IACvE,IAAI,KAAK,KAAK,SAAS;QAAG,KAAqC,CAAC,KAAK,GAAG,KAAK,CAAC;IAC9E,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"loadTypiaSourcePack.js","sourceRoot":"","sources":["../../../src/compiler/loadTypiaSourcePack.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,12 @@ import type { ICompilerService } from "../structures/ICompilerService";
3
3
  /**
4
4
  * Convert a `@ttsc/wasm` diagnostic into the playground's normalized shape.
5
5
  *
6
- * Falls back to computing line/column from the source text when the wasm
7
- * diagnostic did not carry them (some plugin emitters drop them).
6
+ * Native positions and spans count UTF-8 bytes; the editor counts UTF-16 units.
7
+ * Source text converts that boundary, including optional coordinates.
8
+ *
9
+ * @evidence contracts/common.md#principled-implementation Native byte offsets and spans are converted against the same source into UTF-16 editor coordinates; optional line/byte-column metadata supplies the start only when the absolute offset is absent.
10
+ * @evidence contracts/common.md#clear-and-simple-design A single mapping keeps WASM diagnostic fields and UI conventions separate from rendering.
11
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Fallback is based on omitted producer metadata, not special casing a diagnostic code or source fixture.
12
+ * @evidence contracts/common.md#meaningful-documentation Native prose explains producer-to-UI conversion and fallback purpose, following documentation-skill paragraph separation.
8
13
  */
9
14
  export declare function mapDiagnostic(diag: NonNullable<ITtscCompileResult["diagnostics"]>[number], source: string): ICompilerService.IDiagnostic;
@@ -5,18 +5,65 @@ const lineColumnOf_1 = require("./lineColumnOf");
5
5
  /**
6
6
  * Convert a `@ttsc/wasm` diagnostic into the playground's normalized shape.
7
7
  *
8
- * Falls back to computing line/column from the source text when the wasm
9
- * diagnostic did not carry them (some plugin emitters drop them).
8
+ * Native positions and spans count UTF-8 bytes; the editor counts UTF-16 units.
9
+ * Source text converts that boundary, including optional coordinates.
10
+ *
11
+ * @evidence contracts/common.md#principled-implementation Native byte offsets and spans are converted against the same source into UTF-16 editor coordinates; optional line/byte-column metadata supplies the start only when the absolute offset is absent.
12
+ * @evidence contracts/common.md#clear-and-simple-design A single mapping keeps WASM diagnostic fields and UI conventions separate from rendering.
13
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Fallback is based on omitted producer metadata, not special casing a diagnostic code or source fixture.
14
+ * @evidence contracts/common.md#meaningful-documentation Native prose explains producer-to-UI conversion and fallback purpose, following documentation-skill paragraph separation.
10
15
  */
11
16
  function mapDiagnostic(diag, source) {
12
- const fallback = (0, lineColumnOf_1.lineColumnOf)(source, diag.start);
17
+ const start = typeof diag.start === "number" &&
18
+ Number.isFinite(diag.start) &&
19
+ diag.start >= 0
20
+ ? utf16OffsetOfBytes(source, diag.start)
21
+ : optionalStart(source, diag.line, diag.character);
22
+ const location = (0, lineColumnOf_1.lineColumnOf)(source, start);
23
+ const byteLength = typeof diag.length === "number" && Number.isFinite(diag.length)
24
+ ? Math.max(0, Math.trunc(diag.length))
25
+ : 0;
26
+ const end = utf16OffsetOfBytes(source, byteLength, start);
13
27
  return {
14
- line: diag.line && diag.line > 0 ? diag.line : fallback.line,
15
- column: diag.character && diag.character > 0 ? diag.character : fallback.column,
16
- length: typeof diag.length === "number" ? diag.length : 1,
28
+ line: location.line,
29
+ column: location.column,
30
+ length: Math.max(1, end - start),
17
31
  severity: diag.category === "warning" ? "warning" : "error",
18
32
  message: diag.messageText,
19
33
  code: typeof diag.code === "number" ? `TS${diag.code}` : String(diag.code),
20
34
  };
21
35
  }
36
+ /** Convert a UTF-8 byte boundary to its JavaScript string offset. */
37
+ function utf16OffsetOfBytes(source, bytes, start = 0) {
38
+ let offset = start;
39
+ let consumed = 0;
40
+ while (offset < source.length && consumed < bytes) {
41
+ const code = source.codePointAt(offset);
42
+ const width = code <= 0x7f ? 1 : code <= 0x7ff ? 2 : code <= 0xffff ? 3 : 4;
43
+ if (consumed + width > bytes)
44
+ break;
45
+ consumed += width;
46
+ offset += code > 0xffff ? 2 : 1;
47
+ }
48
+ return offset;
49
+ }
50
+ /** Optional native line and byte-column metadata uses the same source domain. */
51
+ function optionalStart(source, line, character) {
52
+ let start = 0;
53
+ const targetLine = typeof line === "number" && Number.isFinite(line)
54
+ ? Math.max(1, Math.trunc(line))
55
+ : 1;
56
+ for (let current = 1; current < targetLine && start < source.length; ++current) {
57
+ while (start < source.length &&
58
+ ![10, 13, 0x2028, 0x2029].includes(source.charCodeAt(start)))
59
+ ++start;
60
+ const code = source.charCodeAt(start++);
61
+ if (code === 13 && source.charCodeAt(start) === 10)
62
+ ++start;
63
+ }
64
+ const column = typeof character === "number" && Number.isFinite(character)
65
+ ? Math.max(0, Math.trunc(character) - 1)
66
+ : 0;
67
+ return Math.min(source.length, utf16OffsetOfBytes(source, column, start));
68
+ }
22
69
  //# sourceMappingURL=mapDiagnostic.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mapDiagnostic.js","sourceRoot":"","sources":["../../../src/compiler/mapDiagnostic.ts"],"names":[],"mappings":";;;AAGA,iDAA8C;AAE9C;;;;;GAKG;AACH,uBACE,IAA4D,EAC5D,MAAc;IAEd,MAAM,QAAQ,GAAG,IAAA,2BAAY,EAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI;QAC5D,MAAM,EACJ,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM;QACzE,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACzD,QAAQ,EAAE,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;QAC3D,OAAO,EAAE,IAAI,CAAC,WAAW;QACzB,IAAI,EAAE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;KAC3E,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"mapDiagnostic.js","sourceRoot":"","sources":["../../../src/compiler/mapDiagnostic.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,10 @@
1
- /** Best-effort error normalization for tgrid transport. */
1
+ /**
2
+ * Normalize native errors to enumerable fields for tgrid transport; preserve
3
+ * message-bearing records and stringify other thrown values.
4
+ *
5
+ * @evidence contracts/common.md#principled-implementation Explicit Error field copying preserves non-enumerable message and stack while carrying the terminal-runtime string code across RPC.
6
+ * @evidence contracts/common.md#clear-and-simple-design One normalization boundary leaves rendering and recovery classification to their consumers.
7
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The mapper carries actual errors without converting rejection into fabricated compiler success.
8
+ * @evidence contracts/common.md#meaningful-documentation Native prose states copying and preservation policies, separated from tags under the documentation skill.
9
+ */
2
10
  export declare function normalizeError(error: unknown): unknown;
@@ -1,7 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeError = normalizeError;
4
- /** Best-effort error normalization for tgrid transport. */
4
+ /**
5
+ * Normalize native errors to enumerable fields for tgrid transport; preserve
6
+ * message-bearing records and stringify other thrown values.
7
+ *
8
+ * @evidence contracts/common.md#principled-implementation Explicit Error field copying preserves non-enumerable message and stack while carrying the terminal-runtime string code across RPC.
9
+ * @evidence contracts/common.md#clear-and-simple-design One normalization boundary leaves rendering and recovery classification to their consumers.
10
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The mapper carries actual errors without converting rejection into fabricated compiler success.
11
+ * @evidence contracts/common.md#meaningful-documentation Native prose states copying and preservation policies, separated from tags under the documentation skill.
12
+ */
5
13
  function normalizeError(error) {
6
14
  if (error instanceof Error) {
7
15
  const normalized = {
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeError.js","sourceRoot":"","sources":["../../../src/compiler/normalizeError.ts"],"names":[],"mappings":";;;AAAA,2DAA2D;AAC3D,wBAA+B,KAAc;IAC3C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,UAAU,GAKZ;YACF,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC;QACF,MAAM,IAAI,GAAI,KAAoC,CAAC,IAAI,CAAC;QACxD,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC;QACrD,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IACE,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,SAAS,IAAK,KAAiC;QAE/C,OAAO,KAAK,CAAC;IACf,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"normalizeError.js","sourceRoot":"","sources":["../../../src/compiler/normalizeError.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;GAQG;AACH,wBAA+B,KAAc;IAC3C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,UAAU,GAKZ;YACF,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC;QACF,MAAM,IAAI,GAAI,KAAoC,CAAC,IAAI,CAAC;QACxD,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC;QACrD,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IACE,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,SAAS,IAAK,KAAiC;QAE/C,OAAO,KAAK,CAAC;IACf,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACnD,CAAC"}
@@ -4,5 +4,10 @@
4
4
  *
5
5
  * Returns `null` for paths that don't match the expected shape — the caller
6
6
  * skips those entries instead of writing them to the MemFS.
7
+ *
8
+ * @evidence contracts/common.md#principled-implementation Separator normalization establishes the virtual namespace, prefix checking restricts writes to node_modules and rejecting parent segments prevents root escape.
9
+ * @evidence contracts/common.md#clear-and-simple-design One path gate returns a normalized key or null; callers own writes and rejection policy.
10
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The same structural checks apply to every package entry without allowlisting consumers.
11
+ * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain accepted spelling, confinement and null meaning under the documentation skill.
7
12
  */
8
13
  export declare function normalizeNodeModulePath(path: string): string | null;
@@ -7,6 +7,11 @@ exports.normalizeNodeModulePath = normalizeNodeModulePath;
7
7
  *
8
8
  * Returns `null` for paths that don't match the expected shape — the caller
9
9
  * skips those entries instead of writing them to the MemFS.
10
+ *
11
+ * @evidence contracts/common.md#principled-implementation Separator normalization establishes the virtual namespace, prefix checking restricts writes to node_modules and rejecting parent segments prevents root escape.
12
+ * @evidence contracts/common.md#clear-and-simple-design One path gate returns a normalized key or null; callers own writes and rejection policy.
13
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The same structural checks apply to every package entry without allowlisting consumers.
14
+ * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain accepted spelling, confinement and null meaning under the documentation skill.
10
15
  */
11
16
  function normalizeNodeModulePath(path) {
12
17
  const normalized = path.replace(/\\/g, "/").replace(/^\/+/, "");
@@ -1 +1 @@
1
- {"version":3,"file":"normalizeNodeModulePath.js","sourceRoot":"","sources":["../../../src/compiler/normalizeNodeModulePath.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,iCAAwC,IAAY;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3E,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"normalizeNodeModulePath.js","sourceRoot":"","sources":["../../../src/compiler/normalizeNodeModulePath.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;GAWG;AACH,iCAAwC,IAAY;IAClD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,IAAI,CAAC;IACzD,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3E,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -1,6 +1,13 @@
1
1
  /**
2
2
  * Pick the most likely emitted JavaScript file from a compile result's output
3
- * map. Tries common paths first, then falls back to the first `.js` entry.
4
- * Returns null when no `.js` was emitted.
3
+ * map. Tries the default playground layout (`rootDir` `src`, `outDir` `dist`,
4
+ * which emits `dist/playground.js` for `src/playground.ts`) and other common
5
+ * paths first, then falls back to the first `.js` entry. Returns null when no
6
+ * `.js` was emitted.
7
+ *
8
+ * @evidence contracts/common.md#principled-implementation The first candidate is the default playground layout (the entry's path below the default `src` root under `dist`), the others cover layouts rooted at the project; the first remaining JavaScript entry is an explicitly heuristic fallback, not a general entrypoint solver.
9
+ * @evidence contracts/common.md#clear-and-simple-design A small selector separates UI output choice from compiler emit configuration.
10
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Layout candidates are product defaults rather than fixture filenames, and absent JavaScript remains null.
11
+ * @evidence contracts/common.md#meaningful-documentation Native prose honestly documents priority and heuristic fallback, separated from tags under the documentation skill.
5
12
  */
6
13
  export declare function pickEmittedJS(output: Record<string, string>, entryFile: string): string | null;
@@ -3,19 +3,36 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.pickEmittedJS = pickEmittedJS;
4
4
  /**
5
5
  * Pick the most likely emitted JavaScript file from a compile result's output
6
- * map. Tries common paths first, then falls back to the first `.js` entry.
7
- * Returns null when no `.js` was emitted.
6
+ * map. Tries the default playground layout (`rootDir` `src`, `outDir` `dist`,
7
+ * which emits `dist/playground.js` for `src/playground.ts`) and other common
8
+ * paths first, then falls back to the first `.js` entry. Returns null when no
9
+ * `.js` was emitted.
10
+ *
11
+ * @evidence contracts/common.md#principled-implementation The first candidate is the default playground layout (the entry's path below the default `src` root under `dist`), the others cover layouts rooted at the project; the first remaining JavaScript entry is an explicitly heuristic fallback, not a general entrypoint solver.
12
+ * @evidence contracts/common.md#clear-and-simple-design A small selector separates UI output choice from compiler emit configuration.
13
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Layout candidates are product defaults rather than fixture filenames, and absent JavaScript remains null.
14
+ * @evidence contracts/common.md#meaningful-documentation Native prose honestly documents priority and heuristic fallback, separated from tags under the documentation skill.
8
15
  */
9
16
  function pickEmittedJS(output, entryFile) {
10
17
  const base = entryFile.replace(/\.[cm]?tsx?$/i, ".js");
11
- const candidates = [`dist/${base}`, `dist/src/${base}`, `src/${base}`, base];
18
+ // `buildTsconfigJSON` roots sources at `src` and emits to `dist`, so the
19
+ // default entry `src/playground.ts` is reported as `dist/playground.js`.
20
+ const underSrcRoot = base.replace(/^src\//, "");
21
+ const candidates = [
22
+ `dist/${underSrcRoot}`,
23
+ `dist/${base}`,
24
+ `dist/src/${base}`,
25
+ `src/${base}`,
26
+ base,
27
+ ];
12
28
  for (const key of candidates) {
13
29
  if (output[key] !== undefined)
14
30
  return output[key];
15
31
  }
16
- const jsKeys = Object.keys(output).filter((k) => k.endsWith(".js"));
17
- if (jsKeys.length > 0)
18
- return output[jsKeys[0]] ?? null;
32
+ for (const key of Object.keys(output)) {
33
+ if (key.endsWith(".js"))
34
+ return output[key] ?? null;
35
+ }
19
36
  return null;
20
37
  }
21
38
  //# sourceMappingURL=pickEmittedJS.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pickEmittedJS.js","sourceRoot":"","sources":["../../../src/compiler/pickEmittedJS.ts"],"names":[],"mappings":";;;AAAA;;;;GAIG;AACH,uBACE,MAA8B,EAC9B,SAAiB;IAEjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,YAAY,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC7E,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACpE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,IAAI,IAAI,CAAC;IACzD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"pickEmittedJS.js","sourceRoot":"","sources":["../../../src/compiler/pickEmittedJS.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;GAWG;AACH,uBACE,MAA8B,EAC9B,SAAiB;IAEjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACvD,yEAAyE;IACzE,yEAAyE;IACzE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG;QACjB,QAAQ,YAAY,EAAE;QACtB,QAAQ,IAAI,EAAE;QACd,YAAY,IAAI,EAAE;QAClB,OAAO,IAAI,EAAE;QACb,IAAI;KACL,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,5 +1,22 @@
1
1
  /**
2
2
  * Scan `source` for `import` / `require` specifiers and return the unique
3
3
  * sorted list of bare npm package names that are not in `ignoredPackages`.
4
+ *
5
+ * This is a lexical discovery pass, not name binding: a locally shadowed direct
6
+ * require call still looks like a dependency request. Computed strings are
7
+ * omitted.
8
+ *
9
+ * Static arguments are quoted strings and substitution-free, escape-free
10
+ * templates (`require(`x`)`, `import(`x`)`). Deliberate limits of the
11
+ * TypeScript-source lane: JSX is not lexed (the playground entry is a `.ts`
12
+ * file), so quote or `import` text in JSX children can be misread; a type
13
+ * argument between the callee and its parenthesis (`require<T>("x")`) is not
14
+ * recognized because `require` is not generic; and a source-phase import
15
+ * (`import source x from "y"`) collects `y`, the package it loads.
16
+ *
17
+ * @evidence contracts/common.md#principled-implementation Tokenization distinguishes executable quoted and static-template specifiers from inert comments, strings and regex bodies; package-name normalization and a Set produce unique sorted install requests. Lexical discovery does not resolve shadowed require bindings.
18
+ * @evidence contracts/common.md#clear-and-simple-design Lexer, module-construct recognition and package filtering are separate local responsibilities, without importing the full compiler into browser keystroke discovery.
19
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Ignored package names are explicit caller policy; source matching does not fabricate dependency results for known examples.
20
+ * @evidence contracts/common.md#meaningful-documentation Native prose states discovery domain and binding limitations; helper comments explain escaped strings and lexical boundaries under the documentation skill.
4
21
  */
5
22
  export declare function collectExternalPackageNames(source: string, ignoredPackages?: Iterable<string>): string[];
@@ -6,6 +6,23 @@ const packageNameFromSpecifier_1 = require("./packageNameFromSpecifier");
6
6
  /**
7
7
  * Scan `source` for `import` / `require` specifiers and return the unique
8
8
  * sorted list of bare npm package names that are not in `ignoredPackages`.
9
+ *
10
+ * This is a lexical discovery pass, not name binding: a locally shadowed direct
11
+ * require call still looks like a dependency request. Computed strings are
12
+ * omitted.
13
+ *
14
+ * Static arguments are quoted strings and substitution-free, escape-free
15
+ * templates (`require(`x`)`, `import(`x`)`). Deliberate limits of the
16
+ * TypeScript-source lane: JSX is not lexed (the playground entry is a `.ts`
17
+ * file), so quote or `import` text in JSX children can be misread; a type
18
+ * argument between the callee and its parenthesis (`require<T>("x")`) is not
19
+ * recognized because `require` is not generic; and a source-phase import
20
+ * (`import source x from "y"`) collects `y`, the package it loads.
21
+ *
22
+ * @evidence contracts/common.md#principled-implementation Tokenization distinguishes executable quoted and static-template specifiers from inert comments, strings and regex bodies; package-name normalization and a Set produce unique sorted install requests. Lexical discovery does not resolve shadowed require bindings.
23
+ * @evidence contracts/common.md#clear-and-simple-design Lexer, module-construct recognition and package filtering are separate local responsibilities, without importing the full compiler into browser keystroke discovery.
24
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Ignored package names are explicit caller policy; source matching does not fabricate dependency results for known examples.
25
+ * @evidence contracts/common.md#meaningful-documentation Native prose states discovery domain and binding limitations; helper comments explain escaped strings and lexical boundaries under the documentation skill.
9
26
  */
10
27
  function collectExternalPackageNames(source, ignoredPackages = BUILT_IN_PLAYGROUND_PACKAGES_1.BUILT_IN_PLAYGROUND_PACKAGES) {
11
28
  const ignored = new Set(ignoredPackages);
@@ -32,11 +49,22 @@ function collectExternalPackageNames(source, ignoredPackages = BUILT_IN_PLAYGROU
32
49
  function collectModuleSpecifiers(source) {
33
50
  const tokens = tokenize(source);
34
51
  const out = [];
52
+ // A quoted literal only; `import "x"` and `from "x"` cannot take a template.
53
+ const asQuoted = (token) => token && token.kind === "string" && !token.template ? token.value : null;
54
+ // A call argument may also be a static template: `require(`x`)`.
35
55
  const asString = (token) => token && token.kind === "string" ? token.value : null;
36
56
  const isOpenParen = (token) => token !== undefined && token.kind === "punct" && token.value === "(";
37
- const isMemberAccess = (token) => token !== undefined &&
38
- token.kind === "punct" &&
39
- (token.value === "." || token.value === "?.");
57
+ const isPunct = (token, value) => token !== undefined && token.kind === "punct" && token.value === value;
58
+ // `obj.name`, `obj?.name` and `this.#name` are not the free binding. The
59
+ // three dots of a spread are not a member access.
60
+ const isMemberAccessAt = (index) => {
61
+ const previous = tokens[index - 1];
62
+ if (isPunct(previous, "#") || isPunct(previous, "?."))
63
+ return true;
64
+ if (!isPunct(previous, "."))
65
+ return false;
66
+ return !(isPunct(tokens[index - 2], ".") && isPunct(tokens[index - 3], "."));
67
+ };
40
68
  const isOptionalChain = (token) => token !== undefined && token.kind === "punct" && token.value === "?.";
41
69
  for (let i = 0; i < tokens.length; i++) {
42
70
  const token = tokens[i];
@@ -44,7 +72,7 @@ function collectModuleSpecifiers(source) {
44
72
  continue;
45
73
  if (token.value === "require") {
46
74
  // `obj.require(...)` is an unrelated method call, not CommonJS require.
47
- if (isMemberAccess(tokens[i - 1]))
75
+ if (isMemberAccessAt(i))
48
76
  continue;
49
77
  const optional = isOptionalChain(tokens[i + 1]) && isOpenParen(tokens[i + 2]);
50
78
  if (isOpenParen(tokens[i + 1]) || optional) {
@@ -56,7 +84,7 @@ function collectModuleSpecifiers(source) {
56
84
  }
57
85
  if (token.value === "import" || token.value === "export") {
58
86
  // `foo.import(...)` / `import.meta` are not module-loading imports.
59
- if (token.value === "import" && isMemberAccess(tokens[i - 1]))
87
+ if (token.value === "import" && isMemberAccessAt(i))
60
88
  continue;
61
89
  // Dynamic `import("x")`.
62
90
  if (token.value === "import" && isOpenParen(tokens[i + 1])) {
@@ -67,7 +95,7 @@ function collectModuleSpecifiers(source) {
67
95
  }
68
96
  // Side-effect `import "x"`.
69
97
  if (token.value === "import") {
70
- const bare = asString(tokens[i + 1]);
98
+ const bare = asQuoted(tokens[i + 1]);
71
99
  if (bare !== null) {
72
100
  out.push(bare);
73
101
  continue;
@@ -99,7 +127,9 @@ function findFromSpecifier(tokens, start) {
99
127
  return null;
100
128
  if (token.kind === "word" && token.value === "from") {
101
129
  const next = tokens[i + 1];
102
- return next && next.kind === "string" ? next.value : null;
130
+ return next && next.kind === "string" && !next.template
131
+ ? next.value
132
+ : null;
103
133
  }
104
134
  }
105
135
  return null;
@@ -302,7 +332,7 @@ function tokenize(source) {
302
332
  // Line comment.
303
333
  if (c === "/" && source[i + 1] === "/") {
304
334
  i += 2;
305
- while (i < n && source[i] !== "\n")
335
+ while (i < n && !isLineTerminator(source[i]))
306
336
  i++;
307
337
  continue;
308
338
  }
@@ -334,9 +364,12 @@ function tokenize(source) {
334
364
  // JavaScript and must receive the same lexical treatment as top-level code.
335
365
  if (c === "`") {
336
366
  i++;
367
+ // A template with no substitution and no escape is one static string.
368
+ let staticValue = "";
337
369
  while (i < n) {
338
370
  const d = source[i];
339
371
  if (d === "\\") {
372
+ staticValue = null;
340
373
  i += 2;
341
374
  continue;
342
375
  }
@@ -347,15 +380,22 @@ function tokenize(source) {
347
380
  if (d === "$" && source[i + 1] === "{") {
348
381
  const start = i + 2;
349
382
  const end = findTemplateSubstitutionEnd(source, start);
383
+ staticValue = null;
350
384
  context.pushOther();
351
- tokens.push(...tokenize(source.slice(start, end)));
385
+ for (const entryToAppend of tokenize(source.slice(start, end)))
386
+ tokens.push(entryToAppend);
352
387
  context.pushOther();
353
388
  i = end < n ? end + 1 : end;
354
389
  continue;
355
390
  }
391
+ if (staticValue !== null)
392
+ staticValue += d;
356
393
  i++;
357
394
  }
358
- context.pushOther();
395
+ if (staticValue !== null && source[i - 1] === "`")
396
+ tokens.push({ kind: "string", value: staticValue, template: true });
397
+ else
398
+ context.pushOther();
359
399
  continue;
360
400
  }
361
401
  // Identifier / keyword.
@@ -419,7 +459,7 @@ function findTemplateSubstitutionEnd(source, start) {
419
459
  }
420
460
  if (c === "/" && source[i + 1] === "/") {
421
461
  i += 2;
422
- while (i < source.length && source[i] !== "\n")
462
+ while (i < source.length && !isLineTerminator(source[i]))
423
463
  i++;
424
464
  continue;
425
465
  }