Skip to content

Commit b10c3c3

Browse files
committed
allow loading ripple compiler & formatter from pkg.pr.new
1 parent 264033e commit b10c3c3

File tree

12 files changed

+76
-33
lines changed

12 files changed

+76
-33
lines changed

scripts/build.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ const iifeBuild = () =>
238238
'languages/rescript/lang-rescript-formatter.ts',
239239
'languages/riot/lang-riot-compiler.ts',
240240
'languages/ripple/lang-ripple-compiler.ts',
241+
'languages/ripple/lang-ripple-formatter.ts',
241242
'languages/ruby-wasm/lang-ruby-wasm-script.ts',
242243
'languages/scss/lang-scss-compiler.ts',
243244
'languages/solid/lang-solid-compiler.ts',

src/livecodes/formatter/format.worker.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { defaultConfig } from '../config/default-config';
22
import { languages, parserPlugins, prettierUrl } from '../languages';
3-
import type { FormatFn, FormatterConfig, Language, Parser } from '../models';
3+
import type { Config, FormatFn, FormatterConfig, Language, Parser } from '../models';
44
import type { FormatterMessage, FormatterMessageEvent } from './models';
55

66
const worker: Worker = self as any;
@@ -9,6 +9,7 @@ declare const prettierPlugins: { [key: string]: { parsers: any } };
99
declare const importScripts: (...args: string[]) => void;
1010

1111
let baseUrl: string;
12+
let initialConfig: Config;
1213
const parsers: { [key: string]: Parser } = {};
1314
const plugins: { [key: string]: any } = {};
1415
const formatters: { [key: string]: FormatFn } = {};
@@ -94,15 +95,15 @@ async function loadParser(language: Language): Promise<Parser | undefined> {
9495
return parser;
9596
}
9697

