@pierre/diffs 1.5.2 → 1.6.0-beta.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 (274) hide show
  1. package/README.md +4 -3
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +6 -5
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts.map +1 -1
  6. package/dist/components/File.js +11 -6
  7. package/dist/components/File.js.map +1 -1
  8. package/dist/components/FileDiff.d.ts.map +1 -1
  9. package/dist/components/FileDiff.js +12 -7
  10. package/dist/components/FileDiff.js.map +1 -1
  11. package/dist/components/FileStream.d.ts +6 -4
  12. package/dist/components/FileStream.d.ts.map +1 -1
  13. package/dist/components/FileStream.js +49 -36
  14. package/dist/components/FileStream.js.map +1 -1
  15. package/dist/constants.d.ts +3 -2
  16. package/dist/constants.d.ts.map +1 -1
  17. package/dist/constants.js +2 -1
  18. package/dist/constants.js.map +1 -1
  19. package/dist/editor/editor.d.ts +2 -1
  20. package/dist/editor/editor.d.ts.map +1 -1
  21. package/dist/editor/editor.js +5 -1
  22. package/dist/editor/editor.js.map +1 -1
  23. package/dist/editor/tokenizer.d.ts +6 -4
  24. package/dist/editor/tokenizer.d.ts.map +1 -1
  25. package/dist/editor/tokenizer.js +25 -470
  26. package/dist/editor/tokenizer.js.map +1 -1
  27. package/dist/highlighter/DiffsEditorTokenizer.d.ts +16 -0
  28. package/dist/highlighter/DiffsEditorTokenizer.d.ts.map +1 -0
  29. package/dist/highlighter/DiffsEditorTokenizer.js +0 -0
  30. package/dist/highlighter/DiffsHighlighter.d.ts +41 -0
  31. package/dist/highlighter/DiffsHighlighter.d.ts.map +1 -0
  32. package/dist/highlighter/DiffsHighlighter.js +39 -0
  33. package/dist/highlighter/DiffsHighlighter.js.map +1 -0
  34. package/dist/highlighter/backends/highlights.d.ts +26 -0
  35. package/dist/highlighter/backends/highlights.d.ts.map +1 -0
  36. package/dist/highlighter/backends/highlights.js +71 -0
  37. package/dist/highlighter/backends/highlights.js.map +1 -0
  38. package/dist/highlighter/backends/shiki.d.ts +27 -0
  39. package/dist/highlighter/backends/shiki.d.ts.map +1 -0
  40. package/dist/highlighter/backends/shiki.js +107 -0
  41. package/dist/highlighter/backends/shiki.js.map +1 -0
  42. package/dist/highlighter/highlighterType.d.ts +13 -0
  43. package/dist/highlighter/highlighterType.d.ts.map +1 -0
  44. package/dist/highlighter/highlighterType.js +32 -0
  45. package/dist/highlighter/highlighterType.js.map +1 -0
  46. package/dist/highlighter/highlights-editor.d.ts +24 -0
  47. package/dist/highlighter/highlights-editor.d.ts.map +1 -0
  48. package/dist/highlighter/highlights-editor.js +166 -0
  49. package/dist/highlighter/highlights-editor.js.map +1 -0
  50. package/dist/highlighter/highlights-stream.d.ts +20 -0
  51. package/dist/highlighter/highlights-stream.d.ts.map +1 -0
  52. package/dist/highlighter/highlights-stream.js +93 -0
  53. package/dist/highlighter/highlights-stream.js.map +1 -0
  54. package/dist/highlighter/languages/areLanguagesAttached.d.ts +2 -1
  55. package/dist/highlighter/languages/areLanguagesAttached.d.ts.map +1 -1
  56. package/dist/highlighter/languages/areLanguagesAttached.js +4 -6
  57. package/dist/highlighter/languages/areLanguagesAttached.js.map +1 -1
  58. package/dist/highlighter/languages/attachResolvedLanguages.d.ts +6 -1
  59. package/dist/highlighter/languages/attachResolvedLanguages.d.ts.map +1 -1
  60. package/dist/highlighter/languages/attachResolvedLanguages.js +6 -11
  61. package/dist/highlighter/languages/attachResolvedLanguages.js.map +1 -1
  62. package/dist/highlighter/languages/constants.d.ts +1 -1
  63. package/dist/highlighter/languages/getResolvedLanguages.d.ts +1 -1
  64. package/dist/highlighter/languages/getResolvedOrResolveLanguage.d.ts +1 -1
  65. package/dist/highlighter/languages/resolveLanguage.d.ts +1 -1
  66. package/dist/highlighter/languages/resolveLanguage.d.ts.map +1 -1
  67. package/dist/highlighter/languages/resolveLanguage.js +19 -16
  68. package/dist/highlighter/languages/resolveLanguage.js.map +1 -1
  69. package/dist/highlighter/languages/resolveLanguages.d.ts +1 -1
  70. package/dist/highlighter/shared_highlighter.d.ts +23 -9
  71. package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  72. package/dist/highlighter/shared_highlighter.js +59 -47
  73. package/dist/highlighter/shared_highlighter.js.map +1 -1
  74. package/dist/highlighter/shiki-editor.d.ts +25 -0
  75. package/dist/highlighter/shiki-editor.d.ts.map +1 -0
  76. package/dist/highlighter/shiki-editor.js +483 -0
  77. package/dist/highlighter/shiki-editor.js.map +1 -0
  78. package/dist/highlighter/shiki-stream.d.ts +20 -0
  79. package/dist/highlighter/shiki-stream.d.ts.map +1 -0
  80. package/dist/highlighter/shiki-stream.js +60 -0
  81. package/dist/highlighter/shiki-stream.js.map +1 -0
  82. package/dist/highlighter/stream-tokenizer.d.ts +40 -0
  83. package/dist/highlighter/stream-tokenizer.d.ts.map +1 -0
  84. package/dist/highlighter/stream-tokenizer.js +70 -0
  85. package/dist/highlighter/stream-tokenizer.js.map +1 -0
  86. package/dist/highlighter/themes/areThemesAttached.d.ts +3 -2
  87. package/dist/highlighter/themes/areThemesAttached.d.ts.map +1 -1
  88. package/dist/highlighter/themes/areThemesAttached.js +5 -4
  89. package/dist/highlighter/themes/areThemesAttached.js.map +1 -1
  90. package/dist/highlighter/themes/attachResolvedThemes.d.ts +5 -2
  91. package/dist/highlighter/themes/attachResolvedThemes.d.ts.map +1 -1
  92. package/dist/highlighter/themes/attachResolvedThemes.js +4 -16
  93. package/dist/highlighter/themes/attachResolvedThemes.js.map +1 -1
  94. package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts +3 -1
  95. package/dist/highlighter/themes/cleanUpResolvedThemes.d.ts.map +1 -1
  96. package/dist/highlighter/themes/cleanUpResolvedThemes.js +8 -5
  97. package/dist/highlighter/themes/cleanUpResolvedThemes.js.map +1 -1
  98. package/dist/highlighter/themes/createCSSVariablesTheme.d.ts +7 -0
  99. package/dist/highlighter/themes/createCSSVariablesTheme.d.ts.map +1 -0
  100. package/dist/highlighter/themes/createCSSVariablesTheme.js +89 -0
  101. package/dist/highlighter/themes/createCSSVariablesTheme.js.map +1 -0
  102. package/dist/highlighter/themes/createCachedLoader.d.ts +5 -0
  103. package/dist/highlighter/themes/createCachedLoader.d.ts.map +1 -0
  104. package/dist/highlighter/themes/createCachedLoader.js +15 -0
  105. package/dist/highlighter/themes/createCachedLoader.js.map +1 -0
  106. package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts +3 -2
  107. package/dist/highlighter/themes/getResolvedOrResolveTheme.d.ts.map +1 -1
  108. package/dist/highlighter/themes/getResolvedOrResolveTheme.js +4 -4
  109. package/dist/highlighter/themes/getResolvedOrResolveTheme.js.map +1 -1
  110. package/dist/highlighter/themes/getResolvedThemes.d.ts +3 -2
  111. package/dist/highlighter/themes/getResolvedThemes.d.ts.map +1 -1
  112. package/dist/highlighter/themes/getResolvedThemes.js +4 -3
  113. package/dist/highlighter/themes/getResolvedThemes.js.map +1 -1
  114. package/dist/highlighter/themes/hasResolvedThemes.d.ts +2 -2
  115. package/dist/highlighter/themes/hasResolvedThemes.d.ts.map +1 -1
  116. package/dist/highlighter/themes/hasResolvedThemes.js +4 -3
  117. package/dist/highlighter/themes/hasResolvedThemes.js.map +1 -1
  118. package/dist/highlighter/themes/registerCustomCSSVariableTheme.d.ts.map +1 -1
  119. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js +3 -3
  120. package/dist/highlighter/themes/registerCustomCSSVariableTheme.js.map +1 -1
  121. package/dist/highlighter/themes/registerCustomTheme.d.ts +9 -4
  122. package/dist/highlighter/themes/registerCustomTheme.d.ts.map +1 -1
  123. package/dist/highlighter/themes/registerCustomTheme.js +8 -16
  124. package/dist/highlighter/themes/registerCustomTheme.js.map +1 -1
  125. package/dist/highlighter/themes/resolveTheme.d.ts +3 -2
  126. package/dist/highlighter/themes/resolveTheme.d.ts.map +1 -1
  127. package/dist/highlighter/themes/resolveTheme.js +4 -7
  128. package/dist/highlighter/themes/resolveTheme.js.map +1 -1
  129. package/dist/highlighter/themes/resolveThemes.d.ts +3 -2
  130. package/dist/highlighter/themes/resolveThemes.d.ts.map +1 -1
  131. package/dist/highlighter/themes/resolveThemes.js +4 -7
  132. package/dist/highlighter/themes/resolveThemes.js.map +1 -1
  133. package/dist/highlighter/themes/themeResolver.d.ts +10 -4
  134. package/dist/highlighter/themes/themeResolver.d.ts.map +1 -1
  135. package/dist/highlighter/themes/themeResolver.js +141 -2
  136. package/dist/highlighter/themes/themeResolver.js.map +1 -1
  137. package/dist/highlighter/themes/types.d.ts +23 -0
  138. package/dist/highlighter/themes/types.d.ts.map +1 -0
  139. package/dist/highlighter/themes/types.js +0 -0
  140. package/dist/highlighter/tokenizer-types.d.ts +35 -0
  141. package/dist/highlighter/tokenizer-types.d.ts.map +1 -0
  142. package/dist/highlighter/tokenizer-types.js +0 -0
  143. package/dist/highlighter/types.d.ts +55 -0
  144. package/dist/highlighter/types.d.ts.map +1 -0
  145. package/dist/highlighter/types.js +0 -0
  146. package/dist/index.d.ts +14 -10
  147. package/dist/index.js +16 -18
  148. package/dist/managers/InteractionManager.d.ts.map +1 -1
  149. package/dist/managers/InteractionManager.js +2 -2
  150. package/dist/managers/InteractionManager.js.map +1 -1
  151. package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts +9 -1
  152. package/dist/node_modules/.pnpm/@types_hast@3.0.4/node_modules/@types/hast/index.d.ts.map +1 -1
  153. package/dist/react/CodeView.js +1 -1
  154. package/dist/react/index.d.ts +8 -3
  155. package/dist/renderers/DiffHunksRenderer.d.ts +2 -1
  156. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  157. package/dist/renderers/DiffHunksRenderer.js +31 -22
  158. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  159. package/dist/renderers/FileRenderer.d.ts +2 -1
  160. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  161. package/dist/renderers/FileRenderer.js +33 -24
  162. package/dist/renderers/FileRenderer.js.map +1 -1
  163. package/dist/shiki-stream/index.d.ts +3 -3
  164. package/dist/shiki-stream/index.js +1 -2
  165. package/dist/shiki-stream/stream.d.ts +4 -4
  166. package/dist/shiki-stream/stream.d.ts.map +1 -1
  167. package/dist/shiki-stream/stream.js +20 -9
  168. package/dist/shiki-stream/stream.js.map +1 -1
  169. package/dist/shiki-stream/types.d.ts +7 -38
  170. package/dist/shiki-stream/types.d.ts.map +1 -1
  171. package/dist/ssr/FileDiffReact.js +1 -1
  172. package/dist/ssr/index.d.ts +7 -2
  173. package/dist/ssr/renderHTML.js +2 -2
  174. package/dist/ssr/renderHTML.js.map +1 -1
  175. package/dist/style.js +1 -1
  176. package/dist/style.js.map +1 -1
  177. package/dist/types.d.ts +10 -11
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/utils/createSpanNodeFromToken.d.ts +3 -2
  180. package/dist/utils/createSpanNodeFromToken.d.ts.map +1 -1
  181. package/dist/utils/createSpanNodeFromToken.js +4 -5
  182. package/dist/utils/createSpanNodeFromToken.js.map +1 -1
  183. package/dist/utils/cssWrappers.d.ts.map +1 -1
  184. package/dist/utils/cssWrappers.js +12 -0
  185. package/dist/utils/cssWrappers.js.map +1 -1
  186. package/dist/utils/getHighlighterOptions.d.ts.map +1 -1
  187. package/dist/utils/getHighlighterOptions.js +3 -2
  188. package/dist/utils/getHighlighterOptions.js.map +1 -1
  189. package/dist/utils/getHighlighterThemeStyles.d.ts +2 -1
  190. package/dist/utils/getHighlighterThemeStyles.d.ts.map +1 -1
  191. package/dist/utils/getHighlighterThemeStyles.js +13 -3
  192. package/dist/utils/getHighlighterThemeStyles.js.map +1 -1
  193. package/dist/utils/getTokenOptions.d.ts +7 -0
  194. package/dist/utils/getTokenOptions.d.ts.map +1 -0
  195. package/dist/utils/getTokenOptions.js +16 -0
  196. package/dist/utils/getTokenOptions.js.map +1 -0
  197. package/dist/utils/hastToHtml.d.ts +10 -0
  198. package/dist/utils/hastToHtml.d.ts.map +1 -0
  199. package/dist/utils/hastToHtml.js +125 -0
  200. package/dist/utils/hastToHtml.js.map +1 -0
  201. package/dist/utils/parseDiffDecorations.d.ts +2 -1
  202. package/dist/utils/parseDiffDecorations.d.ts.map +1 -1
  203. package/dist/utils/renderDiffWithHighlighter.d.ts +3 -2
  204. package/dist/utils/renderDiffWithHighlighter.d.ts.map +1 -1
  205. package/dist/utils/renderDiffWithHighlighter.js +33 -48
  206. package/dist/utils/renderDiffWithHighlighter.js.map +1 -1
  207. package/dist/utils/renderFileWithHighlighter.d.ts +3 -2
  208. package/dist/utils/renderFileWithHighlighter.d.ts.map +1 -1
  209. package/dist/utils/renderFileWithHighlighter.js +10 -26
  210. package/dist/utils/renderFileWithHighlighter.js.map +1 -1
  211. package/dist/utils/renderTokenLines.d.ts +17 -0
  212. package/dist/utils/renderTokenLines.d.ts.map +1 -0
  213. package/dist/utils/renderTokenLines.js +246 -0
  214. package/dist/utils/renderTokenLines.js.map +1 -0
  215. package/dist/utils/resolvePreferredHighlighter.d.ts +13 -0
  216. package/dist/utils/resolvePreferredHighlighter.d.ts.map +1 -0
  217. package/dist/utils/resolvePreferredHighlighter.js +11 -0
  218. package/dist/utils/resolvePreferredHighlighter.js.map +1 -0
  219. package/dist/utils/setDeferredArrayItem.d.ts +5 -0
  220. package/dist/utils/setDeferredArrayItem.d.ts.map +1 -0
  221. package/dist/utils/setDeferredArrayItem.js +39 -0
  222. package/dist/utils/setDeferredArrayItem.js.map +1 -0
  223. package/dist/utils/tokenStyle.d.ts +7 -0
  224. package/dist/utils/tokenStyle.d.ts.map +1 -0
  225. package/dist/utils/tokenStyle.js +28 -0
  226. package/dist/utils/tokenStyle.js.map +1 -0
  227. package/dist/utils/tokensToHtml.d.ts +8 -0
  228. package/dist/utils/tokensToHtml.d.ts.map +1 -0
  229. package/dist/utils/tokensToHtml.js +45 -0
  230. package/dist/utils/tokensToHtml.js.map +1 -0
  231. package/dist/utils/wrapTokenFragments.js.map +1 -1
  232. package/dist/worker/WorkerPoolManager.d.ts +2 -2
  233. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  234. package/dist/worker/WorkerPoolManager.js +56 -46
  235. package/dist/worker/WorkerPoolManager.js.map +1 -1
  236. package/dist/worker/hastLinesTransport.d.ts +14 -0
  237. package/dist/worker/hastLinesTransport.d.ts.map +1 -0
  238. package/dist/worker/hastLinesTransport.js +156 -0
  239. package/dist/worker/hastLinesTransport.js.map +1 -0
  240. package/dist/worker/highlights-sAHlxqlf.js +317 -0
  241. package/dist/worker/highlights-sAHlxqlf.js.map +1 -0
  242. package/dist/worker/index.d.ts +1 -1
  243. package/dist/worker/shiki-Bx2JpdqZ.js +697 -0
  244. package/dist/worker/shiki-Bx2JpdqZ.js.map +1 -0
  245. package/dist/worker/stream-tokenizer-YZ6M1qSx.js +424 -0
  246. package/dist/worker/stream-tokenizer-YZ6M1qSx.js.map +1 -0
  247. package/dist/worker/types.d.ts +5 -3
  248. package/dist/worker/types.d.ts.map +1 -1
  249. package/dist/worker/worker-portable.js +41 -13337
  250. package/dist/worker/worker-portable.js.map +1 -1
  251. package/dist/worker/worker.js +672 -349
  252. package/dist/worker/worker.js.map +1 -1
  253. package/dist/worker/workerMessage.d.ts +24 -0
  254. package/dist/worker/workerMessage.d.ts.map +1 -0
  255. package/dist/worker/workerMessage.js +0 -0
  256. package/package.json +33 -29
  257. package/dist/highlighter/themes/constants.d.ts +0 -5
  258. package/dist/highlighter/themes/constants.d.ts.map +0 -1
  259. package/dist/highlighter/themes/constants.js +0 -6
  260. package/dist/highlighter/themes/constants.js.map +0 -1
  261. package/dist/highlighter/themes/themeResolution.d.ts +0 -7
  262. package/dist/highlighter/themes/themeResolution.d.ts.map +0 -1
  263. package/dist/highlighter/themes/themeResolution.js +0 -21
  264. package/dist/highlighter/themes/themeResolution.js.map +0 -1
  265. package/dist/shiki-stream/tokenizer.d.ts +0 -23
  266. package/dist/shiki-stream/tokenizer.d.ts.map +0 -1
  267. package/dist/shiki-stream/tokenizer.js +0 -72
  268. package/dist/shiki-stream/tokenizer.js.map +0 -1
  269. package/dist/utils/createTransformerWithState.d.ts +0 -12
  270. package/dist/utils/createTransformerWithState.d.ts.map +0 -1
  271. package/dist/utils/createTransformerWithState.js +0 -89
  272. package/dist/utils/createTransformerWithState.js.map +0 -1
  273. package/dist/worker/wasm-B9ZqxnKj.js +0 -8
  274. package/dist/worker/wasm-B9ZqxnKj.js.map +0 -1
