@codespark/framework 1.0.0 → 1.0.2
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.
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/dist/html.d.ts +7 -3
- package/dist/html.js +43 -38
- package/dist/index.d.ts +4 -3
- package/dist/loaders.d.ts +4 -4
- package/dist/loaders.js +16 -17
- package/dist/markdown.d.ts +4 -3
- package/dist/markdown.js +13 -13
- package/dist/react.d.ts +4 -3
- package/dist/react.js +50 -33
- package/package.json +4 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 TonyL1u
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# @codespark/framework
|
|
2
|
+
|
|
3
|
+
Core framework abstraction for the [Codespark](https://codesparkjs.com) ecosystem. Provides a unified API for analyzing and compiling code across different frameworks (React, HTML, Markdown).
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
Visit [https://codesparkjs.com/docs/framework](https://codesparkjs.com/docs/framework) to view the documentation.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @codespark/framework
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @codespark/framework
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
### Using Built-in Frameworks
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { react } from '@codespark/framework/react';
|
|
23
|
+
import { html } from '@codespark/framework/html';
|
|
24
|
+
import { markdown } from '@codespark/framework/markdown';
|
|
25
|
+
|
|
26
|
+
// Analyze and compile React code
|
|
27
|
+
const files = {
|
|
28
|
+
'./App.tsx': `
|
|
29
|
+
export default function App() {
|
|
30
|
+
return <h1>Hello World</h1>;
|
|
31
|
+
}
|
|
32
|
+
`
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
react.analyze('./App.tsx', files);
|
|
36
|
+
const compiled = react.compile();
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Registering Frameworks
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { registerFramework, registry } from '@codespark/framework';
|
|
43
|
+
import { react } from '@codespark/framework/react';
|
|
44
|
+
|
|
45
|
+
// Register a framework
|
|
46
|
+
registerFramework(react);
|
|
47
|
+
|
|
48
|
+
// Get a registered framework
|
|
49
|
+
const framework = registry.get('react');
|
|
50
|
+
|
|
51
|
+
// List all registered frameworks
|
|
52
|
+
const frameworks = registry.list(); // ['react']
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Creating Custom Frameworks
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { Framework, type Outputs } from '@codespark/framework';
|
|
59
|
+
|
|
60
|
+
class MyFramework extends Framework {
|
|
61
|
+
readonly name = 'my-framework';
|
|
62
|
+
readonly imports = {
|
|
63
|
+
'my-lib': 'https://esm.sh/my-lib'
|
|
64
|
+
};
|
|
65
|
+
outputs: Outputs = new Map();
|
|
66
|
+
|
|
67
|
+
analyze(entry: string, files: Record<string, string>) {
|
|
68
|
+
// Analyze dependencies and populate outputs
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
compile(): string {
|
|
72
|
+
const builder = this.createBuilder();
|
|
73
|
+
// Build runtime code
|
|
74
|
+
return builder.toString();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## API
|
|
80
|
+
|
|
81
|
+
### `Framework` (Abstract Class)
|
|
82
|
+
|
|
83
|
+
Base class for all framework implementations.
|
|
84
|
+
|
|
85
|
+
| Property/Method | Description |
|
|
86
|
+
|-----------------|-------------|
|
|
87
|
+
| `name` | Framework identifier |
|
|
88
|
+
| `imports` | Import map for external dependencies |
|
|
89
|
+
| `outputs` | Analyzed outputs by loader type |
|
|
90
|
+
| `analyze(entry, files)` | Analyze entry file and its dependencies |
|
|
91
|
+
| `compile()` | Compile analyzed code to executable string |
|
|
92
|
+
| `getOutput(type)` | Get outputs for a specific loader type |
|
|
93
|
+
|
|
94
|
+
### `registerFramework(framework, name?)`
|
|
95
|
+
|
|
96
|
+
Register a framework instance to the global registry.
|
|
97
|
+
|
|
98
|
+
### `registry`
|
|
99
|
+
|
|
100
|
+
Global framework registry instance.
|
|
101
|
+
|
|
102
|
+
| Method | Description |
|
|
103
|
+
|--------|-------------|
|
|
104
|
+
| `get(name)` | Get a framework by name |
|
|
105
|
+
| `list()` | List all registered framework names |
|
|
106
|
+
| `register(framework, name?)` | Register a framework |
|
|
107
|
+
|
|
108
|
+
### Loader Types
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
enum LoaderType {
|
|
112
|
+
ESModule = 'esmodule', // JavaScript/TypeScript modules
|
|
113
|
+
Style = 'style', // CSS stylesheets
|
|
114
|
+
Script = 'script', // Script tags
|
|
115
|
+
Asset = 'asset' // HTML and other assets
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Built-in Frameworks
|
|
120
|
+
|
|
121
|
+
| Framework | Import Path | Description |
|
|
122
|
+
|-----------|-------------|-------------|
|
|
123
|
+
| React | `@codespark/framework/react` | React with JSX/TSX support |
|
|
124
|
+
| HTML | `@codespark/framework/html` | HTML with inline scripts and styles |
|
|
125
|
+
| Markdown | `@codespark/framework/markdown` | Markdown to HTML |
|
|
126
|
+
|
|
127
|
+
## License
|
|
128
|
+
|
|
129
|
+
MIT
|
package/dist/html.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ declare enum LoaderType {
|
|
|
6
6
|
ESModule = "esmodule",
|
|
7
7
|
Style = "style",
|
|
8
8
|
Script = "script",
|
|
9
|
-
Asset = "asset"
|
|
9
|
+
Asset = "asset"
|
|
10
10
|
}
|
|
11
11
|
interface BaseLoaderOutput<T extends LoaderType> {
|
|
12
12
|
type: T;
|
|
@@ -18,6 +18,7 @@ interface ESModuleLoaderOutput extends BaseLoaderOutput<LoaderType.ESModule> {
|
|
|
18
18
|
name: string;
|
|
19
19
|
imported: string[];
|
|
20
20
|
}[];
|
|
21
|
+
raw: string;
|
|
21
22
|
}
|
|
22
23
|
interface StyleLoaderOutput extends BaseLoaderOutput<LoaderType.Style> {
|
|
23
24
|
imports: string[];
|
|
@@ -54,9 +55,12 @@ declare class Framework extends Framework$1 {
|
|
|
54
55
|
readonly imports: {};
|
|
55
56
|
outputs: Outputs;
|
|
56
57
|
private blobUrlMap;
|
|
58
|
+
private LITE_DEFAULT_ENTRY;
|
|
59
|
+
private LITE_DEFAULT_SCRIPT;
|
|
60
|
+
private LITE_DEFAULT_STYLE;
|
|
57
61
|
constructor(config?: FrameworkConfig | undefined);
|
|
58
|
-
analyze(
|
|
59
|
-
compile(): string;
|
|
62
|
+
analyze(files: Record<string, string>): void;
|
|
63
|
+
compile(entry: string): string;
|
|
60
64
|
private wrapInLiteModeTemplate;
|
|
61
65
|
private transformModulesToBlob;
|
|
62
66
|
private transformCodeWithBlobUrls;
|
package/dist/html.js
CHANGED
|
@@ -6,12 +6,12 @@ import { DomUtils, parseDocument } from "htmlparser2";
|
|
|
6
6
|
import { availablePresets, transform } from "@babel/standalone";
|
|
7
7
|
|
|
8
8
|
//#region src/loaders/types.ts
|
|
9
|
-
let LoaderType = /* @__PURE__ */ function(LoaderType
|
|
10
|
-
LoaderType
|
|
11
|
-
LoaderType
|
|
12
|
-
LoaderType
|
|
13
|
-
LoaderType
|
|
14
|
-
return LoaderType
|
|
9
|
+
let LoaderType = /* @__PURE__ */ function(LoaderType) {
|
|
10
|
+
LoaderType["ESModule"] = "esmodule";
|
|
11
|
+
LoaderType["Style"] = "style";
|
|
12
|
+
LoaderType["Script"] = "script";
|
|
13
|
+
LoaderType["Asset"] = "asset";
|
|
14
|
+
return LoaderType;
|
|
15
15
|
}({});
|
|
16
16
|
|
|
17
17
|
//#endregion
|
|
@@ -103,12 +103,8 @@ const buildExternalDeps = (imports, usedSources) => {
|
|
|
103
103
|
var ESLoader = class {
|
|
104
104
|
name = "es-loader";
|
|
105
105
|
test = /\.(tsx?|jsx?)$/;
|
|
106
|
-
jsxPreset;
|
|
107
|
-
isTSX;
|
|
108
106
|
constructor(options) {
|
|
109
|
-
|
|
110
|
-
this.jsxPreset = jsxPreset;
|
|
111
|
-
this.isTSX = isTSX;
|
|
107
|
+
this.options = options;
|
|
112
108
|
}
|
|
113
109
|
transform(source, ctx) {
|
|
114
110
|
const { imports, usedSources } = analyzeImports(parseCode(source));
|
|
@@ -118,28 +114,30 @@ var ESLoader = class {
|
|
|
118
114
|
if (imp.importKind === "type") continue;
|
|
119
115
|
const importPath = imp.source.value;
|
|
120
116
|
if (imp.specifiers.length === 0) {
|
|
121
|
-
const resolved
|
|
122
|
-
if (resolved
|
|
117
|
+
const resolved = ctx.resolve(importPath);
|
|
118
|
+
if (resolved) dependencies[importPath] = resolved;
|
|
123
119
|
continue;
|
|
124
120
|
}
|
|
125
121
|
if (!usedSources.has(importPath)) continue;
|
|
126
122
|
const resolved = ctx.resolve(importPath);
|
|
127
123
|
if (resolved) dependencies[importPath] = resolved;
|
|
128
124
|
}
|
|
125
|
+
const { jsxPreset, isTSX = false } = this.options || {};
|
|
129
126
|
const { typescript } = availablePresets;
|
|
130
127
|
const defaultPresets = [typescript, {
|
|
131
|
-
isTSX
|
|
128
|
+
isTSX,
|
|
132
129
|
allExtensions: true
|
|
133
130
|
}];
|
|
134
131
|
const { code } = transform(source, {
|
|
135
132
|
filename: ctx.resourcePath,
|
|
136
|
-
presets:
|
|
133
|
+
presets: jsxPreset ? [jsxPreset, defaultPresets] : [defaultPresets]
|
|
137
134
|
});
|
|
138
135
|
return {
|
|
139
136
|
type: LoaderType.ESModule,
|
|
140
137
|
content: code || "",
|
|
141
138
|
dependencies,
|
|
142
|
-
externals
|
|
139
|
+
externals,
|
|
140
|
+
raw: source
|
|
143
141
|
};
|
|
144
142
|
}
|
|
145
143
|
};
|
|
@@ -166,8 +164,8 @@ function createLoaderContext(files) {
|
|
|
166
164
|
resolve: (src) => files[src] !== void 0 ? src : null
|
|
167
165
|
};
|
|
168
166
|
}
|
|
169
|
-
function parseHTML(html
|
|
170
|
-
const doc = parseDocument(html
|
|
167
|
+
function parseHTML(html) {
|
|
168
|
+
const doc = parseDocument(html);
|
|
171
169
|
const elements = [];
|
|
172
170
|
const scripts = DomUtils.getElementsByTagName("script", doc);
|
|
173
171
|
for (const script of scripts) {
|
|
@@ -222,7 +220,8 @@ function processESModule(path, files, outputs, visited = /* @__PURE__ */ new Set
|
|
|
222
220
|
path,
|
|
223
221
|
content: output.content,
|
|
224
222
|
dependencies: output.dependencies,
|
|
225
|
-
externals: output.externals
|
|
223
|
+
externals: output.externals,
|
|
224
|
+
raw: source
|
|
226
225
|
});
|
|
227
226
|
for (const depPath of Object.values(output.dependencies)) processESModule(depPath, files, outputs, visited);
|
|
228
227
|
}
|
|
@@ -284,7 +283,8 @@ function processModuleScript(el, entry, files, outputs, visited = /* @__PURE__ *
|
|
|
284
283
|
path: virtualPath,
|
|
285
284
|
content: output.content,
|
|
286
285
|
dependencies: output.dependencies,
|
|
287
|
-
externals: output.externals
|
|
286
|
+
externals: output.externals,
|
|
287
|
+
raw: el.content
|
|
288
288
|
});
|
|
289
289
|
for (const depPath of Object.values(output.dependencies)) processESModule(depPath, files, outputs, visited);
|
|
290
290
|
}
|
|
@@ -332,18 +332,20 @@ function processLinkElement(el, files, outputs, visited = /* @__PURE__ */ new Se
|
|
|
332
332
|
});
|
|
333
333
|
else if (files[el.href] !== void 0) processStylesheet(el.href, files, outputs, visited);
|
|
334
334
|
}
|
|
335
|
-
function analyze(
|
|
335
|
+
function analyze(files) {
|
|
336
336
|
const outputs = createOutputs();
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
337
|
+
for (const path of Object.keys(files)) {
|
|
338
|
+
if (!path.endsWith(".html")) continue;
|
|
339
|
+
const html = files[path];
|
|
340
|
+
const { elements, bodyContent } = parseHTML(html);
|
|
341
|
+
for (const el of elements) if (el.type === "script") processScriptElement(el, path, files, outputs);
|
|
342
|
+
else if (el.type === "style") processStyleElement(el, path, outputs);
|
|
343
|
+
else if (el.type === "link") processLinkElement(el, files, outputs);
|
|
344
|
+
if (bodyContent) getOutputArray(outputs, LoaderType.Asset).push({
|
|
345
|
+
path,
|
|
346
|
+
content: bodyContent
|
|
347
|
+
});
|
|
348
|
+
}
|
|
347
349
|
return outputs;
|
|
348
350
|
}
|
|
349
351
|
|
|
@@ -358,25 +360,28 @@ var Framework = class extends Framework$1 {
|
|
|
358
360
|
imports = {};
|
|
359
361
|
outputs = /* @__PURE__ */ new Map();
|
|
360
362
|
blobUrlMap = /* @__PURE__ */ new Map();
|
|
363
|
+
LITE_DEFAULT_ENTRY = "./index.html";
|
|
364
|
+
LITE_DEFAULT_SCRIPT = "./index.js";
|
|
365
|
+
LITE_DEFAULT_STYLE = "./index.css";
|
|
361
366
|
constructor(config) {
|
|
362
367
|
super();
|
|
363
368
|
this.config = config;
|
|
364
369
|
}
|
|
365
|
-
analyze(
|
|
366
|
-
const { enabled, htmlEntry =
|
|
367
|
-
if (enabled) this.outputs = analyze(
|
|
370
|
+
analyze(files) {
|
|
371
|
+
const { enabled, htmlEntry = this.LITE_DEFAULT_ENTRY } = this.config?.liteMode ?? {};
|
|
372
|
+
if (enabled && htmlEntry) this.outputs = analyze({
|
|
368
373
|
...files,
|
|
369
374
|
[htmlEntry]: this.wrapInLiteModeTemplate(files[htmlEntry] ?? "")
|
|
370
375
|
});
|
|
371
|
-
else this.outputs = analyze(
|
|
376
|
+
else this.outputs = analyze(files);
|
|
372
377
|
}
|
|
373
|
-
compile() {
|
|
378
|
+
compile(entry) {
|
|
374
379
|
const builder = this.createBuilder();
|
|
375
380
|
const assets = this.getOutput(LoaderType.Asset);
|
|
376
381
|
const styles = this.getOutput(LoaderType.Style);
|
|
377
382
|
const scripts = this.getOutput(LoaderType.Script);
|
|
378
383
|
const modules = this.getOutput(LoaderType.ESModule);
|
|
379
|
-
let htmlContent = assets.
|
|
384
|
+
let htmlContent = assets.find((a) => a.path === entry)?.content ?? "";
|
|
380
385
|
for (const style of styles) if (style.href) htmlContent += `<link${serializeAttributes(style.attributes)} rel="stylesheet" href="${style.href}">`;
|
|
381
386
|
else htmlContent += `<style${serializeAttributes(style.attributes)}>${style.content}</style>`;
|
|
382
387
|
for (const script of scripts) if (script.src) htmlContent += `<script${serializeAttributes(script.attributes)} src="${script.src}"><\/script>`;
|
|
@@ -393,7 +398,7 @@ var Framework = class extends Framework$1 {
|
|
|
393
398
|
}).done();
|
|
394
399
|
}
|
|
395
400
|
wrapInLiteModeTemplate(htmlFragment) {
|
|
396
|
-
const { scriptEntry =
|
|
401
|
+
const { scriptEntry = this.LITE_DEFAULT_SCRIPT, styleEntry = this.LITE_DEFAULT_STYLE } = this.config?.liteMode ?? {};
|
|
397
402
|
return `<!DOCTYPE html>
|
|
398
403
|
<html>
|
|
399
404
|
<head>
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ declare enum LoaderType {
|
|
|
23
23
|
ESModule = "esmodule",
|
|
24
24
|
Style = "style",
|
|
25
25
|
Script = "script",
|
|
26
|
-
Asset = "asset"
|
|
26
|
+
Asset = "asset"
|
|
27
27
|
}
|
|
28
28
|
interface BaseLoaderOutput<T extends LoaderType> {
|
|
29
29
|
type: T;
|
|
@@ -35,6 +35,7 @@ interface ESModuleLoaderOutput extends BaseLoaderOutput<LoaderType.ESModule> {
|
|
|
35
35
|
name: string;
|
|
36
36
|
imported: string[];
|
|
37
37
|
}[];
|
|
38
|
+
raw: string;
|
|
38
39
|
}
|
|
39
40
|
interface StyleLoaderOutput extends BaseLoaderOutput<LoaderType.Style> {
|
|
40
41
|
imports: string[];
|
|
@@ -59,8 +60,8 @@ declare abstract class Framework {
|
|
|
59
60
|
abstract readonly name: string;
|
|
60
61
|
abstract readonly imports: Record<string, string>;
|
|
61
62
|
abstract outputs: Outputs;
|
|
62
|
-
abstract analyze(
|
|
63
|
-
abstract compile(): string;
|
|
63
|
+
abstract analyze(files: Record<string, string>): void;
|
|
64
|
+
abstract compile(entry: string): string;
|
|
64
65
|
protected createBuilder(init?: string): RuntimeBuilder;
|
|
65
66
|
getOutput<T extends LoaderType>(type: T): Output<T>[];
|
|
66
67
|
}
|
package/dist/loaders.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ declare enum LoaderType {
|
|
|
3
3
|
ESModule = "esmodule",
|
|
4
4
|
Style = "style",
|
|
5
5
|
Script = "script",
|
|
6
|
-
Asset = "asset"
|
|
6
|
+
Asset = "asset"
|
|
7
7
|
}
|
|
8
8
|
interface BaseLoaderOutput<T extends LoaderType> {
|
|
9
9
|
type: T;
|
|
@@ -15,6 +15,7 @@ interface ESModuleLoaderOutput extends BaseLoaderOutput<LoaderType.ESModule> {
|
|
|
15
15
|
name: string;
|
|
16
16
|
imported: string[];
|
|
17
17
|
}[];
|
|
18
|
+
raw: string;
|
|
18
19
|
}
|
|
19
20
|
interface StyleLoaderOutput extends BaseLoaderOutput<LoaderType.Style> {
|
|
20
21
|
imports: string[];
|
|
@@ -62,11 +63,10 @@ interface ESLoaderOptions {
|
|
|
62
63
|
isTSX?: boolean;
|
|
63
64
|
}
|
|
64
65
|
declare class ESLoader implements Loader<LoaderType.ESModule> {
|
|
66
|
+
private options?;
|
|
65
67
|
readonly name = "es-loader";
|
|
66
68
|
readonly test: RegExp;
|
|
67
|
-
|
|
68
|
-
private isTSX;
|
|
69
|
-
constructor(options?: ESLoaderOptions);
|
|
69
|
+
constructor(options?: ESLoaderOptions | undefined);
|
|
70
70
|
transform(source: string, ctx: LoaderContext): ESModuleLoaderOutput;
|
|
71
71
|
}
|
|
72
72
|
//#endregion
|
package/dist/loaders.js
CHANGED
|
@@ -4,12 +4,12 @@ import DOMPurify from "dompurify";
|
|
|
4
4
|
import { marked } from "marked";
|
|
5
5
|
|
|
6
6
|
//#region src/loaders/types.ts
|
|
7
|
-
let LoaderType = /* @__PURE__ */ function(LoaderType
|
|
8
|
-
LoaderType
|
|
9
|
-
LoaderType
|
|
10
|
-
LoaderType
|
|
11
|
-
LoaderType
|
|
12
|
-
return LoaderType
|
|
7
|
+
let LoaderType = /* @__PURE__ */ function(LoaderType) {
|
|
8
|
+
LoaderType["ESModule"] = "esmodule";
|
|
9
|
+
LoaderType["Style"] = "style";
|
|
10
|
+
LoaderType["Script"] = "script";
|
|
11
|
+
LoaderType["Asset"] = "asset";
|
|
12
|
+
return LoaderType;
|
|
13
13
|
}({});
|
|
14
14
|
|
|
15
15
|
//#endregion
|
|
@@ -101,12 +101,8 @@ const buildExternalDeps = (imports, usedSources) => {
|
|
|
101
101
|
var ESLoader = class {
|
|
102
102
|
name = "es-loader";
|
|
103
103
|
test = /\.(tsx?|jsx?)$/;
|
|
104
|
-
jsxPreset;
|
|
105
|
-
isTSX;
|
|
106
104
|
constructor(options) {
|
|
107
|
-
|
|
108
|
-
this.jsxPreset = jsxPreset;
|
|
109
|
-
this.isTSX = isTSX;
|
|
105
|
+
this.options = options;
|
|
110
106
|
}
|
|
111
107
|
transform(source, ctx) {
|
|
112
108
|
const { imports, usedSources } = analyzeImports(parseCode(source));
|
|
@@ -116,28 +112,30 @@ var ESLoader = class {
|
|
|
116
112
|
if (imp.importKind === "type") continue;
|
|
117
113
|
const importPath = imp.source.value;
|
|
118
114
|
if (imp.specifiers.length === 0) {
|
|
119
|
-
const resolved
|
|
120
|
-
if (resolved
|
|
115
|
+
const resolved = ctx.resolve(importPath);
|
|
116
|
+
if (resolved) dependencies[importPath] = resolved;
|
|
121
117
|
continue;
|
|
122
118
|
}
|
|
123
119
|
if (!usedSources.has(importPath)) continue;
|
|
124
120
|
const resolved = ctx.resolve(importPath);
|
|
125
121
|
if (resolved) dependencies[importPath] = resolved;
|
|
126
122
|
}
|
|
123
|
+
const { jsxPreset, isTSX = false } = this.options || {};
|
|
127
124
|
const { typescript } = availablePresets;
|
|
128
125
|
const defaultPresets = [typescript, {
|
|
129
|
-
isTSX
|
|
126
|
+
isTSX,
|
|
130
127
|
allExtensions: true
|
|
131
128
|
}];
|
|
132
129
|
const { code } = transform(source, {
|
|
133
130
|
filename: ctx.resourcePath,
|
|
134
|
-
presets:
|
|
131
|
+
presets: jsxPreset ? [jsxPreset, defaultPresets] : [defaultPresets]
|
|
135
132
|
});
|
|
136
133
|
return {
|
|
137
134
|
type: LoaderType.ESModule,
|
|
138
135
|
content: code || "",
|
|
139
136
|
dependencies,
|
|
140
|
-
externals
|
|
137
|
+
externals,
|
|
138
|
+
raw: source
|
|
141
139
|
};
|
|
142
140
|
}
|
|
143
141
|
};
|
|
@@ -152,7 +150,8 @@ var JSONLoader = class {
|
|
|
152
150
|
type: LoaderType.ESModule,
|
|
153
151
|
content: `export default ${source};`,
|
|
154
152
|
dependencies: {},
|
|
155
|
-
externals: []
|
|
153
|
+
externals: [],
|
|
154
|
+
raw: source
|
|
156
155
|
};
|
|
157
156
|
}
|
|
158
157
|
};
|
package/dist/markdown.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ declare enum LoaderType {
|
|
|
6
6
|
ESModule = "esmodule",
|
|
7
7
|
Style = "style",
|
|
8
8
|
Script = "script",
|
|
9
|
-
Asset = "asset"
|
|
9
|
+
Asset = "asset"
|
|
10
10
|
}
|
|
11
11
|
interface BaseLoaderOutput<T extends LoaderType> {
|
|
12
12
|
type: T;
|
|
@@ -18,6 +18,7 @@ interface ESModuleLoaderOutput extends BaseLoaderOutput<LoaderType.ESModule> {
|
|
|
18
18
|
name: string;
|
|
19
19
|
imported: string[];
|
|
20
20
|
}[];
|
|
21
|
+
raw: string;
|
|
21
22
|
}
|
|
22
23
|
interface StyleLoaderOutput extends BaseLoaderOutput<LoaderType.Style> {
|
|
23
24
|
imports: string[];
|
|
@@ -44,8 +45,8 @@ declare class Framework extends Framework$1 {
|
|
|
44
45
|
readonly name = "markdown";
|
|
45
46
|
readonly imports: {};
|
|
46
47
|
outputs: Outputs;
|
|
47
|
-
analyze(
|
|
48
|
-
compile(): any;
|
|
48
|
+
analyze(files: Record<string, string>): void;
|
|
49
|
+
compile(entry: string): any;
|
|
49
50
|
}
|
|
50
51
|
declare const markdown: Framework;
|
|
51
52
|
//#endregion
|
package/dist/markdown.js
CHANGED
|
@@ -3,12 +3,12 @@ import DOMPurify from "dompurify";
|
|
|
3
3
|
import { marked } from "marked";
|
|
4
4
|
|
|
5
5
|
//#region src/loaders/types.ts
|
|
6
|
-
let LoaderType = /* @__PURE__ */ function(LoaderType
|
|
7
|
-
LoaderType
|
|
8
|
-
LoaderType
|
|
9
|
-
LoaderType
|
|
10
|
-
LoaderType
|
|
11
|
-
return LoaderType
|
|
6
|
+
let LoaderType = /* @__PURE__ */ function(LoaderType) {
|
|
7
|
+
LoaderType["ESModule"] = "esmodule";
|
|
8
|
+
LoaderType["Style"] = "style";
|
|
9
|
+
LoaderType["Script"] = "script";
|
|
10
|
+
LoaderType["Asset"] = "asset";
|
|
11
|
+
return LoaderType;
|
|
12
12
|
}({});
|
|
13
13
|
|
|
14
14
|
//#endregion
|
|
@@ -45,13 +45,13 @@ function processFile(path, files, outputs = /* @__PURE__ */ new Map(), visited =
|
|
|
45
45
|
};
|
|
46
46
|
outputs.get(output.type).push(result);
|
|
47
47
|
}
|
|
48
|
-
function analyze(
|
|
48
|
+
function analyze(files) {
|
|
49
49
|
const outputs = /* @__PURE__ */ new Map();
|
|
50
50
|
outputs.set(LoaderType.ESModule, []);
|
|
51
51
|
outputs.set(LoaderType.Style, []);
|
|
52
52
|
outputs.set(LoaderType.Script, []);
|
|
53
53
|
outputs.set(LoaderType.Asset, []);
|
|
54
|
-
processFile(
|
|
54
|
+
for (const path of Object.keys(files)) processFile(path, files, outputs);
|
|
55
55
|
return outputs;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -61,12 +61,12 @@ var Framework = class extends Framework$1 {
|
|
|
61
61
|
name = "markdown";
|
|
62
62
|
imports = {};
|
|
63
63
|
outputs = /* @__PURE__ */ new Map();
|
|
64
|
-
analyze(
|
|
65
|
-
this.outputs = analyze(
|
|
64
|
+
analyze(files) {
|
|
65
|
+
this.outputs = analyze(files);
|
|
66
66
|
}
|
|
67
|
-
compile() {
|
|
68
|
-
const
|
|
69
|
-
return this.createBuilder().setHTML(JSON.stringify(
|
|
67
|
+
compile(entry) {
|
|
68
|
+
const entryAsset = this.getOutput(LoaderType.Asset).find((a) => a.path === entry);
|
|
69
|
+
return this.createBuilder().setHTML(JSON.stringify(entryAsset?.content ?? "")).done();
|
|
70
70
|
}
|
|
71
71
|
};
|
|
72
72
|
const markdown = new Framework();
|
package/dist/react.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ declare enum LoaderType {
|
|
|
6
6
|
ESModule = "esmodule",
|
|
7
7
|
Style = "style",
|
|
8
8
|
Script = "script",
|
|
9
|
-
Asset = "asset"
|
|
9
|
+
Asset = "asset"
|
|
10
10
|
}
|
|
11
11
|
interface BaseLoaderOutput<T extends LoaderType> {
|
|
12
12
|
type: T;
|
|
@@ -18,6 +18,7 @@ interface ESModuleLoaderOutput extends BaseLoaderOutput<LoaderType.ESModule> {
|
|
|
18
18
|
name: string;
|
|
19
19
|
imported: string[];
|
|
20
20
|
}[];
|
|
21
|
+
raw: string;
|
|
21
22
|
}
|
|
22
23
|
interface StyleLoaderOutput extends BaseLoaderOutput<LoaderType.Style> {
|
|
23
24
|
imports: string[];
|
|
@@ -49,8 +50,8 @@ declare class Framework extends Framework$1 {
|
|
|
49
50
|
};
|
|
50
51
|
outputs: Outputs;
|
|
51
52
|
private blobUrlMap;
|
|
52
|
-
analyze(
|
|
53
|
-
compile(): any;
|
|
53
|
+
analyze(files: Record<string, string>): void;
|
|
54
|
+
compile(entry: string): any;
|
|
54
55
|
private transformModulesToBlob;
|
|
55
56
|
private transformCodeWithBlobUrls;
|
|
56
57
|
}
|
package/dist/react.js
CHANGED
|
@@ -6,12 +6,12 @@ import DOMPurify from "dompurify";
|
|
|
6
6
|
import { marked } from "marked";
|
|
7
7
|
|
|
8
8
|
//#region src/loaders/types.ts
|
|
9
|
-
let LoaderType = /* @__PURE__ */ function(LoaderType
|
|
10
|
-
LoaderType
|
|
11
|
-
LoaderType
|
|
12
|
-
LoaderType
|
|
13
|
-
LoaderType
|
|
14
|
-
return LoaderType
|
|
9
|
+
let LoaderType = /* @__PURE__ */ function(LoaderType) {
|
|
10
|
+
LoaderType["ESModule"] = "esmodule";
|
|
11
|
+
LoaderType["Style"] = "style";
|
|
12
|
+
LoaderType["Script"] = "script";
|
|
13
|
+
LoaderType["Asset"] = "asset";
|
|
14
|
+
return LoaderType;
|
|
15
15
|
}({});
|
|
16
16
|
|
|
17
17
|
//#endregion
|
|
@@ -103,12 +103,8 @@ const buildExternalDeps = (imports, usedSources) => {
|
|
|
103
103
|
var ESLoader = class {
|
|
104
104
|
name = "es-loader";
|
|
105
105
|
test = /\.(tsx?|jsx?)$/;
|
|
106
|
-
jsxPreset;
|
|
107
|
-
isTSX;
|
|
108
106
|
constructor(options) {
|
|
109
|
-
|
|
110
|
-
this.jsxPreset = jsxPreset;
|
|
111
|
-
this.isTSX = isTSX;
|
|
107
|
+
this.options = options;
|
|
112
108
|
}
|
|
113
109
|
transform(source, ctx) {
|
|
114
110
|
const { imports, usedSources } = analyzeImports(parseCode(source));
|
|
@@ -118,28 +114,30 @@ var ESLoader = class {
|
|
|
118
114
|
if (imp.importKind === "type") continue;
|
|
119
115
|
const importPath = imp.source.value;
|
|
120
116
|
if (imp.specifiers.length === 0) {
|
|
121
|
-
const resolved
|
|
122
|
-
if (resolved
|
|
117
|
+
const resolved = ctx.resolve(importPath);
|
|
118
|
+
if (resolved) dependencies[importPath] = resolved;
|
|
123
119
|
continue;
|
|
124
120
|
}
|
|
125
121
|
if (!usedSources.has(importPath)) continue;
|
|
126
122
|
const resolved = ctx.resolve(importPath);
|
|
127
123
|
if (resolved) dependencies[importPath] = resolved;
|
|
128
124
|
}
|
|
125
|
+
const { jsxPreset, isTSX = false } = this.options || {};
|
|
129
126
|
const { typescript } = availablePresets;
|
|
130
127
|
const defaultPresets = [typescript, {
|
|
131
|
-
isTSX
|
|
128
|
+
isTSX,
|
|
132
129
|
allExtensions: true
|
|
133
130
|
}];
|
|
134
131
|
const { code } = transform(source, {
|
|
135
132
|
filename: ctx.resourcePath,
|
|
136
|
-
presets:
|
|
133
|
+
presets: jsxPreset ? [jsxPreset, defaultPresets] : [defaultPresets]
|
|
137
134
|
});
|
|
138
135
|
return {
|
|
139
136
|
type: LoaderType.ESModule,
|
|
140
137
|
content: code || "",
|
|
141
138
|
dependencies,
|
|
142
|
-
externals
|
|
139
|
+
externals,
|
|
140
|
+
raw: source
|
|
143
141
|
};
|
|
144
142
|
}
|
|
145
143
|
};
|
|
@@ -154,7 +152,8 @@ var JSONLoader = class {
|
|
|
154
152
|
type: LoaderType.ESModule,
|
|
155
153
|
content: `export default ${source};`,
|
|
156
154
|
dependencies: {},
|
|
157
|
-
externals: []
|
|
155
|
+
externals: [],
|
|
156
|
+
raw: source
|
|
158
157
|
};
|
|
159
158
|
}
|
|
160
159
|
};
|
|
@@ -233,13 +232,14 @@ function processFile(path, files, outputs, visited) {
|
|
|
233
232
|
switch (output.type) {
|
|
234
233
|
case LoaderType.ESModule: {
|
|
235
234
|
const { content, dependencies, externals } = output;
|
|
235
|
+
for (const depPath of Object.values(dependencies)) processFile(depPath, files, outputs, visited);
|
|
236
236
|
getOutputList(outputs, LoaderType.ESModule).push({
|
|
237
237
|
path,
|
|
238
238
|
content,
|
|
239
239
|
dependencies,
|
|
240
|
-
externals
|
|
240
|
+
externals,
|
|
241
|
+
raw: source
|
|
241
242
|
});
|
|
242
|
-
for (const depPath of Object.values(dependencies)) processFile(depPath, files, outputs, visited);
|
|
243
243
|
break;
|
|
244
244
|
}
|
|
245
245
|
case LoaderType.Style: {
|
|
@@ -262,14 +262,16 @@ export default function MarkdownContent() {
|
|
|
262
262
|
return _jsx('div', { dangerouslySetInnerHTML: { __html: ${JSON.stringify(content)} } });
|
|
263
263
|
}`,
|
|
264
264
|
dependencies: {},
|
|
265
|
-
externals: []
|
|
265
|
+
externals: [],
|
|
266
|
+
raw: content
|
|
266
267
|
});
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
270
|
}
|
|
270
|
-
function analyze(
|
|
271
|
+
function analyze(files) {
|
|
271
272
|
const outputs = createOutputsMap();
|
|
272
|
-
|
|
273
|
+
const visited = /* @__PURE__ */ new Set();
|
|
274
|
+
for (const path of Object.keys(files)) if (matchLoader(path)) processFile(path, files, outputs, visited);
|
|
273
275
|
return outputs;
|
|
274
276
|
}
|
|
275
277
|
|
|
@@ -278,17 +280,19 @@ function analyze(entry, files) {
|
|
|
278
280
|
var Framework = class extends Framework$1 {
|
|
279
281
|
name = "react";
|
|
280
282
|
imports = {
|
|
281
|
-
react: "https://esm.sh/react
|
|
282
|
-
"react/jsx-runtime": "https://esm.sh/react
|
|
283
|
-
"react-dom/client": "https://esm.sh/react-dom
|
|
283
|
+
react: "https://esm.sh/react",
|
|
284
|
+
"react/jsx-runtime": "https://esm.sh/react/jsx-runtime",
|
|
285
|
+
"react-dom/client": "https://esm.sh/react-dom/client"
|
|
284
286
|
};
|
|
285
287
|
outputs = /* @__PURE__ */ new Map();
|
|
286
288
|
blobUrlMap = /* @__PURE__ */ new Map();
|
|
287
|
-
analyze(
|
|
288
|
-
this.outputs = analyze(
|
|
289
|
+
analyze(files) {
|
|
290
|
+
this.outputs = analyze(files);
|
|
289
291
|
}
|
|
290
|
-
compile() {
|
|
291
|
-
const
|
|
292
|
+
compile(entry) {
|
|
293
|
+
const modules = this.getOutput(LoaderType.ESModule);
|
|
294
|
+
if (!modules.find((m) => m.path === entry)) throw new Error(`Entry module not found: ${entry}`);
|
|
295
|
+
const transformed = this.transformModulesToBlob(entry, modules);
|
|
292
296
|
const builder = this.createBuilder(transformed);
|
|
293
297
|
const ast = parse(transformed, {
|
|
294
298
|
sourceType: "module",
|
|
@@ -323,16 +327,29 @@ var Framework = class extends Framework$1 {
|
|
|
323
327
|
window.__root__.render(${name ? `jsx(${name}, {})` : "null"});`);
|
|
324
328
|
return builder.toString();
|
|
325
329
|
}
|
|
326
|
-
transformModulesToBlob(modules) {
|
|
330
|
+
transformModulesToBlob(entry, modules) {
|
|
331
|
+
const moduleMap = new Map(modules.map((m) => [m.path, m]));
|
|
332
|
+
const orderedModules = [];
|
|
333
|
+
const visited = /* @__PURE__ */ new Set();
|
|
334
|
+
const visit = (path) => {
|
|
335
|
+
if (visited.has(path)) return;
|
|
336
|
+
visited.add(path);
|
|
337
|
+
const mod = moduleMap.get(path);
|
|
338
|
+
if (!mod) return;
|
|
339
|
+
for (const depPath of Object.values(mod.dependencies)) visit(depPath);
|
|
340
|
+
orderedModules.push(mod);
|
|
341
|
+
};
|
|
342
|
+
visit(entry);
|
|
327
343
|
let entryCode = "";
|
|
328
|
-
|
|
344
|
+
for (let i = 0; i < orderedModules.length; i++) {
|
|
345
|
+
const mod = orderedModules[i];
|
|
329
346
|
const code = this.transformCodeWithBlobUrls(mod);
|
|
330
|
-
if (
|
|
347
|
+
if (i === orderedModules.length - 1) entryCode = code;
|
|
331
348
|
else {
|
|
332
349
|
const blob = new Blob([code], { type: "application/javascript" });
|
|
333
350
|
this.blobUrlMap.set(mod.path, URL.createObjectURL(blob));
|
|
334
351
|
}
|
|
335
|
-
}
|
|
352
|
+
}
|
|
336
353
|
return entryCode;
|
|
337
354
|
}
|
|
338
355
|
transformCodeWithBlobUrls(mod) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codespark/framework",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Framework registration API for codespark ecosystem",
|
|
6
6
|
"keywords": [
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "tsdown",
|
|
28
|
-
"test": "vitest run"
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"release": "pnpm build && npm publish --access public"
|
|
29
30
|
},
|
|
30
31
|
"author": "TonyL1u",
|
|
31
32
|
"license": "MIT",
|
|
@@ -50,6 +51,6 @@
|
|
|
50
51
|
"@types/babel__standalone": "^7.1.9",
|
|
51
52
|
"@types/node": "^22.19.2",
|
|
52
53
|
"domhandler": "^5.0.3",
|
|
53
|
-
"tsdown": "^0.
|
|
54
|
+
"tsdown": "^0.20.3"
|
|
54
55
|
}
|
|
55
56
|
}
|