ember-repl 5.0.1 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +2 -404
  3. package/config/.try.mjs +87 -0
  4. package/config/addon-main.cjs +7 -0
  5. package/config/attw.json +7 -0
  6. package/config/babel.publish.config.cjs +29 -0
  7. package/config/ember-cli-update.json +21 -0
  8. package/config/rollup.config.mjs +44 -0
  9. package/config/testem.cjs +35 -0
  10. package/config/tsconfig.publish.json +18 -0
  11. package/config/vite.config.mjs +36 -0
  12. package/declarations/compile/Compiled.d.ts +7 -0
  13. package/declarations/compile/Compiled.d.ts.map +1 -0
  14. package/declarations/compile/compile.d.ts +17 -0
  15. package/declarations/compile/compile.d.ts.map +1 -0
  16. package/declarations/compile/state.d.ts +43 -0
  17. package/declarations/compile/state.d.ts.map +1 -0
  18. package/declarations/compile/types.d.ts +5 -12
  19. package/declarations/compile/types.d.ts.map +1 -1
  20. package/declarations/index.d.ts +6 -2
  21. package/declarations/index.d.ts.map +1 -1
  22. package/declarations/services/compiler.d.ts +94 -0
  23. package/declarations/services/compiler.d.ts.map +1 -0
  24. package/declarations/services/known-modules.d.ts +7 -0
  25. package/declarations/services/known-modules.d.ts.map +1 -0
  26. package/declarations/setup.d.ts +7 -0
  27. package/declarations/setup.d.ts.map +1 -0
  28. package/declarations/test-support.d.ts +20 -0
  29. package/declarations/test-support.d.ts.map +1 -0
  30. package/dist/_commonjsHelpers-BAGoDD49.js +37 -0
  31. package/dist/_commonjsHelpers-BAGoDD49.js.map +1 -0
  32. package/dist/babel-8wMrbxkT.js +110427 -0
  33. package/dist/babel-8wMrbxkT.js.map +1 -0
  34. package/dist/blank-line-Bzg2Qt4K.js +482 -0
  35. package/dist/blank-line-Bzg2Qt4K.js.map +1 -0
  36. package/dist/compile/Compiled.js +26 -0
  37. package/dist/compile/Compiled.js.map +1 -0
  38. package/dist/compile/compile.js +62 -0
  39. package/dist/compile/compile.js.map +1 -0
  40. package/dist/compile/state.js +75 -0
  41. package/dist/compile/state.js.map +1 -0
  42. package/dist/compile/utils.js +214 -3
  43. package/dist/compile/utils.js.map +1 -1
  44. package/dist/default-CoqAuVeH.js +4 -0
  45. package/dist/default-CoqAuVeH.js.map +1 -0
  46. package/dist/index-BTx1k6gT.js +323 -0
  47. package/dist/index-BTx1k6gT.js.map +1 -0
  48. package/dist/index-Bxzjtr16.js +87 -0
  49. package/dist/index-Bxzjtr16.js.map +1 -0
  50. package/dist/index-C371bO_b.js +1553 -0
  51. package/dist/index-C371bO_b.js.map +1 -0
  52. package/dist/index-C4AyeeIa.js +5721 -0
  53. package/dist/index-C4AyeeIa.js.map +1 -0
  54. package/dist/index-C8S2G0FH.js +1953 -0
  55. package/dist/index-C8S2G0FH.js.map +1 -0
  56. package/dist/index-CCcIVEUK.js +409 -0
  57. package/dist/index-CCcIVEUK.js.map +1 -0
  58. package/dist/index-CDSIcg03.js +9070 -0
  59. package/dist/index-CDSIcg03.js.map +1 -0
  60. package/dist/index-D8szzCn3.js +2 -0
  61. package/dist/index-D8szzCn3.js.map +1 -0
  62. package/dist/index-DBBNT106.js +2644 -0
  63. package/dist/index-DBBNT106.js.map +1 -0
  64. package/dist/index-DP_Su7Zc.js +362 -0
  65. package/dist/index-DP_Su7Zc.js.map +1 -0
  66. package/dist/index-DejgrVqh.js +11299 -0
  67. package/dist/index-DejgrVqh.js.map +1 -0
  68. package/dist/index-Dr5iYoKt.js +1551 -0
  69. package/dist/index-Dr5iYoKt.js.map +1 -0
  70. package/dist/index-DxolpiGq.js +3336 -0
  71. package/dist/index-DxolpiGq.js.map +1 -0
  72. package/dist/index-ZyJlPFQY.js +249 -0
  73. package/dist/index-ZyJlPFQY.js.map +1 -0
  74. package/dist/index-k6CfLgeq.js +26 -0
  75. package/dist/index-k6CfLgeq.js.map +1 -0
  76. package/dist/index.js +4 -1
  77. package/dist/index.js.map +1 -1
  78. package/dist/services/compiler.js +329 -0
  79. package/dist/services/compiler.js.map +1 -0
  80. package/dist/services/known-modules.js +123 -0
  81. package/dist/services/known-modules.js.map +1 -0
  82. package/dist/setup.js +15 -0
  83. package/dist/setup.js.map +1 -0
  84. package/dist/test-support.js +33 -0
  85. package/dist/test-support.js.map +1 -0
  86. package/package.json +118 -147
  87. package/src/compile/Compiled.ts +45 -0
  88. package/src/compile/compile.ts +89 -0
  89. package/src/compile/state.ts +88 -0
  90. package/src/compile/types.ts +14 -13
  91. package/src/compile/utils.ts +1 -1
  92. package/src/index.ts +6 -2
  93. package/src/services/compiler.ts +401 -0
  94. package/src/services/known-modules.ts +130 -0
  95. package/src/setup.ts +26 -0
  96. package/src/test-support.ts +64 -0
  97. package/addon-main.cjs +0 -5
  98. package/declarations/__PRIVATE__.d.ts +0 -2
  99. package/declarations/__PRIVATE__.d.ts.map +0 -1
  100. package/declarations/compile/formats/gjs/babel.d.ts +0 -7
  101. package/declarations/compile/formats/gjs/babel.d.ts.map +0 -1
  102. package/declarations/compile/formats/gjs/eval.d.ts +0 -8
  103. package/declarations/compile/formats/gjs/eval.d.ts.map +0 -1
  104. package/declarations/compile/formats/gjs/index.d.ts +0 -24
  105. package/declarations/compile/formats/gjs/index.d.ts.map +0 -1
  106. package/declarations/compile/formats/gjs/known-modules.d.ts +0 -46
  107. package/declarations/compile/formats/gjs/known-modules.d.ts.map +0 -1
  108. package/declarations/compile/formats/hbs.d.ts +0 -17
  109. package/declarations/compile/formats/hbs.d.ts.map +0 -1
  110. package/declarations/compile/formats/markdown.d.ts +0 -22
  111. package/declarations/compile/formats/markdown.d.ts.map +0 -1
  112. package/declarations/compile/formats.d.ts +0 -18
  113. package/declarations/compile/formats.d.ts.map +0 -1
  114. package/declarations/compile/index.d.ts +0 -81
  115. package/declarations/compile/index.d.ts.map +0 -1
  116. package/declarations/test-support/index.d.ts +0 -2
  117. package/declarations/test-support/index.d.ts.map +0 -1
  118. package/dist/__PRIVATE__.js +0 -2
  119. package/dist/__PRIVATE__.js.map +0 -1
  120. package/dist/compile/formats/gjs/babel.js +0 -2
  121. package/dist/compile/formats/gjs/babel.js.map +0 -1
  122. package/dist/compile/formats/gjs/eval.js +0 -20
  123. package/dist/compile/formats/gjs/eval.js.map +0 -1
  124. package/dist/compile/formats/gjs/index.js +0 -120
  125. package/dist/compile/formats/gjs/index.js.map +0 -1
  126. package/dist/compile/formats/gjs/known-modules.js +0 -50
  127. package/dist/compile/formats/gjs/known-modules.js.map +0 -1
  128. package/dist/compile/formats/hbs.js +0 -94
  129. package/dist/compile/formats/hbs.js.map +0 -1
  130. package/dist/compile/formats/markdown.js +0 -264
  131. package/dist/compile/formats/markdown.js.map +0 -1
  132. package/dist/compile/formats.js +0 -173
  133. package/dist/compile/formats.js.map +0 -1
  134. package/dist/compile/index.js +0 -113
  135. package/dist/compile/index.js.map +0 -1
  136. package/dist/test-support/index.js +0 -8
  137. package/dist/test-support/index.js.map +0 -1
  138. package/src/__PRIVATE__.ts +0 -1
  139. package/src/compile/formats/gjs/babel.ts +0 -7
  140. package/src/compile/formats/gjs/eval.ts +0 -30
  141. package/src/compile/formats/gjs/index.ts +0 -151
  142. package/src/compile/formats/gjs/known-modules.ts +0 -49
  143. package/src/compile/formats/hbs.ts +0 -101
  144. package/src/compile/formats/markdown.ts +0 -344
  145. package/src/compile/formats.ts +0 -179
  146. package/src/compile/index.ts +0 -219
  147. package/src/test-support/index.ts +0 -5