@@ -0,0 +1,24 @@
1
+ import { DiffsEditorTokenizer } from "./DiffsEditorTokenizer.js";
2
+ import { DiffsEditorTokenizerOptions } from "./tokenizer-types.js";
3
+ import { CodeToTokensOptions as CodeToTokensOptions$1 } from "./types.js";
4
+ import { HighlightedToken, RenderRange } from "../types.js";
5
+ import { TextDocumentChange } from "../editor/textDocument.js";
6
+ import { CodeToTokensOptions } from "@pierre/highlights";
7
+ //#region src/highlighter/highlights-editor.d.ts
8
+ declare class HighlightsEditorTokenizer implements DiffsEditorTokenizer {
9
+ #private;
10
+ private readonly options;
11
+ private readonly resolveOptions;
12
+ constructor(options: DiffsEditorTokenizerOptions, resolveOptions: (options: CodeToTokensOptions$1) => CodeToTokensOptions);
13
+ tokenize(change: TextDocumentChange, renderRange?: RenderRange, hostRealignsRows?: boolean): Map<number, HighlightedToken[]>;
14
+ setTheme(themeName: string): void;
15
+ getStringCommentRegexpRangesInLine(lineIndex: number): [number, number][] | null;
16
+ prebuildStateStack(): void;
17
+ stopBackgroundTokenize(): void;
18
+ pauseBackgroundTokenize(): void;
19
+ resumeBackgroundTokenize(): void;
20
+ dispose(): void;
21
+ }
22
+ //#endregion
23
+ export { HighlightsEditorTokenizer };
24
+ //# sourceMappingURL=highlights-editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlights-editor.d.ts","names":[],"sources":["../../src/highlighter/highlights-editor.ts"],"mappings":";;;;;;;cAaa,qCAAqC;;mBAa7B;mBACA;EAFnB,YACmB,SAAS,6BACT,iBACf,SAAS,0BACN;EAqDP,SACE,QAAQ,oBACR,cAAc,aACd,6BACC,YAAY;EAiGf,SAAS;EAUT,mCACE;EAoCF;EACA;EAGA;EAIA;EAIA"}
@@ -0,0 +1,166 @@
1
+ import { formatCSSVariablePrefix } from "../utils/formatCSSVariablePrefix.js";
2
+ import { LiveTokenizer } from "@pierre/highlights";
3
+ //#region src/highlighter/highlights-editor.ts
4
+ var HighlightsEditorTokenizer = class {
5
+ options;
6
+ resolveOptions;
7
+ #tokenizer;
8
+ #version;
9
+ #disposed = false;
10
+ #returnedRange;
11
+ #paused = false;
12
+ #capturedLines;
13
+ #pendingDelivery;
14
+ constructor(options, resolveOptions) {
15
+ this.options = options;
16
+ this.resolveOptions = resolveOptions;
17
+ this.#version = options.textDocument.version;
18
+ this.#tokenizer = this.#createTokenizer();
19
+ }
20
+ #createTokenizer() {
21
+ return new LiveTokenizer({
22
+ ...this.resolveOptions({
23
+ lang: this.options.textDocument.languageId,
24
+ theme: this.options.theme,
25
+ cssVariablePrefix: formatCSSVariablePrefix("token"),
26
+ tokenizeMaxLineLength: this.options.tokenizeMaxLineLength ?? 1e3
27
+ }),
28
+ code: this.options.textDocument.getText(),
29
+ renderRange: [0, 0],
30
+ onDeferTokenize: (lines) => this.#deliver(lines)
31
+ });
32
+ }
33
+ #deliver(lines) {
34
+ const captured = this.#capturedLines;
35
+ if (captured != null) {
36
+ for (const [line, tokens] of lines) captured.set(line, tokens);
37
+ return;
38
+ }
39
+ const range = this.#returnedRange;
40
+ if (range != null) {
41
+ for (const line of lines.keys()) if (line >= range[0] && line < range[1]) lines.delete(line);
42
+ if (lines.size === 0) return;
43
+ }
44
+ this.options.onDeferTokenize(lines);
45
+ }
46
+ #queueDelivery(lines) {
47
+ const pending = this.#pendingDelivery;
48
+ if (pending != null) {
49
+ for (const [line, tokens] of lines) pending.set(line, tokens);
50
+ return;
51
+ }
52
+ this.#pendingDelivery = lines;
53
+ queueMicrotask(() => {
54
+ const batch = this.#pendingDelivery;
55
+ this.#pendingDelivery = void 0;
56
+ if (batch != null && batch.size > 0 && !this.#disposed) this.options.onDeferTokenize(batch);
57
+ });
58
+ }
59
+ tokenize(change, renderRange, hostRealignsRows = false) {
60
+ const document = this.options.textDocument;
61
+ const start = Math.min(renderRange?.startingLine ?? 0, document.lineCount);
62
+ const end = Math.min(start + (renderRange?.totalLines ?? Infinity), document.lineCount);
63
+ const returnedStart = Math.max(start, change.startLine);
64
+ this.#paused = false;
65
+ let lines;
66
+ if (this.#version !== document.version) {
67
+ this.#pendingDelivery = void 0;
68
+ lines = this.#syncDocument(change, [start, end]).lines;
69
+ this.#version = document.version;
70
+ } else if (this.#tokenizer.lineCount !== document.lineCount) {
71
+ this.#pendingDelivery = void 0;
72
+ lines = this.#tokenizer.reset(document.getText(), { renderRange: [start, end] }).lines;
73
+ } else {
74
+ lines = /* @__PURE__ */ new Map();
75
+ this.#readLines(lines, returnedStart, end);
76
+ if (this.#pendingDelivery != null) for (const line of lines.keys()) this.#pendingDelivery.delete(line);
77
+ return lines;
78
+ }
79
+ if (change.lineDelta === 0 ? change.changedLineChanges?.some(([, , lineDelta]) => lineDelta !== 0) ?? false : !hostRealignsRows) this.#readLines(lines, returnedStart, end);
80
+ return lines;
81
+ }
82
+ #syncDocument(change, renderRange) {
83
+ const document = this.options.textDocument;
84
+ const options = { renderRange };
85
+ if (Math.abs(document.version - this.#version) === 1 && change.changes.length > 0 && this.#tokenizer.lineCount === change.previousLineCount) try {
86
+ const update = this.#tokenizer.applyEdits(change.changes.map(({ range, text }) => ({
87
+ range,
88
+ newText: text
89
+ })), options);
90
+ if (this.#tokenizer.lineCount === document.lineCount) return update;
91
+ } catch (error) {
92
+ if (!(error instanceof RangeError)) throw error;
93
+ }
94
+ return this.#tokenizer.reset(document.getText(), options);
95
+ }
96
+ #readLines(lines, from, to) {
97
+ this.#returnedRange = [from, to];
98
+ try {
99
+ this.#tokenizer.flush(to);
100
+ } finally {
101
+ this.#returnedRange = void 0;
102
+ }
103
+ for (let line = from; line < to; line++) {
104
+ if (lines.has(line)) continue;
105
+ const { tokens } = this.#tokenizer.getLineTokens(line);
106
+ lines.set(line, tokens.length === 0 ? [[
107
+ 0,
108
+ "",
109
+ ""
110
+ ]] : tokens.map((token) => [
111
+ token.offset,
112
+ token.color ?? "",
113
+ token.content
114
+ ]));
115
+ }
116
+ }
117
+ setTheme(themeName) {
118
+ if (themeName === this.options.theme) return;
119
+ this.options.theme = themeName;
120
+ this.#tokenizer.dispose();
121
+ this.#pendingDelivery = void 0;
122
+ this.#paused = false;
123
+ this.#version = this.options.textDocument.version;
124
+ this.#tokenizer = this.#createTokenizer();
125
+ }
126
+ getStringCommentRegexpRangesInLine(lineIndex) {
127
+ const document = this.options.textDocument;
128
+ if (this.options.matchBrackets === false || lineIndex < 0 || lineIndex >= document.lineCount) return null;
129
+ const captured = /* @__PURE__ */ new Map();
130
+ this.#capturedLines = captured;
131
+ try {
132
+ if (this.#version !== document.version || this.#tokenizer.lineCount !== document.lineCount) {
133
+ this.#pendingDelivery = void 0;
134
+ this.#tokenizer.reset(document.getText(), { renderRange: [lineIndex, lineIndex + 1] });
135
+ this.#version = document.version;
136
+ }
137
+ this.#tokenizer.flush(lineIndex + 1);
138
+ } finally {
139
+ this.#capturedLines = void 0;
140
+ if (this.#paused) this.#tokenizer.pause();
141
+ }
142
+ if (captured.size > 0) this.#queueDelivery(captured);
143
+ return this.#tokenizer.getLineTokens(lineIndex).bracketIgnoredRanges;
144
+ }
145
+ prebuildStateStack() {}
146
+ stopBackgroundTokenize() {
147
+ this.pauseBackgroundTokenize();
148
+ }
149
+ pauseBackgroundTokenize() {
150
+ this.#paused = true;
151
+ this.#tokenizer.pause();
152
+ }
153
+ resumeBackgroundTokenize() {
154
+ this.#paused = false;
155
+ this.#tokenizer.resume();
156
+ }
157
+ dispose() {
158
+ this.#disposed = true;
159
+ this.#pendingDelivery = void 0;
160
+ this.#tokenizer.dispose();
161
+ }
162
+ };
163
+ //#endregion
164
+ export { HighlightsEditorTokenizer };
165
+
166
+ //# sourceMappingURL=highlights-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlights-editor.js","names":[],"sources":["../../src/highlighter/highlights-editor.ts"],"sourcesContent":["import {\n type CodeToTokensOptions as HighlightsOptions,\n LiveTokenizer,\n type LiveTokenizerUpdate,\n} from '@pierre/highlights';\n\nimport type { TextDocumentChange } from '../editor/textDocument';\nimport type { HighlightedToken, RenderRange } from '../types';\nimport { formatCSSVariablePrefix } from '../utils/formatCSSVariablePrefix';\nimport type { DiffsEditorTokenizer } from './DiffsEditorTokenizer';\nimport type { DiffsEditorTokenizerOptions } from './tokenizer-types';\nimport type { CodeToTokensOptions } from './types';\n\nexport class HighlightsEditorTokenizer implements DiffsEditorTokenizer {\n #tokenizer: LiveTokenizer;\n #version: number;\n #disposed = false;\n // Delivering these lines through onDeferTokenize would patch them twice.\n #returnedRange: readonly [start: number, end: number] | undefined;\n // Flush, edit and reset resume the lexer; reads must restore this pause.\n #paused = false;\n // Defer callbacks during bracket matching to avoid re-entering the renderer.\n #capturedLines: Map<number, HighlightedToken[]> | undefined;\n #pendingDelivery: Map<number, HighlightedToken[]> | undefined;\n\n constructor(\n private readonly options: DiffsEditorTokenizerOptions,\n private readonly resolveOptions: (\n options: CodeToTokensOptions\n ) => HighlightsOptions\n ) {\n this.#version = options.textDocument.version;\n this.#tokenizer = this.#createTokenizer();\n }\n\n #createTokenizer(): LiveTokenizer {\n return new LiveTokenizer({\n ...this.resolveOptions({\n lang: this.options.textDocument.languageId,\n theme: this.options.theme,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n tokenizeMaxLineLength: this.options.tokenizeMaxLineLength ?? 1000,\n }),\n code: this.options.textDocument.getText(),\n renderRange: [0, 0],\n onDeferTokenize: (lines) => this.#deliver(lines),\n });\n }\n\n #deliver(lines: Map<number, HighlightedToken[]>): void {\n const captured = this.#capturedLines;\n if (captured != null) {\n for (const [line, tokens] of lines) captured.set(line, tokens);\n return;\n }\n const range = this.#returnedRange;\n if (range != null) {\n for (const line of lines.keys()) {\n if (line >= range[0] && line < range[1]) lines.delete(line);\n }\n if (lines.size === 0) return;\n }\n this.options.onDeferTokenize(lines);\n }\n\n // Wait until bracket matching returns before patching rows. Edits, resets\n // and theme changes discard the batch because its tokens may be stale.\n #queueDelivery(lines: Map<number, HighlightedToken[]>): void {\n const pending = this.#pendingDelivery;\n if (pending != null) {\n for (const [line, tokens] of lines) pending.set(line, tokens);\n return;\n }\n this.#pendingDelivery = lines;\n queueMicrotask(() => {\n const batch = this.#pendingDelivery;\n this.#pendingDelivery = undefined;\n if (batch != null && batch.size > 0 && !this.#disposed)\n this.options.onDeferTokenize(batch);\n });\n }\n\n tokenize(\n change: TextDocumentChange,\n renderRange?: RenderRange,\n hostRealignsRows = false\n ): Map<number, HighlightedToken[]> {\n const document = this.options.textDocument;\n const start = Math.min(renderRange?.startingLine ?? 0, document.lineCount);\n const end = Math.min(\n start + (renderRange?.totalLines ?? Infinity),\n document.lineCount\n );\n const returnedStart = Math.max(start, change.startLine);\n // Edits, resets and flushes all resume the native background work.\n this.#paused = false;\n let lines: Map<number, HighlightedToken[]>;\n if (this.#version !== document.version) {\n this.#pendingDelivery = undefined;\n lines = this.#syncDocument(change, [start, end]).lines;\n this.#version = document.version;\n } else if (this.#tokenizer.lineCount !== document.lineCount) {\n this.#pendingDelivery = undefined;\n lines = this.#tokenizer.reset(document.getText(), {\n renderRange: [start, end],\n }).lines;\n } else {\n lines = new Map();\n this.#readLines(lines, returnedStart, end);\n if (this.#pendingDelivery != null) {\n for (const line of lines.keys()) this.#pendingDelivery.delete(line);\n }\n return lines;\n }\n // Balanced insert/delete batches shift rows without triggering host realignment.\n // Other structural edits need the suffix only when the host does not move rows.\n if (\n change.lineDelta === 0\n ? (change.changedLineChanges?.some(\n ([, , lineDelta]) => lineDelta !== 0\n ) ?? false)\n : !hostRealignsRows\n ) {\n this.#readLines(lines, returnedStart, end);\n }\n return lines;\n }\n\n // Reload the lexer document if edits were skipped or combined; applying\n // them to stale text can produce incorrect tokens or out-of-range reads.\n #syncDocument(\n change: TextDocumentChange,\n renderRange: readonly [start: number, end: number]\n ): LiveTokenizerUpdate {\n const document = this.options.textDocument;\n const options = { renderRange };\n if (\n Math.abs(document.version - this.#version) === 1 &&\n change.changes.length > 0 &&\n this.#tokenizer.lineCount === change.previousLineCount\n ) {\n try {\n const update = this.#tokenizer.applyEdits(\n change.changes.map(({ range, text }) => ({ range, newText: text })),\n options\n );\n if (this.#tokenizer.lineCount === document.lineCount) return update;\n } catch (error) {\n // Out-of-range edits require a reload; other errors must propagate.\n if (!(error instanceof RangeError)) throw error;\n }\n }\n return this.#tokenizer.reset(document.getText(), options);\n }\n\n // Flushing may complete lines outside [from, to); deliver those by callback.\n #readLines(\n lines: Map<number, HighlightedToken[]>,\n from: number,\n to: number\n ): void {\n this.#returnedRange = [from, to];\n try {\n this.#tokenizer.flush(to);\n } finally {\n this.#returnedRange = undefined;\n }\n for (let line = from; line < to; line++) {\n if (lines.has(line)) continue;\n const { tokens } = this.#tokenizer.getLineTokens(line);\n lines.set(\n line,\n tokens.length === 0\n ? [[0, '', '']]\n : tokens.map((token) => [\n token.offset,\n token.color ?? '',\n token.content,\n ])\n );\n }\n }\n\n setTheme(themeName: string): void {\n if (themeName === this.options.theme) return;\n this.options.theme = themeName;\n this.#tokenizer.dispose();\n this.#pendingDelivery = undefined;\n this.#paused = false;\n this.#version = this.options.textDocument.version;\n this.#tokenizer = this.#createTokenizer();\n }\n\n getStringCommentRegexpRangesInLine(\n lineIndex: number\n ): [number, number][] | null {\n const document = this.options.textDocument;\n if (\n this.options.matchBrackets === false ||\n lineIndex < 0 ||\n lineIndex >= document.lineCount\n )\n return null;\n // Reset and flush resume background work and invoke callbacks immediately.\n // Defer those callbacks and restore any pause before returning.\n const captured = new Map<number, HighlightedToken[]>();\n this.#capturedLines = captured;\n try {\n // Bracket matching can precede rendering. Record the reloaded version\n // so the next render does not apply the same edits again.\n if (\n this.#version !== document.version ||\n this.#tokenizer.lineCount !== document.lineCount\n ) {\n this.#pendingDelivery = undefined;\n this.#tokenizer.reset(document.getText(), {\n renderRange: [lineIndex, lineIndex + 1],\n });\n this.#version = document.version;\n }\n this.#tokenizer.flush(lineIndex + 1);\n } finally {\n this.#capturedLines = undefined;\n if (this.#paused) this.#tokenizer.pause();\n }\n if (captured.size > 0) this.#queueDelivery(captured);\n return this.#tokenizer.getLineTokens(lineIndex).bracketIgnoredRanges;\n }\n\n // Rendering calls this while background tokenization may be paused; do not resume it.\n prebuildStateStack(): void {}\n stopBackgroundTokenize(): void {\n this.pauseBackgroundTokenize();\n }\n pauseBackgroundTokenize(): void {\n this.#paused = true;\n this.#tokenizer.pause();\n }\n resumeBackgroundTokenize(): void {\n this.#paused = false;\n this.#tokenizer.resume();\n }\n dispose(): void {\n this.#disposed = true;\n this.#pendingDelivery = undefined;\n this.#tokenizer.dispose();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { ThemedToken } from "./types.js";
2
+ import { BaseStreamTokenizer } from "./stream-tokenizer.js";
3
+ import { CodeToTokensOptions } from "@pierre/highlights";
4
+ //#region src/highlighter/highlights-stream.d.ts
5
+ /** Keeps the unfinished line editable so new chunks can recall provisional tokens. */
6
+ declare class HighlightsStreamTokenizer extends BaseStreamTokenizer {
7
+ #private;
8
+ private readonly options;
9
+ constructor(options: CodeToTokensOptions);
10
+ protected tokenizeChunk(chunk: string, stable: ThemedToken[]): {
11
+ unstable: ThemedToken[];
12
+ tailLength: number;
13
+ };
14
+ clone(): HighlightsStreamTokenizer;
15
+ protected resetSource(): void;
16
+ protected releaseSource(): void;
17
+ }
18
+ //#endregion
19
+ export { HighlightsStreamTokenizer };
20
+ //# sourceMappingURL=highlights-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlights-stream.d.ts","names":[],"sources":["../../src/highlighter/highlights-stream.ts"],"mappings":";;;;;cAWa,kCAAkC;;mBAIhB;EAA7B,YAA6B,SAAS;YAK5B,cACR,eACA,QAAQ;IACL,UAAU;IAAe;;EA0D9B,SAAS;YAQC;YAKA"}
@@ -0,0 +1,93 @@
1
+ import { appendItems } from "../utils/appendItems.js";
2
+ import { BaseStreamTokenizer } from "./stream-tokenizer.js";
3
+ import { LiveTokenizer } from "@pierre/highlights";
4
+ //#region src/highlighter/highlights-stream.ts
5
+ const TRIM_LINE_COUNT = 1024;
6
+ const DOCUMENT_START = {
7
+ line: 0,
8
+ character: 0
9
+ };
10
+ /** Keeps the unfinished line editable so new chunks can recall provisional tokens. */
11
+ var HighlightsStreamTokenizer = class HighlightsStreamTokenizer extends BaseStreamTokenizer {
12
+ options;
13
+ #tokenizer;
14
+ #trimLineCount = TRIM_LINE_COUNT;
15
+ constructor(options) {
16
+ super();
17
+ this.options = options;
18
+ this.#tokenizer = new LiveTokenizer(options);
19
+ }
20
+ tokenizeChunk(chunk, stable) {
21
+ const lineBreaks = [...chunk.matchAll(/\r\n|\r|\n/g)];
22
+ const startLine = this.#tokenizer.lineCount - 1;
23
+ const position = {
24
+ line: startLine,
25
+ character: this.#tokenizer.getLineLength(startLine)
26
+ };
27
+ this.#tokenizer.applyEdits([{
28
+ range: {
29
+ start: position,
30
+ end: position
31
+ },
32
+ newText: chunk
33
+ }]);
34
+ const lastLine = this.#tokenizer.lineCount - 1;
35
+ let unstable = [];
36
+ for (let line = startLine; line <= lastLine; line++) {
37
+ const { tokens } = this.#tokenizer.getLineTokens(line);
38
+ for (const token of tokens) token.offset += this.stableOffset;
39
+ if (line < lastLine) {
40
+ appendItems(stable, tokens);
41
+ this.pushLineBreak(stable, this.#tokenizer.getLineLength(line), lineBreaks[line - startLine][0]);
42
+ } else unstable = tokens;
43
+ }
44
+ const tailLength = this.#tokenizer.getLineLength(lastLine);
45
+ if (lastLine > this.#trimLineCount) {
46
+ const text = this.#tokenizer.getText();
47
+ const { lineChanges } = this.#tokenizer.applyEdits([{
48
+ range: {
49
+ start: DOCUMENT_START,
50
+ end: {
51
+ line: lastLine - 1,
52
+ character: 0
53
+ }
54
+ },
55
+ newText: ""
56
+ }]);
57
+ if (lineChanges.every((change) => change.newEndLine <= 1)) this.#trimLineCount = TRIM_LINE_COUNT;
58
+ else {
59
+ const keptLength = this.#tokenizer.getText().length;
60
+ this.#tokenizer.applyEdits([{
61
+ range: {
62
+ start: DOCUMENT_START,
63
+ end: DOCUMENT_START
64
+ },
65
+ newText: text.slice(0, text.length - keptLength)
66
+ }]);
67
+ this.#trimLineCount = lastLine * 2;
68
+ }
69
+ }
70
+ return {
71
+ unstable,
72
+ tailLength
73
+ };
74
+ }
75
+ clone() {
76
+ this.assertActive();
77
+ const clone = new HighlightsStreamTokenizer(this.options);
78
+ clone.#tokenizer.reset(this.#tokenizer.getText());
79
+ this.copyStateTo(clone);
80
+ return clone;
81
+ }
82
+ resetSource() {
83
+ this.#tokenizer.reset("");
84
+ this.#trimLineCount = TRIM_LINE_COUNT;
85
+ }
86
+ releaseSource() {
87
+ this.#tokenizer.dispose();
88
+ }
89
+ };
90
+ //#endregion
91
+ export { HighlightsStreamTokenizer };
92
+
93
+ //# sourceMappingURL=highlights-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"highlights-stream.js","names":[],"sources":["../../src/highlighter/highlights-stream.ts"],"sourcesContent":["import { type CodeToTokensOptions, LiveTokenizer } from '@pierre/highlights';\n\nimport { appendItems } from '../utils/appendItems';\nimport { BaseStreamTokenizer } from './stream-tokenizer';\nimport type { ThemedToken } from './types';\n\n// Completed lines the tokenizer keeps before it tries to drop older ones.\nconst TRIM_LINE_COUNT = 1024;\nconst DOCUMENT_START = { line: 0, character: 0 };\n\n/** Keeps the unfinished line editable so new chunks can recall provisional tokens. */\nexport class HighlightsStreamTokenizer extends BaseStreamTokenizer {\n #tokenizer: LiveTokenizer;\n #trimLineCount = TRIM_LINE_COUNT;\n\n constructor(private readonly options: CodeToTokensOptions) {\n super();\n this.#tokenizer = new LiveTokenizer(options);\n }\n\n protected tokenizeChunk(\n chunk: string,\n stable: ThemedToken[]\n ): { unstable: ThemedToken[]; tailLength: number } {\n const lineBreaks = [...chunk.matchAll(/\\r\\n|\\r|\\n/g)];\n const startLine = this.#tokenizer.lineCount - 1;\n const position = {\n line: startLine,\n character: this.#tokenizer.getLineLength(startLine),\n };\n this.#tokenizer.applyEdits([\n { range: { start: position, end: position }, newText: chunk },\n ]);\n const lastLine = this.#tokenizer.lineCount - 1;\n let unstable: ThemedToken[] = [];\n for (let line = startLine; line <= lastLine; line++) {\n const { tokens } = this.#tokenizer.getLineTokens(line);\n for (const token of tokens) token.offset += this.stableOffset;\n if (line < lastLine) {\n appendItems(stable, tokens);\n this.pushLineBreak(\n stable,\n this.#tokenizer.getLineLength(line),\n lineBreaks[line - startLine][0]\n );\n } else {\n unstable = tokens;\n }\n }\n const tailLength = this.#tokenizer.getLineLength(lastLine);\n if (lastLine > this.#trimLineCount) {\n // Warning: keep the last completed line. Lexed from the initial state,\n // it must end in its old state, or the unfinished line would be lexed\n // from the wrong state; then restore the dropped lines.\n const text = this.#tokenizer.getText();\n const { lineChanges } = this.#tokenizer.applyEdits([\n {\n range: {\n start: DOCUMENT_START,\n end: { line: lastLine - 1, character: 0 },\n },\n newText: '',\n },\n ]);\n if (lineChanges.every((change) => change.newEndLine <= 1)) {\n this.#trimLineCount = TRIM_LINE_COUNT;\n } else {\n const keptLength = this.#tokenizer.getText().length;\n this.#tokenizer.applyEdits([\n {\n range: { start: DOCUMENT_START, end: DOCUMENT_START },\n newText: text.slice(0, text.length - keptLength),\n },\n ]);\n // Retry after the window doubles, such as inside a long comment.\n this.#trimLineCount = lastLine * 2;\n }\n }\n return { unstable, tailLength };\n }\n\n clone(): HighlightsStreamTokenizer {\n this.assertActive();\n const clone = new HighlightsStreamTokenizer(this.options);\n clone.#tokenizer.reset(this.#tokenizer.getText());\n this.copyStateTo(clone);\n return clone;\n }\n\n protected resetSource(): void {\n this.#tokenizer.reset('');\n this.#trimLineCount = TRIM_LINE_COUNT;\n }\n\n protected releaseSource(): void {\n this.#tokenizer.dispose();\n }\n}\n"],"mappings":";;;;AAOA,MAAM,kBAAkB;AACxB,MAAM,iBAAiB;CAAE,MAAM;CAAG,WAAW;AAAE;;AAG/C,IAAa,4BAAb,MAAa,kCAAkC,oBAAoB;CAIpC;CAH7B;CACA,iBAAiB;CAEjB,YAAY,SAA+C;EACzD,MAAM;EADqB,KAAA,UAAA;EAE3B,KAAK,aAAa,IAAI,cAAc,OAAO;CAC7C;CAEA,cACE,OACA,QACiD;EACjD,MAAM,aAAa,CAAC,GAAG,MAAM,SAAS,aAAa,CAAC;EACpD,MAAM,YAAY,KAAK,WAAW,YAAY;EAC9C,MAAM,WAAW;GACf,MAAM;GACN,WAAW,KAAK,WAAW,cAAc,SAAS;EACpD;EACA,KAAK,WAAW,WAAW,CACzB;GAAE,OAAO;IAAE,OAAO;IAAU,KAAK;GAAS;GAAG,SAAS;EAAM,CAC9D,CAAC;EACD,MAAM,WAAW,KAAK,WAAW,YAAY;EAC7C,IAAI,WAA0B,CAAC;EAC/B,KAAK,IAAI,OAAO,WAAW,QAAQ,UAAU,QAAQ;GACnD,MAAM,EAAE,WAAW,KAAK,WAAW,cAAc,IAAI;GACrD,KAAK,MAAM,SAAS,QAAQ,MAAM,UAAU,KAAK;GACjD,IAAI,OAAO,UAAU;IACnB,YAAY,QAAQ,MAAM;IAC1B,KAAK,cACH,QACA,KAAK,WAAW,cAAc,IAAI,GAClC,WAAW,OAAO,UAAU,CAAC,EAC/B;GACF,OACE,WAAW;EAEf;EACA,MAAM,aAAa,KAAK,WAAW,cAAc,QAAQ;EACzD,IAAI,WAAW,KAAK,gBAAgB;GAIlC,MAAM,OAAO,KAAK,WAAW,QAAQ;GACrC,MAAM,EAAE,gBAAgB,KAAK,WAAW,WAAW,CACjD;IACE,OAAO;KACL,OAAO;KACP,KAAK;MAAE,MAAM,WAAW;MAAG,WAAW;KAAE;IAC1C;IACA,SAAS;GACX,CACF,CAAC;GACD,IAAI,YAAY,OAAO,WAAW,OAAO,cAAc,CAAC,GACtD,KAAK,iBAAiB;QACjB;IACL,MAAM,aAAa,KAAK,WAAW,QAAQ,CAAC,CAAC;IAC7C,KAAK,WAAW,WAAW,CACzB;KACE,OAAO;MAAE,OAAO;MAAgB,KAAK;KAAe;KACpD,SAAS,KAAK,MAAM,GAAG,KAAK,SAAS,UAAU;IACjD,CACF,CAAC;IAED,KAAK,iBAAiB,WAAW;GACnC;EACF;EACA,OAAO;GAAE;GAAU;EAAW;CAChC;CAEA,QAAmC;EACjC,KAAK,aAAa;EAClB,MAAM,QAAQ,IAAI,0BAA0B,KAAK,OAAO;EACxD,MAAM,WAAW,MAAM,KAAK,WAAW,QAAQ,CAAC;EAChD,KAAK,YAAY,KAAK;EACtB,OAAO;CACT;CAEA,cAA8B;EAC5B,KAAK,WAAW,MAAM,EAAE;EACxB,KAAK,iBAAiB;CACxB;CAEA,gBAAgC;EAC9B,KAAK,WAAW,QAAQ;CAC1B;AACF"}
@@ -1,6 +1,7 @@
1
+ import { DiffsHighlighter } from "../DiffsHighlighter.js";
1
2
  import { SupportedLanguages } from "../../types.js";