97-
const loadFormatter = (language: Language): FormatFn | undefined => {
98+
const loadFormatter = async (language: Language): Promise<FormatFn | undefined> => {
9899
if (language in formatters) {
99100
return formatters[language];
100101
}
101102

102103
const formatter = getFormatter(language);
103104
if (!formatter) return;
104105

105-
formatters[language] = formatter.factory(baseUrl, language);
106+
formatters[language] = await formatter.factory(baseUrl, language, initialConfig);
106107
return formatters[language];
107108
};
108109

@@ -135,7 +136,7 @@ const format = async (
135136
return formatted || unFormatted;
136137
}
137138
if (getFormatter(language) != null) {
138-
const formatFn = loadFormatter(language);
139+
const formatFn = await loadFormatter(language);
139140
const result = await formatFn?.(value, cursorOffset);
140141
return result || unFormatted;
141142
}
@@ -148,7 +149,8 @@ worker.addEventListener(
148149
const message = event.data;
149150

150151
if (message.type === 'init') {
151-
baseUrl = message.baseUrl;
152+
baseUrl = message.payload.baseUrl;
153+
initialConfig = message.payload.config;
152154
}
153155

154156
if (message.type === 'load') {

src/livecodes/formatter/formatter.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import type { FormatFn, Language } from '../models';
1+
import type { Config, FormatFn, Language } from '../models';
22
import { getAppCDN } from '../services/modules';
33
import type { Formatter, FormatterMessage, FormatterMessageEvent } from './models';
44

5-
export const createFormatter = (baseUrl: string): Formatter => {
5+
export const createFormatter = (baseUrl: string, config: Config): Formatter => {
66
let worker: Worker | undefined;
77

88
const initWorker = () => {
99
if (worker) return;
1010
worker = new Worker(baseUrl + '{{hash:format.worker.js}}' + '?appCDN=' + getAppCDN());
11-
const configMessage: FormatterMessage = { type: 'init', baseUrl };
11+
const configMessage: FormatterMessage = { type: 'init', payload: { baseUrl, config } };
1212
worker.postMessage(configMessage);
1313
};
1414

src/livecodes/formatter/get-formatter.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ export const getFormatter = (config: Config, baseUrl: string, lazy: boolean): Fo
88
if (readonly || mode === 'codeblock' || mode === 'result') {
99
return createFakeFormatter();
1010
} else if (lazy) {
11-
return createLazyFormatter(baseUrl);
11+
return createLazyFormatter(baseUrl, config);
1212
} else {
13-
return createFormatter(baseUrl);
13+
return createFormatter(baseUrl, config);
1414
}
1515
};
1616

17-
const createLazyFormatter = (baseUrl: string) => {
17+
const createLazyFormatter = (baseUrl: string, config: Config) => {
1818
const fakeFormatter = createFakeFormatter();
1919
let formatter = fakeFormatter;
2020

@@ -34,7 +34,7 @@ const createLazyFormatter = (baseUrl: string) => {
3434
};
3535

3636
const loadFormatter = function () {
37-
formatter = createFormatter(baseUrl);
37+
formatter = createFormatter(baseUrl, config);
3838
lazyFormatter.load = formatter.load;
3939
lazyFormatter.getFormatFn = formatter.getFormatFn;
4040
lazyFormatter.destroy = formatter.destroy;

src/livecodes/formatter/models.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { FormatFn, FormatterConfig, Language } from '../models';
1+
import type { Config, FormatFn, FormatterConfig, Language } from '../models';
22

33
export interface Formatter {
44
load: (languages: Language[]) => Promise<string>;
@@ -21,7 +21,10 @@ export type FormatterMessage =
2121

2222
export interface InitMessage {
2323
type: 'init';
24-
baseUrl: string;
24+
payload: {
25+
baseUrl: string;
26+
config: Config;
27+
};
2528
}
2629

2730
export interface LoadMessage {

src/livecodes/languages/prettier.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { prettierBaseUrl, prettierPhpUrl, prettierRippleUrl, vendorsBaseUrl } from '../vendors';
1+
import { prettierBaseUrl, prettierPhpUrl, vendorsBaseUrl } from '../vendors';
22

33
export const prettierUrl = prettierBaseUrl + 'standalone.js';
44
export const parserPlugins = {
@@ -11,5 +11,4 @@ export const parserPlugins = {
1111
php: prettierPhpUrl,
1212
pug: vendorsBaseUrl + 'prettier/parser-pug.js',
1313
java: vendorsBaseUrl + 'prettier/parser-java.js',
14-
ripple: prettierRippleUrl,
1514
};

src/livecodes/languages/ripple/lang-ripple-compiler.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,26 @@ import { createImportMap, replaceSFCImports } from '../../compiler/import-map';
33
import { getCompileResult } from '../../compiler/utils';
44
import type { CompilerFunction, Config } from '../../models';
55
import { modulesService } from '../../services/modules';
6+
import { pkgInfoService } from '../../services/pkgInfo';
67
import { getLanguageByAlias } from '../utils';
78

8-
const getLatestVersion = async () => {
9-
const pkg = await fetch('https://data.jsdelivr.com/v1/packages/npm/ripple')
10-
.then((res) => res.json())
11-
.catch(() => ({}));
12-
return pkg.tags?.latest || 'latest';
13-
};
14-
159
(self as any).createRippleCompiler = async (initialConfig: Config): Promise<CompilerFunction> => {
1610
const MAIN_FILE = '__LiveCodes_App__.ripple';
1711
let importedContent = '';
1812
let imports: Record<string, string> = {};
1913

20-
let version: string = initialConfig.customSettings.ripple?.version || (await getLatestVersion());
14+
let version: string =
15+
initialConfig.customSettings.ripple?.version ||
16+
(await pkgInfoService.getPkgLatestVersion('ripple'));
2117
let compile: (code: string, filename: string) => Promise<{ js: { code: string }; css: string }>;
2218

2319
const updateCompiler = async (currentVersion: string) => {
2420
if (typeof compile === 'function' && currentVersion === version) return;
25-
const mod = await import(
26-
/* @__PURE__ */ modulesService.getModuleUrl(`ripple@${currentVersion}/compiler`)
27-
);
21+
const modName =
22+
currentVersion.startsWith('pr:ripple@') || currentVersion.startsWith('pkg.pr.new:ripple@')
23+
? `${currentVersion}/compiler` // 'pr:ripple@f8bdb34'
24+
: `ripple@${currentVersion}/compiler`; // '0.2.25'
25+
const mod = await import(modulesService.getModuleUrl(modName));
2826
compile = mod.compile;
2927
version = currentVersion;
3028
};
@@ -72,7 +70,7 @@ document.head.appendChild(styles);
7270
`;
7371

7472
if (filename === MAIN_FILE) {
75-
const moduleUrl = /* @__PURE__ */ modulesService.getModuleUrl(`ripple@${version}`);
73+
const moduleUrl = modulesService.getModuleUrl(`ripple@${version}`);
7674
imports = {
7775
...createImportMap(importedContent, config),
7876
ripple: moduleUrl,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { defaultConfig } from '../../config/default-config';
2+
import type { Config, FormatFn } from '../../models';
3+
import { modulesService } from '../../services/modules';
4+
import { pkgInfoService } from '../../services/pkgInfo';
5+
import { prettierEsmUrl, prettierRippleUrl } from '../../vendors';
6+
7+
(self as any).createRippleFormatter = async (initialConfig: Config): Promise<FormatFn> => {
8+
const version =
9+
initialConfig.customSettings.ripple?.version ||
10+
(await pkgInfoService.getPkgLatestVersion('ripple'));
11+
const pluginUrl =
12+
version.startsWith('pr:ripple@') || version.startsWith('pkg.pr.new:ripple@')
13+
? modulesService.getModuleUrl(version.replace('ripple', 'prettier-plugin-ripple'))
14+
: prettierRippleUrl;
15+
16+
const [prettier, ripplePlugin] = await Promise.all([import(prettierEsmUrl), import(pluginUrl)]);
17+
return async (code, cursorOffset, formatterConfig) =>
18+
prettier.formatWithCursor(code, {
19+
parser: 'ripple',
20+
plugins: [ripplePlugin],
21+
cursorOffset,
22+
useTabs: formatterConfig?.useTabs ?? defaultConfig.useTabs,
23+
tabWidth: formatterConfig?.tabSize ?? defaultConfig.tabSize,
24+
semi: formatterConfig?.semicolons ?? defaultConfig.semicolons,
25+
singleQuote: formatterConfig?.singleQuote ?? defaultConfig.singleQuote,
26+
trailingComma: formatterConfig?.trailingComma === false ? 'none' : 'all',
27+
});
28+
};

src/livecodes/languages/ripple/lang-ripple.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import type { LanguageSpecs } from '../../models';
2-
import { parserPlugins } from '../prettier';
32

43
export const ripple: LanguageSpecs = {
54
name: 'ripple',
65
title: 'Ripple',
76
info: false,
8-
parser: {
9-
name: 'ripple',
10-
pluginUrls: [parserPlugins.ripple],
7+
formatter: {
8+
factory: async (baseUrl, _language, config) => {
9+
(self as any).importScripts(baseUrl + '{{hash:lang-ripple-formatter.js}}');
10+
return (self as any).createRippleFormatter(config);
11+
},
1112
},
1213
compiler: {
1314
factory: (config, baseUrl) => {

src/livecodes/services/pkgInfo.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,17 @@ const getPkgDefaultFiles = async (
217217
};
218218
};
219219

220+
const getPkgLatestVersion = async (pkgName: string): Promise<string> => {
221+
const pkg = await fetch(`${apiEndpoint}/packages/npm/${pkgName}`, { headers: jsDelivrHeaders })
222+
.then((res) => res.json())
223+
.catch(() => ({}));
224+
return pkg.tags?.latest || 'latest';
225+
};
226+
220227
export const pkgInfoService: CDNService = {
221228
search,
222229
getPkgInfo,
223230
getPkgFiles,
224231
getPkgDefaultFiles,
232+
getPkgLatestVersion,
225233
};

0 commit comments

Comments
 (0)