@@ -1,101 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- // import { precompileJSON } from '@glimmer/compiler';
3
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
- // @ts-ignore
5
- // These things are pre-bundled in the old system.
6
- // ember-template-compiler defines them in AMD/requirejs
7
- import { precompileJSON } from '@glimmer/compiler';
8
- import { getTemplateLocals } from '@glimmer/syntax';
9
- import { setComponentTemplate } from '@ember/component';
10
- import templateOnlyComponent from '@ember/component/template-only';
11
- import { array, concat, fn, get, hash } from '@ember/helper';
12
- import { on } from '@ember/modifier';
13
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
14
- // @ts-ignore
15
- import { createTemplateFactory } from '@ember/template-factory';
16
-
17
- import { nameFor } from '../utils.ts';
18
-
19
- import type { CompileResult } from '../types.ts';
20
- import type { ComponentLike } from '@glint/template';
21
-
22
- /**
23
- * compile a template with an empty scope
24
- * to use components, helpers, etc, you will need to compile with JS
25
- *
26
- * (templates alone do not have a way to import / define complex structures)
27
- */
28
- export function compileHBS(template: string, options: CompileTemplateOptions = {}): CompileResult {
29
- let name = nameFor(template);
30
- let component: undefined | ComponentLike;
31
- let error: undefined | Error;
32
-
33
- try {
34
- component = setComponentTemplate(
35
- compileTemplate(template, { moduleName: options.moduleName || name, ...options }),
36
- templateOnlyComponent(options.moduleName || name)
37
- ) as ComponentLike;
38
- } catch (e) {
39
- error = e as Error | undefined;
40
- }
41
-
42
- return { name, component, error };
43
- }
44
-
45
- interface CompileTemplateOptions {
46
- /**
47
- * Used for debug viewing
48
- */
49
- moduleName?: string;
50
- scope?: Record<string, unknown>;
51
- }
52
-
53
- /**
54
- * The reason why we can't use precompile directly is because of this:
55
- * https://github.com/glimmerjs/glimmer-vm/blob/master/packages/%40glimmer/compiler/lib/compiler.ts#L132
56
- *
57
- * Support for dynamically compiling templates in strict mode doesn't seem to be fully their yet.
58
- * That JSON.stringify (and the lines after) prevent us from easily setting the scope function,
59
- * which means that *everything* is undefined.
60
- */
61
- function compileTemplate(source: string, { moduleName, scope = {} }: CompileTemplateOptions) {
62
- let localScope = { array, concat, fn, get, hash, on, ...scope } as any;
63
- let locals = getTemplateLocals(source);
64
-
65
- let options = {
66
- strictMode: true,
67
- moduleName,
68
- locals,
69
- isProduction: false,
70
- meta: { moduleName },
71
- };
72
-
73
- // Copied from @glimmer/compiler/lib/compiler#precompile
74
- let [block, usedLocals] = precompileJSON(source, options);
75
-
76
- let usedScope = usedLocals.map((key: string) => {
77
- let value = localScope[key];
78
-
79
- if (!value) {
80
- throw new Error(
81
- `Attempt to use ${key} in compiled hbs, but it was not available in scope. ` +
82
- `Available scope includes: ${Object.keys(localScope)}`
83
- );
84
- }
85
-
86
- return value;
87
- });
88
-
89
- let blockJSON = JSON.stringify(block);
90
- let templateJSONObject = {
91
- id: moduleName,
92
- block: blockJSON,
93
- moduleName: moduleName ?? '(dynamically compiled component)',
94
- scope: () => usedScope,
95
- isStrictMode: true,
96
- };
97
-
98
- let factory = createTemplateFactory(templateJSONObject);
99
-
100
- return factory;
101
- }
@@ -1,344 +0,0 @@
1
- import rehypeRaw from 'rehype-raw';
2
- import rehypeStringify from 'rehype-stringify';
3
- import remarkGfm from 'remark-gfm';
4
- import remarkParse from 'remark-parse';
5
- import remarkRehype from 'remark-rehype';
6
- import { unified } from 'unified';
7
- import { visit } from 'unist-util-visit';
8
-
9
- import { invocationOf, nameFor } from '../utils.ts';
10
-
11
- import type { UnifiedPlugin } from '../types.ts';
12
- import type { Node } from 'hast';
13
- import type { Code, Text } from 'mdast';
14
- import type { Parent } from 'unist';
15
- import type { VFile } from 'vfile';
16
-
17
- export interface ExtractedCode {
18
- name: string;
19
- code: string;
20
- lang: string;
21
- }
22
-
23
- export interface LiveCodeExtraction {
24
- templateOnlyGlimdown: string;
25
- blocks: ExtractedCode[];
26
- }
27
- type LiveData = {
28
- liveCode?: ExtractedCode[];
29
- };
30
- type VFileWithMeta = VFile & {
31
- data: LiveData;
32
- };
33
-
34
- interface Options {
35
- snippets?: {
36
- classList?: string[];
37
- };
38
- demo?: {
39
- classList?: string[];
40
- };
41
- copyComponent?: string;
42
- shadowComponent?: string;
43
- }
44
-
45
- const GLIMDOWN_PREVIEW = Symbol('__GLIMDOWN_PREVIEW__');
46
- const GLIMDOWN_RENDER = Symbol('__GLIMDOWN_RENDER__');
47
- const ALLOWED_LANGUAGES = ['gjs', 'hbs'] as const;
48
-
49
- type AllowedLanguage = (typeof ALLOWED_LANGUAGES)[number];
50
- type RelevantCode = Omit<Code, 'lang'> & { lang: AllowedLanguage };
51
-
52
- function isLive(meta: string) {
53
- return meta.includes('live');
54
- }
55
-
56
- function isPreview(meta: string) {
57
- return meta.includes('preview');
58
- }
59
-
60
- function isBelow(meta: string) {
61
- return meta.includes('below');
62
- }
63
-
64
- // TODO: extract and publish remark plugin
65
- function liveCodeExtraction(options: Options = {}) {
66
- let { copyComponent, snippets, demo } = options;
67
- let { classList: snippetClasses } = snippets || {};
68
- let { classList: demoClasses } = demo || {};
69
-
70
- snippetClasses ??= [];
71
- demoClasses ??= [];
72
-
73
- function isRelevantCode(node: Code): node is RelevantCode {
74
- if (node.type !== 'code') return false;
75
-
76
- let { meta, lang } = node;
77
-
78
- meta = meta?.trim();
79
-
80
- if (!meta || !lang) return false;
81
-
82
- if (!meta.includes('live')) {
83
- return false;
84
- }
85
-
86
- if (!(ALLOWED_LANGUAGES as unknown as string[]).includes(lang)) return false;
87
-
88
- return true;
89
- }
90
-
91
- let copyNode = {
92
- type: 'html',
93
- value: copyComponent,
94
- };
95
-
96
- function enhance(code: Code) {
97
- code.data ??= {};
98
- (code.data as any)['hProperties'] ??= {};
99
- // This is secret-to-us-only API, so we don't really care about the type
100
- (code.data as any)['hProperties'][GLIMDOWN_PREVIEW] = true;
101
-
102
- return {
103
- data: {
104
- hProperties: { className: snippetClasses },
105
- },
106
- type: 'div',
107
- hProperties: { className: snippetClasses },
108
- children: [code, copyNode],
109
- };
110
- }
111
-
112
- function flatReplaceAt<T>(array: T[], index: number, replacement: T[]) {
113
- array.splice(index, 1, ...replacement);
114
- }
115
-
116
- // because we mutate the tree as we iterate,
117
- // we need to make sure we don't loop forever
118
- const seen = new Set();
119
-
120
- return function transformer(tree: Parent, file: VFileWithMeta) {
121
- visit(tree, ['code'], function (node, index, parent) {
122
- if (parent === null || parent === undefined) return;
123
- if (index === null || index === undefined) return;
124
-
125
- if (!isRelevantCode(node as Code)) {
126
- let enhanced = enhance(node as Code);
127
-
128
- parent.children[index] = enhanced;
129
-
130
- return 'skip';
131
- }
132
-
133
- if (seen.has(node)) return 'skip';
134
-
135
- seen.add(node);
136
-
137
- let { meta, lang, value } = node as Code;
138
-
139
- if (!meta) return 'skip';
140
- if (!lang) return 'skip';
141
-
142
- file.data.liveCode ??= [];
143
-
144
- let code = value.trim();
145
- let name = nameFor(code);
146
- let invocation = invocationOf(name);
147
-
148
- let shadow = options.shadowComponent;
149
-
150
- let wrapInShadow = shadow && !meta?.includes('no-shadow');
151
-
152
- if (wrapInShadow) {
153
- invocation = `<${shadow}>${invocation}</${shadow}>`;
154
- }
155
-
156
- let invokeNode = {
157
- type: 'html',
158
- data: {
159
- hProperties: { [GLIMDOWN_RENDER]: true },
160
- },
161
- value: `<div class="${demoClasses}">${invocation}</div>`,
162
- };
163
-
164
- let wrapper = enhance(node as Code);
165
-
166
- file.data.liveCode.push({
167
- lang,
168
- name,
169
- code,
170
- });
171
-
172
- let live = isLive(meta);
173
- let preview = isPreview(meta);
174
- let below = isBelow(meta);
175
-
176
- if (live && preview && below) {
177
- flatReplaceAt(parent.children, index, [wrapper, invokeNode]);
178
-
179
- return 'skip';
180
- }
181
-
182
- if (live && preview) {
183
- flatReplaceAt(parent.children, index, [invokeNode, wrapper]);
184
-
185
- return 'skip';
186
- }
187
-
188
- if (live) {
189
- parent.children[index] = invokeNode;
190
-
191
- return 'skip';
192
- }
193
-
194
- parent.children[index] = wrapper;
195
-
196
- return;
197
- });
198
- };
199
- }
200
-
201
- function sanitizeForGlimmer(/* options */) {
202
- return (tree: Parent) => {
203
- visit(tree, 'element', (node: Parent) => {
204
- if ('tagName' in node) {
205
- if (!['pre', 'code'].includes(node.tagName as string)) return;
206
-
207
- visit(node, 'text', (textNode: Text) => {
208
- if ('value' in textNode && textNode.value) {
209
- textNode.value = textNode.value.replace(/{{/g, '\\{{');
210
- }
211
- });
212
-
213
- return 'skip';
214
- }
215
- });
216
- };
217
- }
218
-
219
- function buildCompiler(options: ParseMarkdownOptions) {
220
- let compiler = unified().use(remarkParse).use(remarkGfm);
221
-
222
- /**
223
- * If this were "use"d after `remarkRehype`,
224
- * remark is gone, and folks would need to work with rehype trees
225
- */
226
- if (options.remarkPlugins) {
227
- options.remarkPlugins.forEach((plugin) => {
228
- // Arrays are how plugins are passed options (for some reason?)
229
- // why not just invoke the the function?
230
- let p = Array.isArray(plugin) ? plugin : [plugin];
231
-
232
- compiler = compiler.use(...(p as [any]));
233
- });
234
- }
235
-
236
- // TODO: we only want to do this when we have pre > code.
237
- // code can exist inline.
238
- compiler = compiler.use(liveCodeExtraction, {
239
- snippets: {
240
- classList: ['glimdown-snippet', 'relative'],
241
- },
242
- demo: {
243
- classList: ['glimdown-render'],
244
- },
245
- copyComponent: options?.CopyComponent,
246
- shadowComponent: options?.ShadowComponent,
247
- });
248
-
249
- // .use(() => (tree) => visit(tree, (node) => console.log('i', node)))
250
- // remark rehype is needed to convert markdown to HTML
251
- // However, it also changes all the nodes, so we need another pass
252
- // to make sure our Glimmer-aware nodes are in tact
253
- compiler = compiler.use(remarkRehype, { allowDangerousHtml: true });
254
-
255
- // Convert invocables to raw format, so Glimmer can invoke them
256
- compiler = compiler.use(() => (tree: Node) => {
257
- visit(tree, function (node) {
258
- // We rely on an implicit transformation of data.hProperties => properties
259
- let properties = (node as any).properties;
260
-
261
- if (properties?.[GLIMDOWN_PREVIEW]) {
262
- return 'skip';
263
- }
264
-
265
- if (node.type === 'element' || ('tagName' in node && node.tagName === 'code')) {
266
- if (properties?.[GLIMDOWN_RENDER]) {
267
- node.type = 'glimmer_raw';
268
-
269
- return;
270
- }
271
-
272
- return 'skip';
273
- }
274
-
275
- if (node.type === 'text' || node.type === 'raw') {
276
- // definitively not the better way, but this is supposed to detect "glimmer" nodes
277
- if (
278
- 'value' in node &&
279
- typeof node.value === 'string' &&
280
- node.value.match(/<\/?[_A-Z:0-9].*>/g)
281
- ) {
282
- node.type = 'glimmer_raw';
283
- }
284
-
285
- node.type = 'glimmer_raw';
286
-
287
- return 'skip';
288
- }
289
-
290
- return;
291
- });
292
- });
293
-
294
- if (options.rehypePlugins) {
295
- options.rehypePlugins.forEach((plugin) => {
296
- // Arrays are how plugins are passed options (for some reason?)
297
- // why not just invoke the the function?
298
- let p = Array.isArray(plugin) ? plugin : [plugin];
299
-
300
- compiler = compiler.use(...(p as [any]));
301
- });
302
- }
303
-
304
- compiler = compiler.use(rehypeRaw, { passThrough: ['glimmer_raw', 'raw'] }).use(() => (tree) => {
305
- visit(tree, 'glimmer_raw', (node: Node) => {
306
- node.type = 'raw';
307
- });
308
- });
309
-
310
- compiler = compiler.use(sanitizeForGlimmer);
311
-
312
- // Finally convert to string! oofta!
313
- compiler = compiler.use(rehypeStringify, {
314
- collapseEmptyAttributes: true,
315
- closeSelfClosing: true,
316
- allowParseErrors: true,
317
- allowDangerousCharacters: true,
318
- allowDangerousHtml: true,
319
- }) as any;
320
-
321
- return compiler as ReturnType<typeof unified>;
322
- }
323
-
324
- interface ParseMarkdownOptions {
325
- CopyComponent?: string;
326
- ShadowComponent?: string;
327
- remarkPlugins?: UnifiedPlugin[];
328
- rehypePlugins?: UnifiedPlugin[];
329
- }
330
-
331
- /**
332
- * @internal not under semver
333
- */
334
- export async function parseMarkdown(
335
- input: string,
336
- options: ParseMarkdownOptions = {}
337
- ): Promise<LiveCodeExtraction> {
338
- let markdownCompiler = buildCompiler(options);
339
- let processed = await markdownCompiler.process(input);
340
- let liveCode = (processed.data as LiveData).liveCode || [];
341
- let templateOnly = processed.toString();
342
-
343
- return { templateOnlyGlimdown: templateOnly, blocks: liveCode };
344
- }
@@ -1,179 +0,0 @@
1
- import { invocationName } from './utils.ts';
2
-
3
- import type { ExtractedCode } from './formats/markdown.ts';
4
- import type { CompileResult, UnifiedPlugin } from './types.ts';
5
- import type { EvalImportMap, ScopeMap } from './types.ts';
6
-
7
- async function compileGJSArray(js: { code: string }[], importMap?: EvalImportMap) {
8
- let modules = await Promise.all(
9
- js.map(async ({ code }) => {
10
- return await compileGJS(code, importMap);
11
- })
12
- );
13
-
14
- return modules;
15
- }
16
-
17
- export async function compileGJS(
18
- gjsInput: string,
19
- importMap?: EvalImportMap
20
- ): Promise<CompileResult> {
21
- try {
22
- let { compileJS } = await import('./formats/gjs/index.ts');
23
-
24
- return await compileJS(gjsInput, importMap);
25
- } catch (error) {
26
- return { error: error as Error, name: 'unknown' };
27
- }
28
- }
29
-
30
- export async function compileHBS(
31
- hbsInput: string,
32
- options?: {
33
- moduleName?: string;
34
- scope?: Record<string, unknown>;
35
- }
36
- ): Promise<CompileResult> {
37
- try {
38
- let { compileHBS } = await import('./formats/hbs.ts');
39
-
40
- return compileHBS(hbsInput, options);
41
- } catch (error) {
42
- return { error: error as Error, name: 'unknown' };
43
- }
44
- }
45
-
46
- async function extractScope(
47
- liveCode: ExtractedCode[],
48
- options?: {
49
- importMap?: EvalImportMap;
50
- topLevelScope?: ScopeMap;
51
- }
52
- ): Promise<CompileResult[]> {
53
- let scope: CompileResult[] = [];
54
-
55
- let hbs = liveCode.filter((code) => code.lang === 'hbs');
56
- let js = liveCode.filter((code) => ['js', 'gjs'].includes(code.lang));
57
-
58
- if (js.length > 0) {
59
- let compiled = await compileGJSArray(js, options?.importMap);
60
-
61
- await Promise.all(
62
- compiled.map(async (info) => {
63
- // using web worker + import maps is not available yet (need firefox support)
64
- // (and to somehow be able to point at npm)
65
- //
66
- // if ('importPath' in info) {
67
- // return scope.push({
68
- // moduleName: name,
69
- // component: await import(/* webpackIgnore: true */ info.importPath),
70
- // });
71
- // }
72
-
73
- return scope.push(info);
74
- })
75
- );
76
- }
77
-
78
- for (let { code } of hbs) {
79
- let compiled = await compileHBS(code, { scope: options?.topLevelScope });
80
-
81
- scope.push(compiled);
82
- }
83
-
84
- return scope;
85
- }
86
-
87
- export async function compileMD(
88
- glimdownInput: string,
89
- options?: {
90
- importMap?: EvalImportMap;
91
- topLevelScope?: ScopeMap;
92
- remarkPlugins?: UnifiedPlugin[];
93
- rehypePlugins?: UnifiedPlugin[];
94
- CopyComponent?: string;
95
- ShadowComponent?: string;
96
- }
97
- ): Promise<CompileResult & { rootTemplate?: string }> {
98
- let topLevelScope = options?.topLevelScope ?? {};
99
- let rootTemplate: string;
100
- let liveCode: ExtractedCode[];
101
- let scope: CompileResult[] = [];
102
-
103
- /**
104
- * Step 1: Convert Markdown To HTML (Ember).
105
- *
106
- * The remark plugin, remark-code-extra also extracts
107
- * and transforms the code blocks we care about.
108
- *
109
- * These blocks will be compiled through babel and eval'd so the
110
- * compiled rootTemplate can invoke them
111
- */
112
- try {
113
- let { parseMarkdown } = await import('./formats/markdown.ts');
114
- let { templateOnlyGlimdown, blocks } = await parseMarkdown(glimdownInput, {
115
- CopyComponent: options?.CopyComponent,
116
- ShadowComponent: options?.ShadowComponent,
117
- remarkPlugins: options?.remarkPlugins,
118
- rehypePlugins: options?.rehypePlugins,
119
- });
120
-
121
- rootTemplate = templateOnlyGlimdown;
122
- liveCode = blocks;
123
- } catch (error) {
124
- return { error: error as Error, name: 'unknown' };
125
- }
126
-
127
- /**
128
- * Step 2: Compile the live code samples
129
- */
130
- if (liveCode.length > 0) {
131
- try {
132
- scope = await extractScope(liveCode, options);
133
- } catch (error) {
134
- console.info({ scope });
135
- console.error(error);
136
-
137
- return { error: error as Error, rootTemplate, name: 'unknown' };
138
- }
139
- }
140
-
141
- /**
142
- * Make sure non of our snippets errored
143
- *
144
- * TODO: for these errors, report them differently so that we
145
- * can render the 'Ember' and still highlight the correct line?
146
- * or maybe there is a way to highlight in the editor instead?
147
- */
148
- for (let { error, component } of scope) {
149
- if (!component) {
150
- if (error) {
151
- return { error, rootTemplate, name: 'unknown' };
152
- }
153
- }
154
- }
155
-
156
- /**
157
- * Step 4: Compile the Ember Template
158
- */
159
- try {
160
- let localScope = scope.reduce(
161
- (accum, { component, name }) => {
162
- accum[invocationName(name)] = component;
163
-
164
- return accum;
165
- },
166
- {} as Record<string, unknown>
167
- );
168
-
169
- return await compileHBS(rootTemplate, {
170
- moduleName: 'DynamicRootTemplate',
171
- scope: {
172
- ...topLevelScope,
173
- ...localScope,
174
- },
175
- });
176
- } catch (error) {
177
- return { error: error as Error, rootTemplate, name: 'unknown' };
178
- }
179
- }