round-core 0.0.3 → 0.0.4
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/.github/workflows/benchmarks.yml +44 -0
- package/README.md +78 -48
- package/benchmarks/apps/react/index.html +9 -0
- package/benchmarks/apps/react/main.jsx +25 -0
- package/benchmarks/apps/react/vite.config.js +12 -0
- package/benchmarks/apps/round/index.html +11 -0
- package/benchmarks/apps/round/main.jsx +22 -0
- package/benchmarks/apps/round/vite.config.js +15 -0
- package/benchmarks/bun.lock +497 -0
- package/benchmarks/dist-bench/react/assets/index-9KGqIPOU.js +8 -0
- package/benchmarks/dist-bench/react/index.html +10 -0
- package/benchmarks/dist-bench/round/assets/index-CBBIRhox.js +52 -0
- package/benchmarks/dist-bench/round/index.html +8 -0
- package/benchmarks/package.json +22 -0
- package/benchmarks/scripts/measure-build.js +64 -0
- package/benchmarks/tests/runtime.bench.js +51 -0
- package/benchmarks/vitest.config.js +8 -0
- package/dist/cli.js +582 -0
- package/dist/index.js +1975 -0
- package/dist/vite-plugin.js +736 -0
- package/package.json +14 -6
- package/src/cli.js +10 -3
- package/src/compiler/vite-plugin.js +5 -1
- package/src/runtime/dom.js +23 -9
- package/src/runtime/lifecycle.js +1 -1
- package/vite.config.build.js +47 -0
package/package.json
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "round-core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "A lightweight frontend framework for SPA with signals and fine grained reactivity",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./dist/index.js",
|
|
8
|
+
"./vite-plugin": "./dist/vite-plugin.js"
|
|
9
|
+
},
|
|
6
10
|
"type": "module",
|
|
7
11
|
"icon": "round.png",
|
|
8
12
|
"repository": {
|
|
9
13
|
"url": "https://github.com/ZtaMDev/RoundJS.git"
|
|
10
14
|
},
|
|
11
15
|
"bin": {
|
|
12
|
-
"round": "./
|
|
16
|
+
"round": "./dist/cli.js"
|
|
13
17
|
},
|
|
14
18
|
"scripts": {
|
|
15
|
-
"dev": "node ./cli.js dev --config ./test/main/round.config.json",
|
|
16
|
-
"build": "node ./cli.js build --config ./test/main/round.config.json",
|
|
17
|
-
"
|
|
19
|
+
"dev": "node ./src/cli.js dev --config ./test/main/round.config.json",
|
|
20
|
+
"build": "node ./src/cli.js build --config ./test/main/round.config.json",
|
|
21
|
+
"build:core": "vite build -c vite.config.build.js",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"bench": "bun run --cwd benchmarks bench",
|
|
24
|
+
"bench:build": "bun run --cwd benchmarks bench:build",
|
|
25
|
+
"bench:runtime": "bun run --cwd benchmarks bench:runtime"
|
|
18
26
|
},
|
|
19
27
|
"keywords": [
|
|
20
28
|
"framework",
|
package/src/cli.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import process from 'node:process';
|
|
@@ -6,6 +6,13 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
import { createServer, build as viteBuild, preview as vitePreview } from 'vite';
|
|
7
7
|
import RoundPlugin from './compiler/vite-plugin.js';
|
|
8
8
|
|
|
9
|
+
// Handle graceful shutdown
|
|
10
|
+
function onSignal() {
|
|
11
|
+
process.exit(0);
|
|
12
|
+
}
|
|
13
|
+
process.on('SIGINT', onSignal);
|
|
14
|
+
process.on('SIGTERM', onSignal);
|
|
15
|
+
|
|
9
16
|
function normalizePath(p) {
|
|
10
17
|
return p.replaceAll('\\', '/');
|
|
11
18
|
}
|
|
@@ -239,7 +246,7 @@ async function runInit({ name }) {
|
|
|
239
246
|
preview: 'round preview'
|
|
240
247
|
},
|
|
241
248
|
dependencies: {
|
|
242
|
-
'round-core': '^0.0.
|
|
249
|
+
'round-core': '^0.0.4'
|
|
243
250
|
},
|
|
244
251
|
devDependencies: {
|
|
245
252
|
vite: '^5.0.0'
|
|
@@ -272,7 +279,7 @@ async function runInit({ name }) {
|
|
|
272
279
|
|
|
273
280
|
writeFileIfMissing(viteConfigPath, [
|
|
274
281
|
"import { defineConfig } from 'vite';",
|
|
275
|
-
"import RoundPlugin from 'round-core/
|
|
282
|
+
"import RoundPlugin from 'round-core/vite-plugin';",
|
|
276
283
|
'',
|
|
277
284
|
'export default defineConfig({',
|
|
278
285
|
" plugins: [RoundPlugin({ configPath: './round.config.json' })],",
|
|
@@ -131,6 +131,9 @@ export default function RoundPlugin(pluginOptions = {}) {
|
|
|
131
131
|
const trailingSlash = config?.routing?.trailingSlash;
|
|
132
132
|
state.routingTrailingSlash = trailingSlash !== undefined ? Boolean(trailingSlash) : true;
|
|
133
133
|
|
|
134
|
+
const customTags = config?.htmlTags;
|
|
135
|
+
state.customTags = Array.isArray(customTags) ? customTags : [];
|
|
136
|
+
|
|
134
137
|
const entryRel = config?.entry;
|
|
135
138
|
state.entryAbs = entryRel ? resolveMaybeRelative(configDir, entryRel) : null;
|
|
136
139
|
|
|
@@ -303,7 +306,8 @@ export default function RoundPlugin(pluginOptions = {}) {
|
|
|
303
306
|
|
|
304
307
|
return {
|
|
305
308
|
define: {
|
|
306
|
-
__ROUND_ROUTING_TRAILING_SLASH__: JSON.stringify(state.routingTrailingSlash)
|
|
309
|
+
__ROUND_ROUTING_TRAILING_SLASH__: JSON.stringify(state.routingTrailingSlash),
|
|
310
|
+
__ROUND_CUSTOM_TAGS__: JSON.stringify(state.customTags ?? [])
|
|
307
311
|
},
|
|
308
312
|
esbuild: {
|
|
309
313
|
include: /\.(round|js|jsx|ts|tsx)$/,
|
package/src/runtime/dom.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { effect, untrack } from './signals.js';
|
|
2
|
-
import {
|
|
2
|
+
import { runInLifecycle, createComponentInstance, mountComponent, initLifecycleRoot } from './lifecycle.js';
|
|
3
3
|
import { reportErrorSafe } from './error-reporter.js';
|
|
4
4
|
import { captureContext, runInContext, readContext } from './context.js';
|
|
5
5
|
import { SuspenseContext } from './suspense.js';
|
|
@@ -76,14 +76,13 @@ export function createElement(tag, props = {}, ...children) {
|
|
|
76
76
|
|
|
77
77
|
if (typeof tag === 'string') {
|
|
78
78
|
const isCustomElement = tag.includes('-');
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (!isCustomElement && !isStandard && /^[a-z]/.test(tag)) {
|
|
79
|
+
|
|
80
|
+
const isStandard = /^(a|abbr|address|area|article|aside|audio|b|base|bdi|bdo|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|data|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|main|map|mark|meta|meter|nav|noscript|object|ol|optgroup|option|output|p|param|picture|pre|progress|q|rp|rt|ruby|s|samp|script|search|section|select|slot|small|source|span|strong|style|sub|summary|sup|svg|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|u|ul|var|video|wbr|menu|animate|animateMotion|animateTransform|circle|clipPath|defs|desc|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|foreignObject|g|image|line|linearGradient|marker|mask|metadata|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|stop|switch|symbol|text|textPath|tspan|use|view)$/.test(tag);
|
|
81
|
+
|
|
82
|
+
// __ROUND_CUSTOM_TAGS__ is injected by the vite plugin from round.config.json
|
|
83
|
+
const isCustomConfigured = typeof __ROUND_CUSTOM_TAGS__ !== 'undefined' && __ROUND_CUSTOM_TAGS__.includes(tag);
|
|
84
|
+
|
|
85
|
+
if (!isCustomElement && !isStandard && !isCustomConfigured && /^[a-z]/.test(tag)) {
|
|
87
86
|
throw new Error(`Component names must start with an uppercase letter: <${tag} />`);
|
|
88
87
|
}
|
|
89
88
|
}
|
|
@@ -273,6 +272,21 @@ export function createElement(tag, props = {}, ...children) {
|
|
|
273
272
|
return;
|
|
274
273
|
}
|
|
275
274
|
|
|
275
|
+
if (key === 'classList') {
|
|
276
|
+
if (value && typeof value === 'object') {
|
|
277
|
+
Object.entries(value).forEach(([className, condition]) => {
|
|
278
|
+
if (typeof condition === 'function') {
|
|
279
|
+
effect(() => {
|
|
280
|
+
element.classList.toggle(className, !!condition());
|
|
281
|
+
}, { onLoad: false });
|
|
282
|
+
} else {
|
|
283
|
+
element.classList.toggle(className, !!condition);
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
|
|
276
290
|
if (key === 'className') element.className = value;
|
|
277
291
|
else if (key === 'value') element.value = value;
|
|
278
292
|
else if (key === 'checked') element.checked = Boolean(value);
|
package/src/runtime/lifecycle.js
CHANGED
|
@@ -6,7 +6,7 @@ export function getCurrentComponent() {
|
|
|
6
6
|
return componentStack[componentStack.length - 1];
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export function
|
|
9
|
+
export function runInLifecycle(componentInstance, fn) {
|
|
10
10
|
componentStack.push(componentInstance);
|
|
11
11
|
try {
|
|
12
12
|
return fn();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
|
|
5
|
+
// Custom plugin to move .d.ts files or raw assets if needed,
|
|
6
|
+
// for now we just handle JS bundling.
|
|
7
|
+
|
|
8
|
+
// Custom plugin to move .d.ts files or raw assets if needed,
|
|
9
|
+
// for now we just handle JS bundling.
|
|
10
|
+
|
|
11
|
+
export default defineConfig({
|
|
12
|
+
build: {
|
|
13
|
+
// Target modern environments
|
|
14
|
+
target: 'es2022',
|
|
15
|
+
outDir: 'dist',
|
|
16
|
+
emptyOutDir: true,
|
|
17
|
+
minify: false, // User can enable if they want extreme minification, but for a lib readable code is nice.
|
|
18
|
+
// Wait, user asked for "extremo rapido y liviano" (extremely fast and light).
|
|
19
|
+
// So I SHOULD minify.
|
|
20
|
+
lib: {
|
|
21
|
+
entry: {
|
|
22
|
+
index: path.resolve(__dirname, 'src/index.js'),
|
|
23
|
+
cli: path.resolve(__dirname, 'src/cli.js'),
|
|
24
|
+
// We expose the plugin separately so users can import it in their vite.config.js
|
|
25
|
+
'vite-plugin': path.resolve(__dirname, 'src/compiler/vite-plugin.js')
|
|
26
|
+
},
|
|
27
|
+
formats: ['es'] // ESM only is fine for modern "type": "module" package
|
|
28
|
+
},
|
|
29
|
+
rollupOptions: {
|
|
30
|
+
// Externalize dependencies so they aren't bundled into the library
|
|
31
|
+
external: [
|
|
32
|
+
'vite',
|
|
33
|
+
'marked',
|
|
34
|
+
'node:fs', 'node:path', 'node:process', 'node:url', 'node:vm', 'node:util',
|
|
35
|
+
'fs', 'path', 'process', 'url', 'vm', 'util'
|
|
36
|
+
],
|
|
37
|
+
output: {
|
|
38
|
+
banner: (chunk) => {
|
|
39
|
+
if (chunk.name === 'cli' || chunk.fileName === 'cli.js') {
|
|
40
|
+
return '#!/usr/bin/env node';
|
|
41
|
+
}
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|