native-sfc 0.0.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.
@@ -0,0 +1,272 @@
1
+ // dependencies loaded from esm.sh
2
+
3
+ // src/components.ts
4
+ import * as stackTraceParser2 from "https://esm.sh/stacktrace-parser";
5
+
6
+ // src/rewriter.ts
7
+ import { parse } from "https://esm.sh/es-module-lexer/js";
8
+ import * as stackTraceParser from "https://esm.sh/stacktrace-parser";
9
+ function rewriteModule(code, sourceUrl) {
10
+ const [imports] = parse(code);
11
+ const rewritableImports = imports.filter((i) => {
12
+ const specifier = code.slice(i.s, i.e);
13
+ return !isBrowserUrl(specifier) && !specifier.startsWith("data:");
14
+ });
15
+ for (const importEntry of rewritableImports.reverse()) {
16
+ const specifier = code.slice(importEntry.s, importEntry.e);
17
+ let rewritten = specifier;
18
+ if (specifier.startsWith(".") || specifier.startsWith("/")) {
19
+ rewritten = new URL(specifier, sourceUrl).href;
20
+ } else {
21
+ rewritten = `https://esm.sh/${specifier}`;
22
+ }
23
+ code = code.slice(0, importEntry.s) + rewritten + code.slice(importEntry.e);
24
+ }
25
+ return `import.meta.url=${JSON.stringify(sourceUrl)};
26
+ ${code}`;
27
+ }
28
+ function isBrowserUrl(url) {
29
+ return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("blob:http://") || url.startsWith("blob:https://") || url.startsWith("data:");
30
+ }
31
+ var blobMap = /* @__PURE__ */ new Map();
32
+ async function esm(code, sourceUrl) {
33
+ code = rewriteModule(code, sourceUrl);
34
+ const blob = new Blob([code], { type: "text/javascript" });
35
+ const blobUrl = URL.createObjectURL(blob);
36
+ blobMap.set(blobUrl, sourceUrl);
37
+ try {
38
+ const module = await import(blobUrl);
39
+ return module;
40
+ } finally {
41
+ URL.revokeObjectURL(blobUrl);
42
+ }
43
+ }
44
+ function getImporterUrl() {
45
+ const stack = stackTraceParser.parse(new Error().stack);
46
+ for (const { file } of stack) {
47
+ if (file && file !== import.meta.url) {
48
+ if (file.startsWith("blob:")) {
49
+ if (blobMap.has(file)) {
50
+ return blobMap.get(file);
51
+ }
52
+ continue;
53
+ }
54
+ return file;
55
+ }
56
+ }
57
+ return null;
58
+ }
59
+
60
+ // src/error.ts
61
+ var NativeSFCError = class extends Error {
62
+ constructor(message, options) {
63
+ super(message, options);
64
+ this.name = "NativeSFCError";
65
+ }
66
+ };
67
+ function warn(...args) {
68
+ console.warn("NativeSFC Warning:", ...args);
69
+ }
70
+
71
+ // src/network.ts
72
+ var fetch = globalThis.fetch;
73
+ function defineFetch(customFetch) {
74
+ fetch = customFetch;
75
+ }
76
+ async function requestText(url, userFriendlySource) {
77
+ return request(url, userFriendlySource).then((res) => res.text());
78
+ }
79
+ async function request(url, userFriendlySource) {
80
+ let response;
81
+ try {
82
+ response = await fetch(url);
83
+ } catch (error) {
84
+ throw new NativeSFCError(`Failed to fetch ${url} at ${userFriendlySource}`, {
85
+ cause: error
86
+ });
87
+ }
88
+ if (!response.ok) {
89
+ throw new NativeSFCError(`Failed to fetch ${url} at ${userFriendlySource}`, {
90
+ cause: new Error(`HTTP status ${response.status}`)
91
+ });
92
+ }
93
+ return response;
94
+ }
95
+
96
+ // src/events.ts
97
+ var eventTarget = new EventTarget();
98
+ function emit(eventName, detail) {
99
+ const event = new CustomEvent(eventName, { detail });
100
+ eventTarget.dispatchEvent(event);
101
+ }
102
+ function on(eventName, listener) {
103
+ eventTarget.addEventListener(eventName, listener);
104
+ return () => {
105
+ eventTarget.removeEventListener(eventName, listener);
106
+ };
107
+ }
108
+
109
+ // src/components.ts
110
+ var loadedComponentsRecord = /* @__PURE__ */ new Map();
111
+ async function loadComponent(name, url, afterConstructor) {
112
+ const importerUrl = getImporterUrl() || location.href;
113
+ url = new URL(url, importerUrl).href;
114
+ emit("component-loading", { name, url });
115
+ if (customElements.get(name)) {
116
+ if (!loadedComponentsRecord.has(name)) {
117
+ throw new NativeSFCError(`Component name ${JSON.stringify(name)} is already being used`);
118
+ }
119
+ const loadedComponentRecord = loadedComponentsRecord.get(name);
120
+ if (loadedComponentRecord.url === url) {
121
+ return loadedComponentRecord.cec;
122
+ }
123
+ }
124
+ const html = await requestText(
125
+ url,
126
+ `loadComponent(${JSON.stringify(name)}, ${JSON.stringify(url)})`
127
+ );
128
+ const doc = new DOMParser().parseFromString(html, "text/html");
129
+ filterGlobalStyle(doc);
130
+ rewriteStyleAndScript(doc, url);
131
+ const adoptedStyleSheets = await collectAdoptedStyleSheets(doc);
132
+ const result = await evaluateModules(doc, url);
133
+ for (const el of doc.querySelectorAll("script")) {
134
+ doc.body.prepend(el);
135
+ }
136
+ const component = result.default;
137
+ const defaultExportIsComponent = component?.prototype instanceof HTMLElement;
138
+ if (component && !defaultExportIsComponent) {
139
+ warn(
140
+ `The default export of component ${JSON.stringify(name)} loaded from ${url} is not a web component class`,
141
+ component
142
+ );
143
+ }
144
+ const define = (component2) => {
145
+ const cec = extendsElement(component2, doc.body.innerHTML, adoptedStyleSheets, afterConstructor);
146
+ customElements.define(name, cec);
147
+ emit("component-defined", { name, url });
148
+ loadedComponentsRecord.set(name, { cec, url });
149
+ return cec;
150
+ };
151
+ if (!component || !defaultExportIsComponent) {
152
+ return define(HTMLElement);
153
+ } else {
154
+ return define(component);
155
+ }
156
+ }
157
+ function extendsElement(BaseClass = HTMLElement, innerHTML, adoptedStyleSheets, afterConstructor) {
158
+ return class extends BaseClass {
159
+ constructor(...args) {
160
+ super(innerHTML, adoptedStyleSheets);
161
+ if (!this.shadowRoot) {
162
+ const shadowRoot = this.attachShadow({ mode: "open" });
163
+ shadowRoot.innerHTML = innerHTML;
164
+ if (adoptedStyleSheets && adoptedStyleSheets.length > 0) {
165
+ shadowRoot.adoptedStyleSheets = adoptedStyleSheets;
166
+ }
167
+ }
168
+ if (afterConstructor) {
169
+ afterConstructor.call(this);
170
+ }
171
+ }
172
+ };
173
+ }
174
+ function defineComponent(fc) {
175
+ const whoDefineMe = stackTraceParser2.parse(new Error().stack).at(-1).file;
176
+ if (blobMap.has(whoDefineMe)) {
177
+ return class extends HTMLElement {
178
+ connectedCallback() {
179
+ fc.call(this, this.shadowRoot || this.attachShadow({ mode: "open" }));
180
+ }
181
+ };
182
+ }
183
+ return fc.call(globalThis, document);
184
+ }
185
+ function filterGlobalStyle(doc) {
186
+ for (const styleElement of doc.querySelectorAll("style")) {
187
+ if (styleElement.hasAttribute("global")) {
188
+ document.head.append(styleElement);
189
+ }
190
+ }
191
+ for (const linkElement of doc.querySelectorAll('link[rel="stylesheet"]')) {
192
+ if (linkElement.hasAttribute("global")) {
193
+ document.head.append(linkElement);
194
+ }
195
+ }
196
+ }
197
+ function cssStyleSheetFromText(styleText, userFriendlySource) {
198
+ const sheet = new CSSStyleSheet();
199
+ try {
200
+ sheet.replaceSync(styleText);
201
+ } catch (error) {
202
+ warn(`Failed to create CSSStyleSheet at ${userFriendlySource}`, error);
203
+ }
204
+ return sheet;
205
+ }
206
+ async function collectAdoptedStyleSheets(doc) {
207
+ const adoptedStyleSheets = [];
208
+ for (const link of doc.querySelectorAll(`link[rel="stylesheet"]`)) {
209
+ const styleText = await requestText(link.href, link.outerHTML).catch(
210
+ (error) => {
211
+ warn(`Failed to load ${link.outerHTML}`, error);
212
+ return "";
213
+ }
214
+ );
215
+ if (!styleText) continue;
216
+ const sheet = cssStyleSheetFromText(styleText, link.outerHTML);
217
+ adoptedStyleSheets.push(sheet);
218
+ link.remove();
219
+ }
220
+ for (const style of doc.querySelectorAll("style")) {
221
+ const styleText = style.innerHTML;
222
+ if (!styleText) continue;
223
+ const sheet = cssStyleSheetFromText(styleText, style.outerHTML);
224
+ adoptedStyleSheets.push(sheet);
225
+ style.remove();
226
+ }
227
+ return adoptedStyleSheets;
228
+ }
229
+ function rewriteStyleAndScript(doc, url) {
230
+ for (const script of doc.querySelectorAll("script[src]")) {
231
+ const src = new URL(
232
+ script.getAttribute("src") || "",
233
+ // getAttribute to avoid getting absolute URL directly, do not use script.src
234
+ url
235
+ ).href;
236
+ script.src = src;
237
+ }
238
+ for (const link of doc.querySelectorAll("link[href]")) {
239
+ const href = new URL(
240
+ link.getAttribute("href") || "",
241
+ // getAttribute to avoid getting absolute URL directly, do not use link.href
242
+ url
243
+ ).href;
244
+ link.href = href;
245
+ }
246
+ }
247
+ async function evaluateModules(doc, url) {
248
+ const result = {};
249
+ for (const script of doc.querySelectorAll('script[type="module"]')) {
250
+ const src = script.src;
251
+ if (src) {
252
+ const res = await request(src, script.outerHTML);
253
+ const code = await res.text();
254
+ const module = await esm(code, res.url);
255
+ Object.assign(result, module);
256
+ } else {
257
+ const module = await esm(script.textContent, url);
258
+ Object.assign(result, module);
259
+ }
260
+ script.remove();
261
+ }
262
+ return result;
263
+ }
264
+ export {
265
+ NativeSFCError,
266
+ defineComponent,
267
+ defineFetch,
268
+ loadComponent,
269
+ on
270
+ };
271
+ //! we provide an extra argument to user's component constructor
272
+ //! if the user's constructor does not create a shadow root, we will create one here
@@ -0,0 +1,71 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * @fileoverview Component loading and registration system for Native SFC (Single File Components).
5
+ *
6
+ * This module provides the core functionality to:
7
+ * - Load HTML-based web components from external files
8
+ * - Parse and process component templates, styles, and scripts
9
+ * - Register custom elements with the browser's CustomElementRegistry
10
+ * - Handle style encapsulation via Shadow DOM and adoptedStyleSheets
11
+ *
12
+ * The component loading process:
13
+ * 1. Fetch the component HTML file
14
+ * 2. Extract and process global styles (move to document head)
15
+ * 3. Rewrite relative URLs in scripts and stylesheets to absolute URLs
16
+ * 4. Convert styles to CSSStyleSheet objects for adoptedStyleSheets (prevents FOUC)
17
+ * 5. Evaluate ES modules and extract the default export (component class)
18
+ * 6. Create an extended component class that injects shadow root with template
19
+ * 7. Register the component with customElements.define()
20
+ */
21
+ /**
22
+ * Load and register a web component from an HTML file.
23
+ *
24
+ * This is the primary entry point for loading Native SFC components.
25
+ * The HTML file can contain:
26
+ * - Template markup (the component's shadow DOM content)
27
+ * - `<style>` tags (scoped to the component's shadow DOM)
28
+ * - `<style global>` tags (injected into the main document)
29
+ * - `<script type="module">` (ES modules, default export should be the component class)
30
+ * - `<script>` (classic scripts, executed when component is instantiated)
31
+ * - `<link rel="stylesheet">` (external stylesheets, also supports `global` attribute)
32
+ *
33
+ * @param name - The custom element tag name (must contain a hyphen, e.g., "my-component")
34
+ * @param url - URL to the component HTML file (relative to the importer or absolute)
35
+ * @param afterConstructor - Optional callback invoked after component constructor completes
36
+ * @returns The CustomElementConstructor for the registered component
37
+ * @throws {NativeSFCError} If the component name is already registered by external code
38
+ *
39
+ * @example
40
+ * // Load and use a component
41
+ * await loadComponent('my-button', './components/my-button.html');
42
+ * document.body.innerHTML = '<my-button>Click me</my-button>';
43
+ */
44
+ export declare function loadComponent(name: string, url: string, afterConstructor?: VoidFunction): Promise<CustomElementConstructor>;
45
+ /**
46
+ * a dual component definition helper function
47
+ * - when used inside loadComponent-imported module, it defines a web component class
48
+ * - when used in normal document context, it just runs the function with document as root
49
+ */
50
+ export declare function defineComponent(fc: (root: Document | ShadowRoot) => void): any;
51
+ export declare class NativeSFCError extends Error {
52
+ constructor(message: string, options?: ErrorOptions);
53
+ }
54
+ declare let fetch$1: typeof globalThis.fetch;
55
+ export declare function defineFetch(customFetch: typeof fetch$1): void;
56
+ export interface NativeSFCEvents {
57
+ "component-loading": {
58
+ name: string;
59
+ url: string;
60
+ };
61
+ "component-defined": {
62
+ name: string;
63
+ url: string;
64
+ };
65
+ }
66
+ export type NativeSFCEventsMap = {
67
+ [K in keyof NativeSFCEvents]: CustomEvent<NativeSFCEvents[K]>;
68
+ };
69
+ export declare function on<K extends keyof NativeSFCEvents>(eventName: K, listener: (ev: NativeSFCEventsMap[K]) => any): () => void;
70
+
71
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,272 @@
1
+ // entrypoint for bundler
2
+
3
+ // src/components.ts
4
+ import * as stackTraceParser2 from "stacktrace-parser";
5
+
6
+ // src/rewriter.ts
7
+ import { parse } from "es-module-lexer/js";
8
+ import * as stackTraceParser from "stacktrace-parser";
9
+ function rewriteModule(code, sourceUrl) {
10
+ const [imports] = parse(code);
11
+ const rewritableImports = imports.filter((i) => {
12
+ const specifier = code.slice(i.s, i.e);
13
+ return !isBrowserUrl(specifier) && !specifier.startsWith("data:");
14
+ });
15
+ for (const importEntry of rewritableImports.reverse()) {
16
+ const specifier = code.slice(importEntry.s, importEntry.e);
17
+ let rewritten = specifier;
18
+ if (specifier.startsWith(".") || specifier.startsWith("/")) {
19
+ rewritten = new URL(specifier, sourceUrl).href;
20
+ } else {
21
+ rewritten = `https://esm.sh/${specifier}`;
22
+ }
23
+ code = code.slice(0, importEntry.s) + rewritten + code.slice(importEntry.e);
24
+ }
25
+ return `import.meta.url=${JSON.stringify(sourceUrl)};
26
+ ${code}`;
27
+ }
28
+ function isBrowserUrl(url) {
29
+ return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("blob:http://") || url.startsWith("blob:https://") || url.startsWith("data:");
30
+ }
31
+ var blobMap = /* @__PURE__ */ new Map();
32
+ async function esm(code, sourceUrl) {
33
+ code = rewriteModule(code, sourceUrl);
34
+ const blob = new Blob([code], { type: "text/javascript" });
35
+ const blobUrl = URL.createObjectURL(blob);
36
+ blobMap.set(blobUrl, sourceUrl);
37
+ try {
38
+ const module = await import(blobUrl);
39
+ return module;
40
+ } finally {
41
+ URL.revokeObjectURL(blobUrl);
42
+ }
43
+ }
44
+ function getImporterUrl() {
45
+ const stack = stackTraceParser.parse(new Error().stack);
46
+ for (const { file } of stack) {
47
+ if (file && file !== import.meta.url) {
48
+ if (file.startsWith("blob:")) {
49
+ if (blobMap.has(file)) {
50
+ return blobMap.get(file);
51
+ }
52
+ continue;
53
+ }
54
+ return file;
55
+ }
56
+ }
57
+ return null;
58
+ }
59
+
60
+ // src/error.ts
61
+ var NativeSFCError = class extends Error {
62
+ constructor(message, options) {
63
+ super(message, options);
64
+ this.name = "NativeSFCError";
65
+ }
66
+ };
67
+ function warn(...args) {
68
+ console.warn("NativeSFC Warning:", ...args);
69
+ }
70
+
71
+ // src/network.ts
72
+ var fetch = globalThis.fetch;
73
+ function defineFetch(customFetch) {
74
+ fetch = customFetch;
75
+ }
76
+ async function requestText(url, userFriendlySource) {
77
+ return request(url, userFriendlySource).then((res) => res.text());
78
+ }
79
+ async function request(url, userFriendlySource) {
80
+ let response;
81
+ try {
82
+ response = await fetch(url);
83
+ } catch (error) {
84
+ throw new NativeSFCError(`Failed to fetch ${url} at ${userFriendlySource}`, {
85
+ cause: error
86
+ });
87
+ }
88
+ if (!response.ok) {
89
+ throw new NativeSFCError(`Failed to fetch ${url} at ${userFriendlySource}`, {
90
+ cause: new Error(`HTTP status ${response.status}`)
91
+ });
92
+ }
93
+ return response;
94
+ }
95
+
96
+ // src/events.ts
97
+ var eventTarget = new EventTarget();
98
+ function emit(eventName, detail) {
99
+ const event = new CustomEvent(eventName, { detail });
100
+ eventTarget.dispatchEvent(event);
101
+ }
102
+ function on(eventName, listener) {
103
+ eventTarget.addEventListener(eventName, listener);
104
+ return () => {
105
+ eventTarget.removeEventListener(eventName, listener);
106
+ };
107
+ }
108
+
109
+ // src/components.ts
110
+ var loadedComponentsRecord = /* @__PURE__ */ new Map();
111
+ async function loadComponent(name, url, afterConstructor) {
112
+ const importerUrl = getImporterUrl() || location.href;
113
+ url = new URL(url, importerUrl).href;
114
+ emit("component-loading", { name, url });
115
+ if (customElements.get(name)) {
116
+ if (!loadedComponentsRecord.has(name)) {
117
+ throw new NativeSFCError(`Component name ${JSON.stringify(name)} is already being used`);
118
+ }
119
+ const loadedComponentRecord = loadedComponentsRecord.get(name);
120
+ if (loadedComponentRecord.url === url) {
121
+ return loadedComponentRecord.cec;
122
+ }
123
+ }
124
+ const html = await requestText(
125
+ url,
126
+ `loadComponent(${JSON.stringify(name)}, ${JSON.stringify(url)})`
127
+ );
128
+ const doc = new DOMParser().parseFromString(html, "text/html");
129
+ filterGlobalStyle(doc);
130
+ rewriteStyleAndScript(doc, url);
131
+ const adoptedStyleSheets = await collectAdoptedStyleSheets(doc);
132
+ const result = await evaluateModules(doc, url);
133
+ for (const el of doc.querySelectorAll("script")) {
134
+ doc.body.prepend(el);
135
+ }
136
+ const component = result.default;
137
+ const defaultExportIsComponent = component?.prototype instanceof HTMLElement;
138
+ if (component && !defaultExportIsComponent) {
139
+ warn(
140
+ `The default export of component ${JSON.stringify(name)} loaded from ${url} is not a web component class`,
141
+ component
142
+ );
143
+ }
144
+ const define = (component2) => {
145
+ const cec = extendsElement(component2, doc.body.innerHTML, adoptedStyleSheets, afterConstructor);
146
+ customElements.define(name, cec);
147
+ emit("component-defined", { name, url });
148
+ loadedComponentsRecord.set(name, { cec, url });
149
+ return cec;
150
+ };
151
+ if (!component || !defaultExportIsComponent) {
152
+ return define(HTMLElement);
153
+ } else {
154
+ return define(component);
155
+ }
156
+ }
157
+ function extendsElement(BaseClass = HTMLElement, innerHTML, adoptedStyleSheets, afterConstructor) {
158
+ return class extends BaseClass {
159
+ constructor(...args) {
160
+ super(innerHTML, adoptedStyleSheets);
161
+ if (!this.shadowRoot) {
162
+ const shadowRoot = this.attachShadow({ mode: "open" });
163
+ shadowRoot.innerHTML = innerHTML;
164
+ if (adoptedStyleSheets && adoptedStyleSheets.length > 0) {
165
+ shadowRoot.adoptedStyleSheets = adoptedStyleSheets;
166
+ }
167
+ }
168
+ if (afterConstructor) {
169
+ afterConstructor.call(this);
170
+ }
171
+ }
172
+ };
173
+ }
174
+ function defineComponent(fc) {
175
+ const whoDefineMe = stackTraceParser2.parse(new Error().stack).at(-1).file;
176
+ if (blobMap.has(whoDefineMe)) {
177
+ return class extends HTMLElement {
178
+ connectedCallback() {
179
+ fc.call(this, this.shadowRoot || this.attachShadow({ mode: "open" }));
180
+ }
181
+ };
182
+ }
183
+ return fc.call(globalThis, document);
184
+ }
185
+ function filterGlobalStyle(doc) {
186
+ for (const styleElement of doc.querySelectorAll("style")) {
187
+ if (styleElement.hasAttribute("global")) {
188
+ document.head.append(styleElement);
189
+ }
190
+ }
191
+ for (const linkElement of doc.querySelectorAll('link[rel="stylesheet"]')) {
192
+ if (linkElement.hasAttribute("global")) {
193
+ document.head.append(linkElement);
194
+ }
195
+ }
196
+ }
197
+ function cssStyleSheetFromText(styleText, userFriendlySource) {
198
+ const sheet = new CSSStyleSheet();
199
+ try {
200
+ sheet.replaceSync(styleText);
201
+ } catch (error) {
202
+ warn(`Failed to create CSSStyleSheet at ${userFriendlySource}`, error);
203
+ }
204
+ return sheet;
205
+ }
206
+ async function collectAdoptedStyleSheets(doc) {
207
+ const adoptedStyleSheets = [];
208
+ for (const link of doc.querySelectorAll(`link[rel="stylesheet"]`)) {
209
+ const styleText = await requestText(link.href, link.outerHTML).catch(
210
+ (error) => {
211
+ warn(`Failed to load ${link.outerHTML}`, error);
212
+ return "";
213
+ }
214
+ );
215
+ if (!styleText) continue;
216
+ const sheet = cssStyleSheetFromText(styleText, link.outerHTML);
217
+ adoptedStyleSheets.push(sheet);
218
+ link.remove();
219
+ }
220
+ for (const style of doc.querySelectorAll("style")) {
221
+ const styleText = style.innerHTML;
222
+ if (!styleText) continue;
223
+ const sheet = cssStyleSheetFromText(styleText, style.outerHTML);
224
+ adoptedStyleSheets.push(sheet);
225
+ style.remove();
226
+ }
227
+ return adoptedStyleSheets;
228
+ }
229
+ function rewriteStyleAndScript(doc, url) {
230
+ for (const script of doc.querySelectorAll("script[src]")) {
231
+ const src = new URL(
232
+ script.getAttribute("src") || "",
233
+ // getAttribute to avoid getting absolute URL directly, do not use script.src
234
+ url
235
+ ).href;
236
+ script.src = src;
237
+ }
238
+ for (const link of doc.querySelectorAll("link[href]")) {
239
+ const href = new URL(
240
+ link.getAttribute("href") || "",
241
+ // getAttribute to avoid getting absolute URL directly, do not use link.href
242
+ url
243
+ ).href;
244
+ link.href = href;
245
+ }
246
+ }
247
+ async function evaluateModules(doc, url) {
248
+ const result = {};
249
+ for (const script of doc.querySelectorAll('script[type="module"]')) {
250
+ const src = script.src;
251
+ if (src) {
252
+ const res = await request(src, script.outerHTML);
253
+ const code = await res.text();
254
+ const module = await esm(code, res.url);
255
+ Object.assign(result, module);
256
+ } else {
257
+ const module = await esm(script.textContent, url);
258
+ Object.assign(result, module);
259
+ }
260
+ script.remove();
261
+ }
262
+ return result;
263
+ }
264
+ export {
265
+ NativeSFCError,
266
+ defineComponent,
267
+ defineFetch,
268
+ loadComponent,
269
+ on
270
+ };
271
+ //! we provide an extra argument to user's component constructor
272
+ //! if the user's constructor does not create a shadow root, we will create one here
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "native-sfc",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "scripts": {
11
+ "build": "node esbuild.ts && dts-bundle-generator -o dist/index.d.ts src/index.ts",
12
+ "dev": "node esbuild.ts --dev"
13
+ },
14
+ "dependencies": {
15
+ "es-module-lexer": "^2.0.0",
16
+ "stacktrace-parser": "^0.1.11"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^25.0.6",
20
+ "dts-bundle-generator": "^9.5.1",
21
+ "esbuild": "^0.27.2"
22
+ },
23
+ "author": "YieldRay",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/YieldRay/native-sfc.git"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/YieldRay/native-sfc/issues"
31
+ },
32
+ "homepage": "https://github.com/YieldRay/native-sfc#readme",
33
+ "publishConfig": {
34
+ "registry": "https://registry.npmjs.org"
35
+ }
36
+ }