vaderjs 2.3.4 → 2.3.6
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/config/index.ts +4 -1
- package/index.ts +66 -41
- package/main.js +108 -53
- package/package.json +1 -1
- package/plugins/index.ts +10 -1
package/config/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
type Config = {
|
|
1
|
+
export type Config = {
|
|
2
2
|
port: number,
|
|
3
3
|
host?: string,
|
|
4
|
+
plugin_config?: {
|
|
5
|
+
[key: string]: any
|
|
6
|
+
},
|
|
4
7
|
plugins?: any[],
|
|
5
8
|
generateTypes?: boolean,
|
|
6
9
|
host_provider?: 'vercel' | 'netlify' | 'aws' | 'gcp' | 'azure' | 'heroku' | 'custom' | 'apache' | 'none',
|
package/index.ts
CHANGED
|
@@ -346,29 +346,38 @@ function performUnitOfWork(fiber: Fiber): Fiber | null {
|
|
|
346
346
|
* Updates a function component fiber.
|
|
347
347
|
* @param {Fiber} fiber - The function component fiber to update.
|
|
348
348
|
*/
|
|
349
|
-
|
|
349
|
+
function updateFunctionComponent(fiber: Fiber) {
|
|
350
350
|
wipFiber = fiber;
|
|
351
351
|
hookIndex = 0;
|
|
352
352
|
fiber.hooks = fiber.alternate?.hooks || [];
|
|
353
353
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const children = [(fiber.type as Function)(fiber.props)]
|
|
357
|
-
.flat()
|
|
358
|
-
.filter(child => child != null && typeof child !== 'boolean')
|
|
359
|
-
.map(child => typeof child === 'object' ? child : createTextElement(child));
|
|
354
|
+
const rawChildren = (fiber.type as Function)(fiber.props);
|
|
355
|
+
const children = normalizeChildren(rawChildren, fiber);
|
|
360
356
|
|
|
361
357
|
reconcileChildren(fiber, children);
|
|
362
358
|
}
|
|
359
|
+
function normalizeChildren(children: any, parentFiber: Fiber): VNode[] {
|
|
360
|
+
if (!children) return [];
|
|
361
|
+
let arr = Array.isArray(children) ? children : [children];
|
|
362
|
+
|
|
363
|
+
return arr.flatMap((child, index) => {
|
|
364
|
+
if (child == null || typeof child === "boolean") return [];
|
|
365
|
+
if (typeof child === "string" || typeof child === "number") return [createTextElement(String(child))];
|
|
366
|
+
|
|
367
|
+
// Ensure every child has a stable key
|
|
368
|
+
const key = child.key ?? child.props?.id ?? `${parentFiber.key ?? "root"}-${index}`;
|
|
369
|
+
return [{ ...child, key }];
|
|
370
|
+
});
|
|
371
|
+
}
|
|
363
372
|
/**
|
|
364
373
|
* Updates a host component fiber (DOM element).
|
|
365
374
|
* @param {Fiber} fiber - The host component fiber to update.
|
|
366
375
|
*/
|
|
367
376
|
function updateHostComponent(fiber: Fiber): void {
|
|
368
|
-
if (!fiber.dom)
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
reconcileChildren(fiber,
|
|
377
|
+
if (!fiber.dom) fiber.dom = createDom(fiber);
|
|
378
|
+
|
|
379
|
+
const children = normalizeChildren(fiber.props.children, fiber);
|
|
380
|
+
reconcileChildren(fiber, children);
|
|
372
381
|
}
|
|
373
382
|
|
|
374
383
|
/**
|
|
@@ -376,12 +385,11 @@ function updateHostComponent(fiber: Fiber): void {
|
|
|
376
385
|
* @param {Fiber} wipFiber - The work-in-progress fiber.
|
|
377
386
|
* @param {VNode[]} elements - The new child elements.
|
|
378
387
|
*/
|
|
379
|
-
|
|
388
|
+
function reconcileChildren(wipFiber: Fiber, elements: VNode[]) {
|
|
380
389
|
let index = 0;
|
|
381
390
|
let oldFiber = wipFiber.alternate?.child;
|
|
382
391
|
let prevSibling: Fiber | null = null;
|
|
383
|
-
|
|
384
|
-
// Create map of existing fibers by key
|
|
392
|
+
|
|
385
393
|
const existingFibers = new Map<string | number | null, Fiber>();
|
|
386
394
|
while (oldFiber) {
|
|
387
395
|
const key = oldFiber.key ?? index;
|
|
@@ -393,23 +401,21 @@ function updateHostComponent(fiber: Fiber): void {
|
|
|
393
401
|
index = 0;
|
|
394
402
|
for (; index < elements.length; index++) {
|
|
395
403
|
const element = elements[index];
|
|
396
|
-
const key = element
|
|
404
|
+
const key = element.key ?? index;
|
|
397
405
|
const oldFiber = existingFibers.get(key);
|
|
398
|
-
|
|
406
|
+
|
|
399
407
|
const sameType = oldFiber && element && element.type === oldFiber.type;
|
|
400
408
|
let newFiber: Fiber | null = null;
|
|
401
409
|
|
|
402
410
|
if (sameType) {
|
|
403
|
-
// Reuse
|
|
411
|
+
// Reuse old fiber for same type + key
|
|
404
412
|
newFiber = {
|
|
405
|
-
|
|
413
|
+
...oldFiber,
|
|
406
414
|
props: element.props,
|
|
407
|
-
dom: oldFiber.dom,
|
|
408
415
|
parent: wipFiber,
|
|
409
416
|
alternate: oldFiber,
|
|
410
417
|
effectTag: "UPDATE",
|
|
411
|
-
|
|
412
|
-
key
|
|
418
|
+
_needsUpdate: false,
|
|
413
419
|
};
|
|
414
420
|
existingFibers.delete(key);
|
|
415
421
|
} else if (element) {
|
|
@@ -421,7 +427,8 @@ function updateHostComponent(fiber: Fiber): void {
|
|
|
421
427
|
parent: wipFiber,
|
|
422
428
|
alternate: null,
|
|
423
429
|
effectTag: "PLACEMENT",
|
|
424
|
-
key
|
|
430
|
+
key,
|
|
431
|
+
_needsUpdate: true,
|
|
425
432
|
};
|
|
426
433
|
}
|
|
427
434
|
|
|
@@ -436,9 +443,7 @@ function updateHostComponent(fiber: Fiber): void {
|
|
|
436
443
|
prevSibling.sibling = newFiber;
|
|
437
444
|
}
|
|
438
445
|
|
|
439
|
-
if (newFiber)
|
|
440
|
-
prevSibling = newFiber;
|
|
441
|
-
}
|
|
446
|
+
if (newFiber) prevSibling = newFiber;
|
|
442
447
|
}
|
|
443
448
|
|
|
444
449
|
// Mark remaining old fibers for deletion
|
|
@@ -455,23 +460,17 @@ function updateHostComponent(fiber: Fiber): void {
|
|
|
455
460
|
* @param {...any} children - The element's children.
|
|
456
461
|
* @returns {VNode} The created virtual DOM element.
|
|
457
462
|
*/
|
|
458
|
-
export function createElement(
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
)
|
|
463
|
+
export function createElement(type: string | Function, props?: any, ...children: any[]): VNode {
|
|
464
|
+
const rawChildren = children.flat().filter(c => c != null && typeof c !== "boolean");
|
|
465
|
+
const normalizedChildren = rawChildren.map((child, i) => {
|
|
466
|
+
if (typeof child === "object") return child;
|
|
467
|
+
return createTextElement(String(child));
|
|
468
|
+
});
|
|
469
|
+
|
|
463
470
|
return {
|
|
464
471
|
type,
|
|
465
|
-
props: {
|
|
466
|
-
|
|
467
|
-
children: children
|
|
468
|
-
.flat()
|
|
469
|
-
.filter(child => child != null && typeof child !== "boolean")
|
|
470
|
-
.map(child =>
|
|
471
|
-
typeof child === "object" ? child : createTextElement(child)
|
|
472
|
-
),
|
|
473
|
-
},
|
|
474
|
-
key: props?.key ?? null,
|
|
472
|
+
props: { ...props, children: normalizedChildren },
|
|
473
|
+
key: props?.key ?? props?.id ?? null,
|
|
475
474
|
};
|
|
476
475
|
}
|
|
477
476
|
|
|
@@ -598,10 +597,36 @@ export function Switch({ children }: { children: VNode[] }): VNode | null {
|
|
|
598
597
|
export function Match({ when, children }: { when: boolean, children: VNode[] }): VNode | null {
|
|
599
598
|
return when ? children : null;
|
|
600
599
|
}
|
|
601
|
-
|
|
600
|
+
/**
|
|
601
|
+
* Wraps a functional component into a VNode for Vader.js rendering.
|
|
602
|
+
* @param {Function} fn - The function component to wrap.
|
|
603
|
+
* @returns {Function} A function that creates a VNode when called with props.
|
|
604
|
+
*/
|
|
605
|
+
export function component<P extends object>(
|
|
606
|
+
fn: (props: P) => VNode | VNode[]
|
|
607
|
+
): (props: P & { key?: string | number }) => VNode {
|
|
608
|
+
return (props: P & { key?: string | number }) => {
|
|
609
|
+
return createElement(fn, props);
|
|
610
|
+
};
|
|
611
|
+
}
|
|
602
612
|
export function Show({ when, children }: { when: boolean, children: VNode[] }): VNode | null {
|
|
603
613
|
return when ? children : null;
|
|
604
614
|
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* For TypeScript to recognize your JSX factory,
|
|
618
|
+
* you often need the global namespace declaration as well:
|
|
619
|
+
*/
|
|
620
|
+
declare global {
|
|
621
|
+
namespace JSX {
|
|
622
|
+
interface IntrinsicElements {
|
|
623
|
+
[elemName: string]: any;
|
|
624
|
+
}
|
|
625
|
+
interface Element {
|
|
626
|
+
[key: string]: any;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
605
630
|
|
|
606
631
|
/**
|
|
607
632
|
* A React-like useRef hook for mutable references.
|
package/main.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
* VaderJS Build & Development Script
|
|
4
|
-
*
|
|
5
|
-
* This script handles building the VaderJS framework, your application code,
|
|
6
|
-
* and serving it in a local development environment with live reloading.
|
|
7
|
-
*
|
|
8
|
-
* Commands:
|
|
9
|
-
* bun run vaderjs build - Builds the project for production.
|
|
10
|
-
* bun run vaderjs dev - Starts the dev server with HMR and file watching.
|
|
11
|
-
* bun run vaderjs serve - Builds and serves the production output.
|
|
12
|
-
*/
|
|
2
|
+
|
|
13
3
|
|
|
14
4
|
import { build, serve } from "bun";
|
|
15
5
|
import fs from "fs/promises";
|
|
@@ -85,7 +75,13 @@ const vaderAPI = {
|
|
|
85
75
|
await p.exited;
|
|
86
76
|
},
|
|
87
77
|
injectHTML: (content) => htmlInjections.push(content),
|
|
88
|
-
log:
|
|
78
|
+
log: {
|
|
79
|
+
warn: (msg) => logger.warn(msg),
|
|
80
|
+
info: (msg) => logger.info(msg),
|
|
81
|
+
error: (msg) => logger.error(msg),
|
|
82
|
+
success: (msg) => logger.success(msg),
|
|
83
|
+
step: (msg) => logger.step(msg)
|
|
84
|
+
},
|
|
89
85
|
getProjectRoot: () => PROJECT_ROOT,
|
|
90
86
|
getDistDir: () => DIST_DIR,
|
|
91
87
|
getPublicDir: () => PUBLIC_DIR,
|
|
@@ -93,9 +89,10 @@ const vaderAPI = {
|
|
|
93
89
|
|
|
94
90
|
async function loadConfig() {
|
|
95
91
|
try {
|
|
96
|
-
const configModule = await import(path.join(PROJECT_ROOT, "vaderjs.config.js"));
|
|
92
|
+
const configModule = await import(path.join(PROJECT_ROOT, "vaderjs.config.js"));
|
|
97
93
|
return configModule.default || configModule;
|
|
98
94
|
} catch {
|
|
95
|
+
console.log(path.join(PROJECT_ROOT, "vaderjs.config.js"))
|
|
99
96
|
logger.warn("No 'vader.config.js' found, using defaults.");
|
|
100
97
|
return {};
|
|
101
98
|
}
|
|
@@ -149,10 +146,43 @@ async function buildVaderCore() {
|
|
|
149
146
|
function patchHooksUsage(code) {
|
|
150
147
|
return code.replace(/import\s+{[^}]*use(State|Effect|Memo|Navigation)[^}]*}\s+from\s+['"]vaderjs['"];?\n?/g, "");
|
|
151
148
|
}
|
|
149
|
+
function publicAssetPlugin() {
|
|
150
|
+
return {
|
|
151
|
+
name: "public-asset-replacer",
|
|
152
|
+
setup(build) {
|
|
153
|
+
build.onLoad({ filter: /\.(js|ts|jsx|tsx|html)$/ }, async (args) => {
|
|
154
|
+
let code = await fs.readFile(args.path, "utf8");
|
|
155
|
+
|
|
156
|
+
code = code.replace(/\{\{public:(.+?)\}\}/g, (_, relPath) => {
|
|
157
|
+
const absPath = path.join(PUBLIC_DIR, relPath.trim());
|
|
158
|
+
if (fsSync.existsSync(absPath)) {
|
|
159
|
+
return "/" + relPath.trim().replace(/\\/g, "/");
|
|
160
|
+
}
|
|
161
|
+
logger.warn(`Public asset not found: ${relPath}`);
|
|
162
|
+
return relPath;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
contents: code,
|
|
167
|
+
loader: args.path.endsWith(".html")
|
|
168
|
+
? "text"
|
|
169
|
+
: args.path.endsWith(".tsx")
|
|
170
|
+
? "tsx"
|
|
171
|
+
: args.path.endsWith(".jsx")
|
|
172
|
+
? "jsx"
|
|
173
|
+
: args.path.endsWith(".ts")
|
|
174
|
+
? "ts"
|
|
175
|
+
: "js",
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
152
181
|
|
|
153
182
|
/**
|
|
154
183
|
* Step 3: Pre-processes all files in `/src` into a temporary directory.
|
|
155
184
|
*/
|
|
185
|
+
|
|
156
186
|
async function preprocessSources(srcDir, tempDir) {
|
|
157
187
|
await fs.mkdir(tempDir, { recursive: true });
|
|
158
188
|
for (const entry of await fs.readdir(srcDir, { withFileTypes: true })) {
|
|
@@ -163,7 +193,7 @@ async function preprocessSources(srcDir, tempDir) {
|
|
|
163
193
|
await preprocessSources(srcPath, destPath);
|
|
164
194
|
} else if (/\.(tsx|jsx|ts|js)$/.test(entry.name)) {
|
|
165
195
|
let content = await fs.readFile(srcPath, "utf8");
|
|
166
|
-
content = patchHooksUsage(content);
|
|
196
|
+
content = patchHooksUsage(content);
|
|
167
197
|
await fs.writeFile(destPath, content);
|
|
168
198
|
} else {
|
|
169
199
|
await fs.copyFile(srcPath, destPath);
|
|
@@ -201,6 +231,9 @@ async function buildSrc() {
|
|
|
201
231
|
jsxImportSource: "vaderjs",
|
|
202
232
|
target: "browser",
|
|
203
233
|
minify: false,
|
|
234
|
+
plugins: [
|
|
235
|
+
publicAssetPlugin(),
|
|
236
|
+
],
|
|
204
237
|
external: ["vaderjs"],
|
|
205
238
|
});
|
|
206
239
|
}
|
|
@@ -222,57 +255,61 @@ async function copyPublicAssets() {
|
|
|
222
255
|
return;
|
|
223
256
|
}
|
|
224
257
|
|
|
225
|
-
// Ensure the dist directory exists
|
|
226
258
|
if (!fsSync.existsSync(DIST_DIR)) {
|
|
227
259
|
await fs.mkdir(DIST_DIR, { recursive: true });
|
|
228
260
|
}
|
|
229
261
|
|
|
230
|
-
const devClientScript = isDev
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
262
|
+
const devClientScript = isDev
|
|
263
|
+
? `<script>
|
|
264
|
+
new WebSocket("ws://" + location.host + "/__hmr").onmessage = (msg) => {
|
|
265
|
+
if (msg.data === "reload") location.reload();
|
|
266
|
+
};
|
|
267
|
+
</script>`
|
|
268
|
+
: "";
|
|
236
269
|
|
|
237
270
|
const entries = fsSync.readdirSync(APP_DIR, { recursive: true })
|
|
238
271
|
.filter(file => /index\.(jsx|tsx)$/.test(file))
|
|
239
272
|
.map(file => ({
|
|
240
|
-
|
|
241
|
-
|
|
273
|
+
name: path.dirname(file) === '.' ? 'index' : path.dirname(file).replace(/\\/g, '/'),
|
|
274
|
+
path: path.join(APP_DIR, file)
|
|
242
275
|
}));
|
|
243
276
|
|
|
277
|
+
// Helper to resolve any asset path from /public
|
|
278
|
+
function resolvePublicPath(p) {
|
|
279
|
+
const assetPath = p.replace(/^(\.\/|\/)/, ""); // strip leading ./ or /
|
|
280
|
+
const absPath = path.join(PUBLIC_DIR, assetPath);
|
|
281
|
+
if (fsSync.existsSync(absPath)) {
|
|
282
|
+
return "/" + assetPath.replace(/\\/g, "/");
|
|
283
|
+
}
|
|
284
|
+
return p; // leave unchanged if not in public
|
|
285
|
+
}
|
|
286
|
+
|
|
244
287
|
for (const { name, path: entryPath } of entries) {
|
|
245
|
-
// Check for the specific case where 'name' could be 'index.js' and prevent duplication
|
|
246
288
|
const outDir = path.join(DIST_DIR, name === 'index' ? '' : name);
|
|
247
|
-
const outJsPath = path.join(outDir, 'index.js');
|
|
248
|
-
|
|
249
|
-
// Ensure the output directory exists
|
|
289
|
+
const outJsPath = path.join(outDir, 'index.js');
|
|
250
290
|
await fs.mkdir(outDir, { recursive: true });
|
|
251
291
|
|
|
252
|
-
//
|
|
292
|
+
// --- CSS HANDLING ---
|
|
253
293
|
const cssLinks = [];
|
|
254
|
-
|
|
255
|
-
const cssImports = [...
|
|
256
|
-
|
|
294
|
+
let content = await fs.readFile(entryPath, "utf8");
|
|
295
|
+
const cssImports = [...content.matchAll(/import\s+['"](.*\.css)['"]/g)];
|
|
257
296
|
for (const match of cssImports) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
logger.warn(`CSS file not found: ${sourceCssPath}`);
|
|
271
|
-
}
|
|
297
|
+
const cssImportPath = match[1];
|
|
298
|
+
const sourceCssPath = path.resolve(path.dirname(entryPath), cssImportPath);
|
|
299
|
+
if (fsSync.existsSync(sourceCssPath)) {
|
|
300
|
+
const relativeCssPath = path.relative(APP_DIR, sourceCssPath);
|
|
301
|
+
const destCssPath = path.join(DIST_DIR, relativeCssPath);
|
|
302
|
+
await fs.mkdir(path.dirname(destCssPath), { recursive: true });
|
|
303
|
+
await fs.copyFile(sourceCssPath, destCssPath);
|
|
304
|
+
const htmlRelativePath = path.relative(outDir, destCssPath).replace(/\\/g, '/');
|
|
305
|
+
cssLinks.push(`<link rel="stylesheet" href="${htmlRelativePath}">`);
|
|
306
|
+
} else {
|
|
307
|
+
logger.warn(`CSS file not found: ${sourceCssPath}`);
|
|
308
|
+
}
|
|
272
309
|
}
|
|
273
310
|
|
|
274
|
-
//
|
|
275
|
-
|
|
311
|
+
// --- HTML GENERATION ---
|
|
312
|
+
let htmlContent = `<!DOCTYPE html>
|
|
276
313
|
<html lang="en">
|
|
277
314
|
<head>
|
|
278
315
|
<meta charset="UTF-8" />
|
|
@@ -286,37 +323,54 @@ async function copyPublicAssets() {
|
|
|
286
323
|
<script type="module">
|
|
287
324
|
import App from '${name !== 'index' ? "/" + name : ''}/index.js';
|
|
288
325
|
import * as Vader from '/src/vader/index.js';
|
|
289
|
-
window.Vader = Vader
|
|
326
|
+
window.Vader = Vader;
|
|
290
327
|
Vader.render(Vader.createElement(App, null), document.getElementById("app"));
|
|
291
328
|
</script>
|
|
292
329
|
${devClientScript}
|
|
293
330
|
</body>
|
|
294
331
|
</html>`;
|
|
295
332
|
|
|
296
|
-
|
|
333
|
+
// --- FIX ASSET PATHS IN HTML ---
|
|
334
|
+
htmlContent = htmlContent.replace(
|
|
335
|
+
/(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
|
|
336
|
+
(match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
|
|
337
|
+
);
|
|
297
338
|
|
|
298
|
-
|
|
339
|
+
await fs.writeFile(path.join(outDir, "index.html"), htmlContent);
|
|
299
340
|
|
|
300
|
-
//
|
|
341
|
+
// --- JS BUILD ---
|
|
301
342
|
await build({
|
|
302
343
|
entrypoints: [entryPath],
|
|
303
|
-
outdir: outDir,
|
|
344
|
+
outdir: outDir,
|
|
304
345
|
target: "browser",
|
|
305
346
|
minify: false,
|
|
306
347
|
sourcemap: "external",
|
|
307
348
|
external: ["vaderjs"],
|
|
308
349
|
jsxFactory: "e",
|
|
309
350
|
jsxFragment: "Fragment",
|
|
351
|
+
plugins: [
|
|
352
|
+
publicAssetPlugin(),
|
|
353
|
+
],
|
|
310
354
|
jsxImportSource: "vaderjs",
|
|
311
355
|
});
|
|
312
356
|
|
|
313
|
-
//
|
|
357
|
+
// --- FIX IMPORT PATHS IN JS ---
|
|
314
358
|
let jsContent = await fs.readFile(outJsPath, "utf8");
|
|
359
|
+
|
|
360
|
+
// Vader import fix
|
|
315
361
|
jsContent = jsContent.replace(/from\s+['"]vaderjs['"]/g, `from '/src/vader/index.js'`);
|
|
362
|
+
|
|
363
|
+
// Asset path fix for JS
|
|
364
|
+
jsContent = jsContent.replace(
|
|
365
|
+
/(["'(])([^"'()]+?\.(png|jpe?g|gif|svg|webp|ico))(["')])/gi,
|
|
366
|
+
(match, p1, assetPath, ext, p4) => p1 + resolvePublicPath(assetPath) + p4
|
|
367
|
+
);
|
|
368
|
+
|
|
316
369
|
await fs.writeFile(outJsPath, jsContent);
|
|
317
370
|
}
|
|
318
371
|
}
|
|
319
372
|
|
|
373
|
+
|
|
320
374
|
|
|
321
375
|
|
|
322
376
|
async function buildAll(isDev = false) {
|
|
@@ -442,6 +496,7 @@ console.log(banner);
|
|
|
442
496
|
const command = process.argv[2];
|
|
443
497
|
|
|
444
498
|
if (command === "dev") {
|
|
499
|
+
globalThis.isDev = true
|
|
445
500
|
await runDevServer();
|
|
446
501
|
} else if (command === "build") {
|
|
447
502
|
await buildAll(false);
|
package/package.json
CHANGED
package/plugins/index.ts
CHANGED
|
@@ -9,7 +9,13 @@ export interface VaderAPI {
|
|
|
9
9
|
injectHTML(content: string): void;
|
|
10
10
|
|
|
11
11
|
/** Log a message prefixed with [Vader Plugin] */
|
|
12
|
-
log
|
|
12
|
+
log : {
|
|
13
|
+
warn: (msg: any) => void,
|
|
14
|
+
info: (msg: any) => void,
|
|
15
|
+
error: (msg: any) => void,
|
|
16
|
+
success: (msg: any) => void,
|
|
17
|
+
step: (msg: any) => void
|
|
18
|
+
}
|
|
13
19
|
|
|
14
20
|
/** Get absolute path to the project root */
|
|
15
21
|
getProjectRoot(): string;
|
|
@@ -33,6 +39,9 @@ export type PluginHookName =
|
|
|
33
39
|
|
|
34
40
|
/** Interface for a single plugin */
|
|
35
41
|
export interface VaderPlugin {
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
version: string;
|
|
36
45
|
/** Called before build starts */
|
|
37
46
|
onBuildStart?(api: VaderAPI): Promise<void> | void;
|
|
38
47
|
|