@skaldapp/loader-sfc 2.4.10

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.
@@ -0,0 +1,107 @@
1
+ import { compileScript, compileStyleAsync, compileTemplate, parse, } from "@vue/compiler-sfc";
2
+ import hash_sum from "hash-sum";
3
+ import { transform } from "sucrase";
4
+ const fetching = async (input) => {
5
+ try {
6
+ const response = await fetch(input);
7
+ if (response.ok)
8
+ return await response.text();
9
+ else
10
+ throw new Error(response.statusText);
11
+ }
12
+ catch (error) {
13
+ console.error(error);
14
+ }
15
+ return;
16
+ }, inject = async (code) => {
17
+ const objectURL = URL.createObjectURL(new Blob([code], { type: "application/javascript" }));
18
+ try {
19
+ return (await import(objectURL));
20
+ }
21
+ finally {
22
+ URL.revokeObjectURL(objectURL);
23
+ }
24
+ };
25
+ export default async (sfc, { parseOptions, scriptOptions: { templateOptions: { compilerOptions: { expressionPlugins, ...restCompilerOptions } = {}, ...restTemplateOptions } = {}, ...restScriptOptions } = {}, styleOptions, } = {}) => {
26
+ let styleWarning = "";
27
+ const hash = hash_sum(sfc), styleErrors = [], { descriptor, errors: parseErrors } = parse(sfc || "<template></template>", { filename: `${hash}.vue`, ...parseOptions }), { filename, script, scriptSetup, slotted, styles, template } = descriptor;
28
+ const id = `data-v-${hash}`, langs = new Set([script, scriptSetup]
29
+ .filter((scriptBlock) => scriptBlock !== null)
30
+ .flatMap(({ lang = "js" }) => [
31
+ ...(/[jt]sx$/.test(lang) ? ["jsx"] : []),
32
+ ...(/tsx?$/.test(lang) ? ["typescript"] : []),
33
+ ])), compilerOptions = {
34
+ expressionPlugins: [
35
+ ...new Set([...(expressionPlugins ?? []), ...langs]),
36
+ ],
37
+ filename,
38
+ scopeId: id,
39
+ slotted,
40
+ ...restCompilerOptions,
41
+ }, templateOptions = {
42
+ compilerOptions,
43
+ filename,
44
+ id,
45
+ scoped: styles.some(({ scoped }) => scoped),
46
+ slotted,
47
+ ...restTemplateOptions,
48
+ }, scriptOptions = {
49
+ id,
50
+ templateOptions,
51
+ ...restScriptOptions,
52
+ }, style = document.getElementById(id) instanceof HTMLStyleElement
53
+ ? Promise.resolve([])
54
+ : Promise.all(styles.map(async ({ content, module, scoped = false, src }) => {
55
+ const modules = !!module;
56
+ if (modules && !styleWarning) {
57
+ styleWarning =
58
+ "<style module> is not supported in the playground.";
59
+ return "";
60
+ }
61
+ else {
62
+ const { code, errors } = await compileStyleAsync({
63
+ filename,
64
+ id,
65
+ modules,
66
+ scoped,
67
+ source: src ? ((await fetching(src)) ?? "") : content,
68
+ ...styleOptions,
69
+ });
70
+ styleErrors.push(...errors);
71
+ return code;
72
+ }
73
+ })), sucraseOptions = {
74
+ jsxRuntime: "preserve",
75
+ transforms: [...langs],
76
+ }, { ast, content: source = "" } = template ?? {}, { bindings, content, warnings: scriptWarnings, } = script || scriptSetup ? compileScript(descriptor, scriptOptions) : {};
77
+ if (bindings)
78
+ compilerOptions.bindingMetadata = bindings;
79
+ const { code, errors: templateErrors, tips: templateTips, } = template && (!scriptSetup || !scriptOptions.inlineTemplate)
80
+ ? compileTemplate({
81
+ ...ast,
82
+ filename,
83
+ id,
84
+ source,
85
+ ...templateOptions,
86
+ })
87
+ : {};
88
+ [...parseErrors, ...(templateErrors ?? []), ...styleErrors].forEach(console.error);
89
+ [...(scriptWarnings ?? []), ...(styleWarning ? [styleWarning] : [])].forEach(console.warn);
90
+ [...(templateTips ?? [])].forEach(console.info);
91
+ const [styleResult, scriptResult, templateResult] = await Promise.all([
92
+ style,
93
+ content
94
+ ? inject(langs.size ? transform(content, sucraseOptions).code : content)
95
+ : Promise.resolve(undefined),
96
+ code
97
+ ? inject(langs.size ? transform(code, sucraseOptions).code : code)
98
+ : Promise.resolve(undefined),
99
+ ]), textContent = styleResult.join("\n").trim();
100
+ if (textContent) {
101
+ const el = document.createElement("style");
102
+ el.id = id;
103
+ el.textContent = textContent;
104
+ document.head.appendChild(el);
105
+ }
106
+ return { __scopeId: id, ...scriptResult?.["default"], ...templateResult };
107
+ };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "$schema": "https://www.schemastore.org/package",
3
+ "name": "@skaldapp/loader-sfc",
4
+ "version": "2.4.10",
5
+ "description": "A lightweight library that enables loading Vue 3 Single File Components (.vue files) directly in the browser at runtime without requiring a build step. Supports TypeScript and JSX transformations for dynamic component loading.",
6
+ "keywords": [
7
+ "vue",
8
+ "sfc",
9
+ "loader",
10
+ "runtime",
11
+ "typescript",
12
+ "jsx",
13
+ "dynamic",
14
+ "components"
15
+ ],
16
+ "homepage": "https://github.com/skaldapp/loader-sfc#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/skaldapp/loader-sfc/issues"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/skaldapp/loader-sfc.git"
23
+ },
24
+ "license": "AGPL-3.0-only",
25
+ "author": "Jerry Bruwes <jbruwes@gmail.com> (https://jbruwes.github.io)",
26
+ "type": "module",
27
+ "main": "./dist/loader-sfc.js",
28
+ "types": "./dist/loader-sfc.d.ts",
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "scripts": {
33
+ "build": "tsc && vite build",
34
+ "lint": "eslint ."
35
+ },
36
+ "prettier": "@skaldapp/configs/prettierrc",
37
+ "dependencies": {
38
+ "@vue/compiler-sfc": "^3.5.26",
39
+ "hash-sum": "^2.0.0",
40
+ "sucrase": "^3.35.1"
41
+ },
42
+ "devDependencies": {
43
+ "@skaldapp/configs": "^1.2.41",
44
+ "@types/hash-sum": "^1.0.2",
45
+ "@types/node": "^25.0.3",
46
+ "eslint": "^9.39.2",
47
+ "terser": "^5.44.1",
48
+ "vite": "^7.3.1"
49
+ }
50
+ }