2
3
  //#region src/highlighter/languages/areLanguagesAttached.d.ts
3
- declare function areLanguagesAttached(languages: SupportedLanguages | SupportedLanguages[]): boolean;
4
+ declare function areLanguagesAttached(languages: SupportedLanguages | SupportedLanguages[], highlighter?: DiffsHighlighter): boolean;
4
5
  //#endregion
5
6
  export { areLanguagesAttached };
6
7
  //# sourceMappingURL=areLanguagesAttached.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"areLanguagesAttached.d.ts","names":[],"sources":["../../../src/highlighter/languages/areLanguagesAttached.ts"],"mappings":";;iBAGgB,qBACd,WAAW,qBAAqB"}
1
+ {"version":3,"file":"areLanguagesAttached.d.ts","names":[],"sources":["../../../src/highlighter/languages/areLanguagesAttached.ts"],"mappings":";;;iBAGgB,qBACd,WAAW,qBAAqB,sBAChC,cAAc"}
@@ -1,11 +1,9 @@
1
1
  import { AttachedLanguages } from "./constants.js";
2
2
  //#region src/highlighter/languages/areLanguagesAttached.ts
3
- function areLanguagesAttached(languages) {
4
- for (const language of Array.isArray(languages) ? languages : [languages]) {
5
- if (language === "text" || language === "ansi") continue;
6
- if (!AttachedLanguages.has(language)) return false;
7
- }
8
- return true;
3
+ function areLanguagesAttached(languages, highlighter) {
4
+ const names = Array.isArray(languages) ? languages : [languages];
5
+ if (highlighter != null) return highlighter.hasLoadedLanguages(names);
6
+ return names.every((name) => name === "text" || name === "ansi" || AttachedLanguages.has(name));
9
7
  }
10
8
  //#endregion
11
9
  export { areLanguagesAttached };
@@ -1 +1 @@
1
- {"version":3,"file":"areLanguagesAttached.js","names":[],"sources":["../../../src/highlighter/languages/areLanguagesAttached.ts"],"sourcesContent":["import type { SupportedLanguages } from '../../types';\nimport { AttachedLanguages } from './constants';\n\nexport function areLanguagesAttached(\n languages: SupportedLanguages | SupportedLanguages[]\n): boolean {\n for (const language of Array.isArray(languages) ? languages : [languages]) {\n if (language === 'text' || language === 'ansi') {\n continue;\n }\n if (!AttachedLanguages.has(language)) {\n return false;\n }\n }\n return true;\n}\n"],"mappings":";;AAGA,SAAgB,qBACd,WACS;CACT,KAAK,MAAM,YAAY,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS,GAAG;EACzE,IAAI,aAAa,UAAU,aAAa,QACtC;EAEF,IAAI,CAAC,kBAAkB,IAAI,QAAQ,GACjC,OAAO;CAEX;CACA,OAAO;AACT"}
1
+ {"version":3,"file":"areLanguagesAttached.js","names":[],"sources":["../../../src/highlighter/languages/areLanguagesAttached.ts"],"sourcesContent":["import type { DiffsHighlighter, SupportedLanguages } from '../../types';\nimport { AttachedLanguages } from './constants';\n\nexport function areLanguagesAttached(\n languages: SupportedLanguages | SupportedLanguages[],\n highlighter?: DiffsHighlighter\n): boolean {\n const names = Array.isArray(languages) ? languages : [languages];\n if (highlighter != null) {\n return highlighter.hasLoadedLanguages(names);\n }\n return names.every(\n (name) => name === 'text' || name === 'ansi' || AttachedLanguages.has(name)\n );\n}\n"],"mappings":";;AAGA,SAAgB,qBACd,WACA,aACS;CACT,MAAM,QAAQ,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS;CAC/D,IAAI,eAAe,MACjB,OAAO,YAAY,mBAAmB,KAAK;CAE7C,OAAO,MAAM,OACV,SAAS,SAAS,UAAU,SAAS,UAAU,kBAAkB,IAAI,IAAI,CAC5E;AACF"}
@@ -1,7 +1,12 @@
1
- import { DiffsHighlighter } from "../../types.js";
2
1
  import { ResolvedLanguage } from "../../worker/types.js";
2
+ import { DiffsHighlighter } from "../DiffsHighlighter.js";
3
+ import "../../types.js";
3
4
  import "../../worker/index.js";
4
5
  //#region src/highlighter/languages/attachResolvedLanguages.d.ts
6
+ /**
7
+ * Record resolved grammars in the shared language cache and attach them to a
8
+ * highlighter. Highlights bundles its lexers and ignores the grammars.
9
+ */
5
10
  declare function attachResolvedLanguages(resolvedLanguages: ResolvedLanguage | ResolvedLanguage[], highlighter: DiffsHighlighter): void;
6
11
  //#endregion
7
12
  export { attachResolvedLanguages };
@@ -1 +1 @@
1
- {"version":3,"file":"attachResolvedLanguages.d.ts","names":[],"sources":["../../../src/highlighter/languages/attachResolvedLanguages.ts"],"mappings":";;;;iBAIgB,wBACd,mBAAmB,mBAAmB,oBACtC,aAAa"}
1
+ {"version":3,"file":"attachResolvedLanguages.d.ts","names":[],"sources":["../../../src/highlighter/languages/attachResolvedLanguages.ts"],"mappings":";;;;;;;;;iBAQgB,wBACd,mBAAmB,mBAAmB,oBACtC,aAAa"}
@@ -1,22 +1,17 @@
1
1
  import { AttachedLanguages, ResolvedLanguages } from "./constants.js";
2
2
  //#region src/highlighter/languages/attachResolvedLanguages.ts
3
+ /**
4
+ * Record resolved grammars in the shared language cache and attach them to a
5
+ * highlighter. Highlights bundles its lexers and ignores the grammars.
6
+ */
3
7
  function attachResolvedLanguages(resolvedLanguages, highlighter) {
4
- resolvedLanguages = Array.isArray(resolvedLanguages) ? resolvedLanguages : [resolvedLanguages];
5
- for (const resolvedLang of resolvedLanguages) {
6
- if (AttachedLanguages.has(resolvedLang.name)) continue;
8
+ for (const resolvedLang of Array.isArray(resolvedLanguages) ? resolvedLanguages : [resolvedLanguages]) {
7
9
  let lang = ResolvedLanguages.get(resolvedLang.name);
8
10
  if (lang == null) {
9
11
  lang = resolvedLang;
10
12
  ResolvedLanguages.set(resolvedLang.name, lang);
11
13
  }
12
- const grammar = lang.data.find((grammar) => grammar.name === lang.name || grammar.aliases?.includes(lang.name) === true);
13
- if (grammar == null) throw new Error(`attachResolvedLanguages: No returned grammar declares "${lang.name}" as its name or an alias.`);
14
- highlighter.loadLanguageSync(lang.data);
15
- try {
16
- highlighter.getLanguage(lang.name);
17
- } catch {
18
- throw new Error(`attachResolvedLanguages: "${grammar.name}" is already loaded without alias "${lang.name}". Load the alias first or give the grammar a unique name.`);
19
- }
14
+ highlighter.attachLanguages([lang]);
20
15
  AttachedLanguages.add(lang.name);
21
16
  }
22
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"attachResolvedLanguages.js","names":[],"sources":["../../../src/highlighter/languages/attachResolvedLanguages.ts"],"sourcesContent":["import type { DiffsHighlighter } from '../../types';\nimport type { ResolvedLanguage } from '../../worker';\nimport { AttachedLanguages, ResolvedLanguages } from './constants';\n\nexport function attachResolvedLanguages(\n resolvedLanguages: ResolvedLanguage | ResolvedLanguage[],\n highlighter: DiffsHighlighter\n): void {\n resolvedLanguages = Array.isArray(resolvedLanguages)\n ? resolvedLanguages\n : [resolvedLanguages];\n\n for (const resolvedLang of resolvedLanguages) {\n if (AttachedLanguages.has(resolvedLang.name)) continue;\n let lang = ResolvedLanguages.get(resolvedLang.name);\n if (lang == null) {\n lang = resolvedLang;\n ResolvedLanguages.set(resolvedLang.name, lang);\n }\n const grammar = lang.data.find(\n (grammar) =>\n grammar.name === lang.name ||\n grammar.aliases?.includes(lang.name) === true\n );\n if (grammar == null) {\n throw new Error(\n `attachResolvedLanguages: No returned grammar declares \"${lang.name}\" as its name or an alias.`\n );\n }\n highlighter.loadLanguageSync(lang.data);\n // Shiki can skip an already-loaded grammar, including any newly added aliases.\n try {\n highlighter.getLanguage(lang.name);\n } catch {\n throw new Error(\n `attachResolvedLanguages: \"${grammar.name}\" is already loaded without alias \"${lang.name}\". Load the alias first or give the grammar a unique name.`\n );\n }\n AttachedLanguages.add(lang.name);\n }\n}\n"],"mappings":";;AAIA,SAAgB,wBACd,mBACA,aACM;CACN,oBAAoB,MAAM,QAAQ,iBAAiB,IAC/C,oBACA,CAAC,iBAAiB;CAEtB,KAAK,MAAM,gBAAgB,mBAAmB;EAC5C,IAAI,kBAAkB,IAAI,aAAa,IAAI,GAAG;EAC9C,IAAI,OAAO,kBAAkB,IAAI,aAAa,IAAI;EAClD,IAAI,QAAQ,MAAM;GAChB,OAAO;GACP,kBAAkB,IAAI,aAAa,MAAM,IAAI;EAC/C;EACA,MAAM,UAAU,KAAK,KAAK,MACvB,YACC,QAAQ,SAAS,KAAK,QACtB,QAAQ,SAAS,SAAS,KAAK,IAAI,MAAM,IAC7C;EACA,IAAI,WAAW,MACb,MAAM,IAAI,MACR,0DAA0D,KAAK,KAAK,2BACtE;EAEF,YAAY,iBAAiB,KAAK,IAAI;EAEtC,IAAI;GACF,YAAY,YAAY,KAAK,IAAI;EACnC,QAAQ;GACN,MAAM,IAAI,MACR,6BAA6B,QAAQ,KAAK,qCAAqC,KAAK,KAAK,2DAC3F;EACF;EACA,kBAAkB,IAAI,KAAK,IAAI;CACjC;AACF"}
1
+ {"version":3,"file":"attachResolvedLanguages.js","names":[],"sources":["../../../src/highlighter/languages/attachResolvedLanguages.ts"],"sourcesContent":["import type { DiffsHighlighter } from '../../types';\nimport type { ResolvedLanguage } from '../../worker';\nimport { AttachedLanguages, ResolvedLanguages } from './constants';\n\n/**\n * Record resolved grammars in the shared language cache and attach them to a\n * highlighter. Highlights bundles its lexers and ignores the grammars.\n */\nexport function attachResolvedLanguages(\n resolvedLanguages: ResolvedLanguage | ResolvedLanguage[],\n highlighter: DiffsHighlighter\n): void {\n for (const resolvedLang of Array.isArray(resolvedLanguages)\n ? resolvedLanguages\n : [resolvedLanguages]) {\n // The first resolution of a name wins so every instance and worker\n // attaches the same grammar data for it.\n let lang = ResolvedLanguages.get(resolvedLang.name);\n if (lang == null) {\n lang = resolvedLang;\n ResolvedLanguages.set(resolvedLang.name, lang);\n }\n highlighter.attachLanguages([lang]);\n AttachedLanguages.add(lang.name);\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,wBACd,mBACA,aACM;CACN,KAAK,MAAM,gBAAgB,MAAM,QAAQ,iBAAiB,IACtD,oBACA,CAAC,iBAAiB,GAAG;EAGvB,IAAI,OAAO,kBAAkB,IAAI,aAAa,IAAI;EAClD,IAAI,QAAQ,MAAM;GAChB,OAAO;GACP,kBAAkB,IAAI,aAAa,MAAM,IAAI;EAC/C;EACA,YAAY,gBAAgB,CAAC,IAAI,CAAC;EAClC,kBAAkB,IAAI,KAAK,IAAI;CACjC;AACF"}
@@ -1,5 +1,5 @@
1
- import { SupportedLanguages } from "../../types.js";
2
1
  import { ResolvedLanguage } from "../../worker/types.js";
2
+ import { SupportedLanguages } from "../../types.js";
3
3
  import "../../worker/index.js";
4
4
  import { DynamicImportLanguageRegistration } from "shiki";
5
5
  //#region src/highlighter/languages/constants.d.ts
@@ -1,5 +1,5 @@
1
- import { SupportedLanguages } from "../../types.js";
2
1
  import { ResolvedLanguage } from "../../worker/types.js";
2
+ import { SupportedLanguages } from "../../types.js";
3
3
  import "../../worker/index.js";
4
4
  //#region src/highlighter/languages/getResolvedLanguages.d.ts
5
5
  declare function getResolvedLanguages(languages: SupportedLanguages[]): ResolvedLanguage[];
@@ -1,5 +1,5 @@
1
- import { SupportedLanguages } from "../../types.js";
2
1
  import { ResolvedLanguage } from "../../worker/types.js";
2
+ import { SupportedLanguages } from "../../types.js";
3
3
  import "../../worker/index.js";
4
4
  //#region src/highlighter/languages/getResolvedOrResolveLanguage.d.ts
5
5
  declare function getResolvedOrResolveLanguage(language: Exclude<SupportedLanguages, 'text' | 'ansi'>): ResolvedLanguage | Promise<ResolvedLanguage>;
@@ -1,5 +1,5 @@
1
- import { SupportedLanguages } from "../../types.js";
2
1
  import { ResolvedLanguage } from "../../worker/types.js";
2
+ import { SupportedLanguages } from "../../types.js";
3
3
  import "../../worker/index.js";
4
4
  //#region src/highlighter/languages/resolveLanguage.d.ts
5
5
  declare function resolveLanguage(lang: Exclude<SupportedLanguages, 'text' | 'ansi'>): Promise<ResolvedLanguage>;
@@ -1 +1 @@
1
- {"version":3,"file":"resolveLanguage.d.ts","names":[],"sources":["../../../src/highlighter/languages/resolveLanguage.ts"],"mappings":";;;;iBAWsB,gBACpB,MAAM,QAAQ,uCACb,QAAQ"}
1
+ {"version":3,"file":"resolveLanguage.d.ts","names":[],"sources":["../../../src/highlighter/languages/resolveLanguage.ts"],"mappings":";;;;iBAasB,gBACpB,MAAM,QAAQ,uCACb,QAAQ"}
@@ -1,27 +1,30 @@
1
1
  import { RegisteredCustomLanguages, ResolvedLanguages, ResolvingLanguages } from "./constants.js";
2
2
  import { isWorkerContext } from "../../utils/isWorkerContext.js";
3
- import { bundledLanguages } from "shiki";
4
3
  //#region src/highlighter/languages/resolveLanguage.ts
5
4
  async function resolveLanguage(lang) {
6
- if (isWorkerContext()) throw new Error(`resolveLanguage("${lang}") cannot be called from a worker context. Languages must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`);
7
- const resolver = ResolvingLanguages.get(lang);
8
- if (resolver != null) return resolver;
9
- try {
5
+ if (typeof __DIFFS_WORKER__ !== "undefined" ? __DIFFS_WORKER__ : isWorkerContext()) throw new Error(`resolveLanguage("${lang}") cannot be called from a worker context. Languages must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`);
6
+ const pending = ResolvingLanguages.get(lang);
7
+ if (pending != null) return pending;
8
+ const resolver = (async () => {
10
9
  let loader = RegisteredCustomLanguages.get(lang);
11
- if (loader == null && Object.prototype.hasOwnProperty.call(bundledLanguages, lang)) loader = bundledLanguages[lang];
10
+ if (loader == null) {
11
+ const { bundledLanguages } = await import("shiki/langs");
12
+ if (Object.prototype.hasOwnProperty.call(bundledLanguages, lang)) loader = bundledLanguages[lang];
13
+ }
12
14
  if (loader == null) throw new Error(`resolveLanguage: "${lang}" not found in bundled or custom languages`);
13
- const resolver = loader().then(({ default: data }) => {
14
- const resolvedLang = {
15
- name: lang,
16
- data
17
- };
18
- if (!ResolvedLanguages.has(lang)) ResolvedLanguages.set(lang, resolvedLang);
19
- return resolvedLang;
20
- });
21
- ResolvingLanguages.set(lang, resolver);
15
+ const { default: data } = await loader();
16
+ const resolvedLang = {
17
+ name: lang,
18
+ data
19
+ };
20
+ if (!ResolvedLanguages.has(lang)) ResolvedLanguages.set(lang, resolvedLang);
21
+ return resolvedLang;
22
+ })();
23
+ ResolvingLanguages.set(lang, resolver);
24
+ try {
22
25
  return await resolver;
23
26
  } finally {
24
- ResolvingLanguages.delete(lang);
27
+ if (ResolvingLanguages.get(lang) === resolver) ResolvingLanguages.delete(lang);
25
28
  }
26
29
  }
27
30
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"resolveLanguage.js","names":[],"sources":["../../../src/highlighter/languages/resolveLanguage.ts"],"sourcesContent":["import { bundledLanguages } from 'shiki';\n\nimport type { BundledLanguage, SupportedLanguages } from '../../types';\nimport { isWorkerContext } from '../../utils/isWorkerContext';\nimport type { ResolvedLanguage } from '../../worker';\nimport {\n RegisteredCustomLanguages,\n ResolvedLanguages,\n ResolvingLanguages,\n} from './constants';\n\nexport async function resolveLanguage(\n lang: Exclude<SupportedLanguages, 'text' | 'ansi'>\n): Promise<ResolvedLanguage> {\n // Prevent dynamic imports in worker contexts\n if (isWorkerContext()) {\n throw new Error(\n `resolveLanguage(\"${lang}\") cannot be called from a worker context. ` +\n 'Languages must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.'\n );\n }\n\n const resolver = ResolvingLanguages.get(lang);\n if (resolver != null) {\n return resolver;\n }\n\n try {\n let loader = RegisteredCustomLanguages.get(lang);\n if (\n loader == null &&\n Object.prototype.hasOwnProperty.call(bundledLanguages, lang)\n ) {\n loader = bundledLanguages[lang as BundledLanguage];\n }\n if (loader == null) {\n throw new Error(\n `resolveLanguage: \"${lang}\" not found in bundled or custom languages`\n );\n }\n\n const resolver = loader().then(({ default: data }) => {\n const resolvedLang = { name: lang, data };\n if (!ResolvedLanguages.has(lang)) {\n ResolvedLanguages.set(lang, resolvedLang);\n }\n return resolvedLang;\n });\n ResolvingLanguages.set(lang, resolver);\n return await resolver;\n } finally {\n ResolvingLanguages.delete(lang);\n }\n}\n"],"mappings":";;;;AAWA,eAAsB,gBACpB,MAC2B;CAE3B,IAAI,gBAAgB,GAClB,MAAM,IAAI,MACR,oBAAoB,KAAK,2JAE3B;CAGF,MAAM,WAAW,mBAAmB,IAAI,IAAI;CAC5C,IAAI,YAAY,MACd,OAAO;CAGT,IAAI;EACF,IAAI,SAAS,0BAA0B,IAAI,IAAI;EAC/C,IACE,UAAU,QACV,OAAO,UAAU,eAAe,KAAK,kBAAkB,IAAI,GAE3D,SAAS,iBAAiB;EAE5B,IAAI,UAAU,MACZ,MAAM,IAAI,MACR,qBAAqB,KAAK,2CAC5B;EAGF,MAAM,WAAW,OAAO,CAAC,CAAC,MAAM,EAAE,SAAS,WAAW;GACpD,MAAM,eAAe;IAAE,MAAM;IAAM;GAAK;GACxC,IAAI,CAAC,kBAAkB,IAAI,IAAI,GAC7B,kBAAkB,IAAI,MAAM,YAAY;GAE1C,OAAO;EACT,CAAC;EACD,mBAAmB,IAAI,MAAM,QAAQ;EACrC,OAAO,MAAM;CACf,UAAU;EACR,mBAAmB,OAAO,IAAI;CAChC;AACF"}
1
+ {"version":3,"file":"resolveLanguage.js","names":[],"sources":["../../../src/highlighter/languages/resolveLanguage.ts"],"sourcesContent":["import type { BundledLanguage } from 'shiki';\n\nimport type { SupportedLanguages } from '../../types';\nimport { isWorkerContext } from '../../utils/isWorkerContext';\nimport type { ResolvedLanguage } from '../../worker';\nimport {\n RegisteredCustomLanguages,\n ResolvedLanguages,\n ResolvingLanguages,\n} from './constants';\n\ndeclare const __DIFFS_WORKER__: boolean | undefined;\n\nexport async function resolveLanguage(\n lang: Exclude<SupportedLanguages, 'text' | 'ansi'>\n): Promise<ResolvedLanguage> {\n if (\n typeof __DIFFS_WORKER__ !== 'undefined'\n ? __DIFFS_WORKER__\n : isWorkerContext()\n ) {\n throw new Error(\n `resolveLanguage(\"${lang}\") cannot be called from a worker context. Languages must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`\n );\n }\n const pending = ResolvingLanguages.get(lang);\n if (pending != null) return pending;\n const resolver = (async () => {\n let loader = RegisteredCustomLanguages.get(lang);\n if (loader == null) {\n const { bundledLanguages } = await import('shiki/langs');\n if (Object.prototype.hasOwnProperty.call(bundledLanguages, lang))\n loader = bundledLanguages[lang as BundledLanguage];\n }\n if (loader == null)\n throw new Error(\n `resolveLanguage: \"${lang}\" not found in bundled or custom languages`\n );\n const { default: data } = await loader();\n const resolvedLang = { name: lang, data };\n if (!ResolvedLanguages.has(lang)) ResolvedLanguages.set(lang, resolvedLang);\n return resolvedLang;\n })();\n ResolvingLanguages.set(lang, resolver);\n try {\n return await resolver;\n } finally {\n if (ResolvingLanguages.get(lang) === resolver)\n ResolvingLanguages.delete(lang);\n }\n}\n"],"mappings":";;;AAaA,eAAsB,gBACpB,MAC2B;CAC3B,IACE,OAAO,qBAAqB,cACxB,mBACA,gBAAgB,GAEpB,MAAM,IAAI,MACR,oBAAoB,KAAK,2JAC3B;CAEF,MAAM,UAAU,mBAAmB,IAAI,IAAI;CAC3C,IAAI,WAAW,MAAM,OAAO;CAC5B,MAAM,YAAY,YAAY;EAC5B,IAAI,SAAS,0BAA0B,IAAI,IAAI;EAC/C,IAAI,UAAU,MAAM;GAClB,MAAM,EAAE,qBAAqB,MAAM,OAAO;GAC1C,IAAI,OAAO,UAAU,eAAe,KAAK,kBAAkB,IAAI,GAC7D,SAAS,iBAAiB;EAC9B;EACA,IAAI,UAAU,MACZ,MAAM,IAAI,MACR,qBAAqB,KAAK,2CAC5B;EACF,MAAM,EAAE,SAAS,SAAS,MAAM,OAAO;EACvC,MAAM,eAAe;GAAE,MAAM;GAAM;EAAK;EACxC,IAAI,CAAC,kBAAkB,IAAI,IAAI,GAAG,kBAAkB,IAAI,MAAM,YAAY;EAC1E,OAAO;CACT,EAAA,CAAG;CACH,mBAAmB,IAAI,MAAM,QAAQ;CACrC,IAAI;EACF,OAAO,MAAM;CACf,UAAU;EACR,IAAI,mBAAmB,IAAI,IAAI,MAAM,UACnC,mBAAmB,OAAO,IAAI;CAClC;AACF"}
@@ -1,5 +1,5 @@
1
- import { SupportedLanguages } from "../../types.js";
2
1
  import { ResolvedLanguage } from "../../worker/types.js";
2
+ import { SupportedLanguages } from "../../types.js";
3
3
  import "../../worker/index.js";
4
4
  //#region src/highlighter/languages/resolveLanguages.d.ts
5
5
  declare function resolveLanguages(languages: SupportedLanguages[]): Promise<ResolvedLanguage[]>;
@@ -1,22 +1,36 @@
1
- import { DiffsHighlighter, DiffsThemeNames, HighlighterTypes, SupportedLanguages, ThemesType } from "../types.js";
1
+ import { DiffsHighlighter } from "./DiffsHighlighter.js";
2
+ import { DiffsThemeNames, HighlighterTypes, SupportedLanguages, ThemesType } from "../types.js";
3
+ import { HighlighterDisposedError, getHighlighterType } from "./highlighterType.js";
2
4
  //#region src/highlighter/shared_highlighter.d.ts
3
- type CachedOrLoadingHighlighterType = Promise<DiffsHighlighter> | DiffsHighlighter | undefined;
4
5
  interface HighlighterOptions {
5
6
  themes: DiffsThemeNames[];
6
7
  langs: SupportedLanguages[];
7
8
  preferredHighlighter?: HighlighterTypes;
8
9
  }
10
+ /**
11
+ * Creates an instance the caller must dispose. Defaults to the active type
12
+ * or DEFAULT_HIGHLIGHTER; rejects if a different type is already active.
13
+ */
14
+ declare function createHighlighter(type?: HighlighterTypes): Promise<DiffsHighlighter>;
9
15
  declare function getSharedHighlighter({ themes, langs, preferredHighlighter }: HighlighterOptions): Promise<DiffsHighlighter>;
10
- declare function isHighlighterLoaded(h?: CachedOrLoadingHighlighterType): h is DiffsHighlighter;
16
+ declare function isHighlighterLoaded(): boolean;
11
17
  interface GetHighlighterIfLoadedProps {
12
- theme: DiffsThemeNames | ThemesType;
13
- lang: SupportedLanguages;
18
+ theme?: DiffsThemeNames | ThemesType;
19
+ lang?: SupportedLanguages;
14
20
  }
15
- declare function getHighlighterIfLoaded(withSettings?: GetHighlighterIfLoadedProps): DiffsHighlighter | undefined;
16
- declare function isHighlighterLoading(h?: CachedOrLoadingHighlighterType): h is Promise<DiffsHighlighter>;
17
- declare function isHighlighterNull(h?: CachedOrLoadingHighlighterType): h is undefined;
21
+ /**
22
+ * Returns undefined if the theme or language is not loaded.
23
+ */
24
+ declare function getHighlighterIfLoaded({ theme, lang }?: GetHighlighterIfLoadedProps): DiffsHighlighter | undefined;
25
+ declare function isHighlighterLoading(): boolean;
26
+ declare function isHighlighterNull(): boolean;
18
27
  declare function preloadHighlighter(options: HighlighterOptions): Promise<void>;
28
+ /**
29
+ * Disposes an already loaded shared instance synchronously and clears caches.
30
+ * Instances from createHighlighter() must be disposed separately before
31
+ * switching types.
32
+ */
19
33
  declare function disposeHighlighter(): Promise<void>;
20
34
  //#endregion
21
- export { disposeHighlighter, getHighlighterIfLoaded, getSharedHighlighter, isHighlighterLoaded, isHighlighterLoading, isHighlighterNull, preloadHighlighter };
35
+ export { HighlighterDisposedError, HighlighterOptions, createHighlighter, disposeHighlighter, getHighlighterIfLoaded, getHighlighterType, getSharedHighlighter, isHighlighterLoaded, isHighlighterLoading, isHighlighterNull, preloadHighlighter };
22
36
  //# sourceMappingURL=shared_highlighter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared_highlighter.d.ts","names":[],"sources":["../../src/highlighter/shared_highlighter.ts"],"mappings":";;KA2BK,iCACD,QAAQ,oBACR;UAKM;EACR,QAAQ;EACR,OAAO;EACP,uBAAuB;;iBAGH,uBACpB,QACA,OACA,wBACC,qBAAqB,QAAQ;iBAmDhB,oBACd,IAAG,iCACF,KAAK;UAIE;EACR,OAAO,kBAAkB;EACzB,MAAM;;iBAGQ,uBACd,eAAe,8BACd;iBAca,qBACd,IAAG,iCACF,KAAK,QAAQ;iBAIA,kBACd,IAAG,iCACF;iBAImB,mBACpB,SAAS,qBACR;iBAImB,sBAAsB"}
1
+ {"version":3,"file":"shared_highlighter.d.ts","names":[],"sources":["../../src/highlighter/shared_highlighter.ts"],"mappings":";;;;UAyBiB;EACf,QAAQ;EACR,OAAO;EACP,uBAAuB;;;;;;iBAOH,kBACpB,OAAO,mBACN,QAAQ;iBAgBW,uBACpB,QACA,OACA,wBACC,qBAAqB,QAAQ;iBAwChB;UAKN;EACR,QAAQ,kBAAkB;EAC1B,OAAO;;;;;iBAMO,yBACd,OACA,SACC,8BAAmC;iBActB;iBAIA;iBAKM,mBACpB,SAAS,qBACR;;;;;;iBASmB,sBAAsB"}