@pure-ds/core 0.5.24 → 0.5.26
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/dist/types/src/js/pds-core/pds-registry.d.ts.map +1 -1
- package/package.json +1 -1
- package/packages/pds-cli/bin/pds-bootstrap.js +46 -428
- package/packages/pds-cli/bin/templates/bootstrap/esbuild-dev.cjs +76 -0
- package/packages/pds-cli/bin/templates/bootstrap/esbuild-dev.mjs +69 -0
- package/packages/pds-cli/bin/templates/bootstrap/pds.config.js +59 -0
- package/packages/pds-cli/bin/templates/bootstrap/public/assets/css/app.css +59 -0
- package/packages/pds-cli/bin/templates/bootstrap/public/assets/js/dev-reload.js +18 -0
- package/packages/pds-cli/bin/templates/bootstrap/public/assets/my/my-home.js +32 -0
- package/packages/pds-cli/bin/templates/bootstrap/public/assets/my/my-theme.js +74 -0
- package/packages/pds-cli/bin/templates/bootstrap/public/index.html +38 -0
- package/packages/pds-cli/bin/templates/bootstrap/src/js/app.js +38 -0
- package/public/assets/js/app.js +6 -6
- package/public/assets/js/pds-manager.js +1 -1
- package/public/assets/js/pds.js +5 -5
- package/src/js/pds-core/pds-registry.js +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pds-registry.d.ts","sourceRoot":"","sources":["../../../../../src/js/pds-core/pds-registry.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pds-registry.d.ts","sourceRoot":"","sources":["../../../../../src/js/pds-core/pds-registry.js"],"names":[],"mappings":"AA4EA,mCAA0C;AAvE1C;IAEI,cAAqB;IACrB;;;;;;MAMC;IAGH;;OAEG;IACH,oBAEC;IAED;;;OAGG;IACH,gCAGC;IAED;;;OAGG;IACH,wCAqBC;IAED;;OAEG;IACH,mBAEC;IAED;;OAEG;IACH,sBAEC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { readFile, writeFile, mkdir, access, rename, rm } from 'fs/promises';
|
|
3
|
+
import { readFile, writeFile, mkdir, access, rename, rm, copyFile, readdir } from 'fs/promises';
|
|
4
4
|
import { existsSync } from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { spawn } from 'child_process';
|
|
7
|
-
import {
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
8
|
|
|
9
9
|
const projectRoot = process.cwd();
|
|
10
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const templateRoot = path.join(__dirname, 'templates', 'bootstrap');
|
|
10
12
|
|
|
11
13
|
function log(message) {
|
|
12
14
|
console.log(message);
|
|
@@ -29,6 +31,19 @@ async function writeFileIfMissing(filePath, content) {
|
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
async function copyFileIfMissing(sourcePath, targetPath) {
|
|
35
|
+
try {
|
|
36
|
+
await access(targetPath);
|
|
37
|
+
log(`↪️ Skipping existing ${path.relative(projectRoot, targetPath)}`);
|
|
38
|
+
return false;
|
|
39
|
+
} catch {
|
|
40
|
+
await ensureDir(path.dirname(targetPath));
|
|
41
|
+
await copyFile(sourcePath, targetPath);
|
|
42
|
+
log(`✅ Created ${path.relative(projectRoot, targetPath)}`);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
32
47
|
function getNpmCommand() {
|
|
33
48
|
return process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
34
49
|
}
|
|
@@ -54,423 +69,48 @@ async function writePackageJson(pkgPath, pkg) {
|
|
|
54
69
|
await writeFile(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
55
70
|
}
|
|
56
71
|
|
|
57
|
-
function
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
<title>Pure Design System</title>
|
|
64
|
-
|
|
65
|
-
<!-- PDS Styles -->
|
|
66
|
-
<link rel="stylesheet" href="/assets/css/app.css" />
|
|
67
|
-
|
|
68
|
-
<!-- Import Map for Lit components -->
|
|
69
|
-
<script type="importmap">
|
|
70
|
-
{
|
|
71
|
-
"imports": {
|
|
72
|
-
"#pds/lit": "/assets/js/lit.js"
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
</script>
|
|
76
|
-
|
|
77
|
-
<!-- Dev live-reload (safe in production, no-op without server) -->
|
|
78
|
-
<script type="module" src="/assets/js/dev-reload.js" defer></script>
|
|
79
|
-
|
|
80
|
-
<!-- App Script -->
|
|
81
|
-
<script type="module" src="/assets/js/app.js" defer></script>
|
|
82
|
-
</head>
|
|
83
|
-
|
|
84
|
-
<body class="container">
|
|
85
|
-
<header class="stack-sm">
|
|
86
|
-
<p class="auto-gen">Auto-generated by PDS ${version} at ${generatedAt}</p>
|
|
87
|
-
</header>
|
|
88
|
-
|
|
89
|
-
<main></main>
|
|
90
|
-
|
|
91
|
-
<footer class="text-sm text-muted">
|
|
92
|
-
<small>© 2026 Pure Design System</small>
|
|
93
|
-
</footer>
|
|
94
|
-
</body>
|
|
95
|
-
</html>
|
|
96
|
-
`;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function buildDevReloadJs() {
|
|
100
|
-
return `const shouldConnect =
|
|
101
|
-
location.hostname === 'localhost' || location.hostname === '127.0.0.1';
|
|
102
|
-
|
|
103
|
-
if (shouldConnect) {
|
|
104
|
-
const reloadPort = 4174;
|
|
105
|
-
const endpoint = 'http://localhost:' + reloadPort + '/events';
|
|
106
|
-
const source = new EventSource(endpoint);
|
|
107
|
-
|
|
108
|
-
source.onmessage = (event) => {
|
|
109
|
-
if (event.data === 'reload') {
|
|
110
|
-
location.reload();
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
source.onerror = () => {
|
|
115
|
-
source.close();
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function buildAppCss() {
|
|
122
|
-
return `html:not(.pds-ready) {
|
|
123
|
-
opacity: 0;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
main {
|
|
127
|
-
margin: auto;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
h1 {
|
|
131
|
-
background: linear-gradient(var(--gradient-angle, 135deg),
|
|
132
|
-
var(--color-primary-400),
|
|
133
|
-
var(--color-accent-400)
|
|
134
|
-
);
|
|
135
|
-
background-clip: text;
|
|
136
|
-
-webkit-background-clip: text;
|
|
137
|
-
color: transparent;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.container {
|
|
141
|
-
display: grid;
|
|
142
|
-
grid-template-rows: auto 1fr auto;
|
|
143
|
-
height: 100dvh;
|
|
144
|
-
padding: 0;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
header, footer {
|
|
148
|
-
padding: var(--spacing-4);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
footer {
|
|
152
|
-
text-align: center;
|
|
72
|
+
async function writeIndexFromTemplate(sourcePath, targetPath, { version, generatedAt }) {
|
|
73
|
+
const raw = await readFile(sourcePath, 'utf8');
|
|
74
|
+
const content = raw
|
|
75
|
+
.replaceAll('{{PDS_VERSION}}', version)
|
|
76
|
+
.replaceAll('{{PDS_GENERATED_AT}}', generatedAt);
|
|
77
|
+
await writeFileIfMissing(targetPath, content);
|
|
153
78
|
}
|
|
154
79
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
font-size: var(--font-size-xs);
|
|
158
|
-
}
|
|
80
|
+
async function copyTemplateDirectory(sourceDir, targetDir, options) {
|
|
81
|
+
const entries = await readdir(sourceDir, { withFileTypes: true });
|
|
159
82
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.hero {
|
|
167
|
-
padding: var(--spacing-8);
|
|
168
|
-
zoom: 1.15;
|
|
169
|
-
text-align: center;
|
|
170
|
-
border: var(--border-width-medium) solid transparent;
|
|
171
|
-
background: linear-gradient(var(--color-surface-base), var(--color-surface-base)) padding-box,
|
|
172
|
-
linear-gradient(var(--gradient-angle, 135deg), var(--color-primary-400), var(--color-accent-400)) border-box;
|
|
173
|
-
max-width: var(--max-w-lg);
|
|
174
|
-
border-radius: var(--radius-lg);
|
|
175
|
-
border-width: 3px;
|
|
176
|
-
}
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
const sourcePath = path.join(sourceDir, entry.name);
|
|
85
|
+
const targetPath = path.join(targetDir, entry.name);
|
|
86
|
+
const relativePath = path.relative(templateRoot, sourcePath);
|
|
177
87
|
|
|
178
|
-
.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function buildMyHome() {
|
|
185
|
-
return `/**
|
|
186
|
-
* @file my-home.js
|
|
187
|
-
* @description A simple home component for the app.
|
|
188
|
-
*/
|
|
189
|
-
customElements.define(
|
|
190
|
-
"my-home",
|
|
191
|
-
class extends HTMLElement {
|
|
192
|
-
connectedCallback() {
|
|
193
|
-
this.innerHTML = /*html*/ \`
|
|
194
|
-
<article class="hero">
|
|
195
|
-
<h1>Welcome to your new App</h1>
|
|
196
|
-
<div>
|
|
197
|
-
<p>
|
|
198
|
-
This <code><my-home></code> Web Component is lazy-loaded and styled with Pure Design System.
|
|
199
|
-
</p>
|
|
200
|
-
<p>
|
|
201
|
-
You can start building your app by editing the files in <code>public/assets/my/</code> and <code>src/js/</code>.
|
|
202
|
-
</p>
|
|
203
|
-
</div>
|
|
204
|
-
<nav>
|
|
205
|
-
<a target="_blank" href="https://github.com/Pure-Web-Foundation/pure-ds/blob/main/getting-started.md" class="btn btn-primary btn-lg">
|
|
206
|
-
<pds-icon icon="rocket"></pds-icon> Get Started
|
|
207
|
-
</a>
|
|
208
|
-
<a target="_blank" href="https://puredesignsystem.z6.web.core.windows.net/storybook/" class="btn btn-secondary btn-lg">
|
|
209
|
-
<pds-icon icon="book-open"></pds-icon> Storybook
|
|
210
|
-
</a>
|
|
211
|
-
</nav>
|
|
212
|
-
</article>
|
|
213
|
-
\`;
|
|
88
|
+
if (entry.isDirectory()) {
|
|
89
|
+
await ensureDir(targetPath);
|
|
90
|
+
await copyTemplateDirectory(sourcePath, targetPath, options);
|
|
91
|
+
continue;
|
|
214
92
|
}
|
|
215
|
-
},
|
|
216
|
-
);
|
|
217
|
-
`;
|
|
218
|
-
}
|
|
219
93
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
*
|
|
224
|
-
* Uses Pure Design System (PDS) for styling and theming.
|
|
225
|
-
*/
|
|
226
|
-
customElements.define(
|
|
227
|
-
"my-theme",
|
|
228
|
-
class extends HTMLElement {
|
|
229
|
-
constructor() {
|
|
230
|
-
super();
|
|
231
|
-
this.attachShadow({ mode: "open" });
|
|
94
|
+
if (relativePath === path.join('public', 'index.html')) {
|
|
95
|
+
await writeIndexFromTemplate(sourcePath, targetPath, options);
|
|
96
|
+
continue;
|
|
232
97
|
}
|
|
233
98
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
"\n :host {\n display: block;\n }\n "
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
await PDS.adoptLayers(
|
|
240
|
-
this.shadowRoot,
|
|
241
|
-
["tokens", "primitives", "components", "utilities"],
|
|
242
|
-
[componentStyles],
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
this.shadowRoot.innerHTML +=
|
|
246
|
-
"\n <form>\n <fieldset role=\"radiogroup\" aria-label=\"Theme\" class=\"buttons\">\n <legend>Theme</legend>\n <label>\n <input type=\"radio\" name=\"theme\" value=\"system\">\n <span>\n <pds-icon icon=\"moon-stars\"></pds-icon>\n System\n </span>\n </label>\n <label>\n <input type=\"radio\" name=\"theme\" value=\"light\">\n <span>\n <pds-icon icon=\"sun\"></pds-icon>\n Light\n </span>\n </label>\n <label>\n <input type=\"radio\" name=\"theme\" value=\"dark\">\n <span>\n <pds-icon icon=\"moon\"></pds-icon>\n Dark\n </span>\n </label>\n </fieldset>\n </form>";
|
|
247
|
-
|
|
248
|
-
this.#updateCheckedState();
|
|
249
|
-
|
|
250
|
-
this.shadowRoot.addEventListener("change", (e) => {
|
|
251
|
-
if (e.target.type === "radio" && e.target.name === "theme") {
|
|
252
|
-
PDS.theme = e.target.value;
|
|
253
|
-
PDS.toast("Theme changed to " + e.target.value, { duration: 2000 });
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
const observer = new MutationObserver(() => {
|
|
258
|
-
this.#updateCheckedState();
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
observer.observe(document.documentElement, {
|
|
262
|
-
attributes: true,
|
|
263
|
-
attributeFilter: ["data-theme"],
|
|
264
|
-
});
|
|
99
|
+
if (relativePath === 'esbuild-dev.cjs' || relativePath === 'esbuild-dev.mjs') {
|
|
100
|
+
continue;
|
|
265
101
|
}
|
|
266
102
|
|
|
267
|
-
|
|
268
|
-
const currentTheme = PDS.theme || "system";
|
|
269
|
-
const radios = this.shadowRoot.querySelectorAll('input[type="radio"]');
|
|
270
|
-
radios.forEach((radio) => {
|
|
271
|
-
radio.checked = radio.value === currentTheme;
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
);
|
|
276
|
-
`;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function buildAppJs() {
|
|
280
|
-
return `import { PDS } from "@pure-ds/core";
|
|
281
|
-
import { config } from "../../pds.config.js";
|
|
282
|
-
|
|
283
|
-
await PDS.start(config);
|
|
284
|
-
|
|
285
|
-
const main = document.querySelector("main");
|
|
286
|
-
if (main && !main.querySelector("my-home")) {
|
|
287
|
-
main.innerHTML = "<my-home></my-home>";
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
* Generates an HTML NodeList by parsing the given HTML string
|
|
292
|
-
* @param {String} html
|
|
293
|
-
* @returns {NodeListOf<ChildNode>} DOM element
|
|
294
|
-
*/
|
|
295
|
-
const parseHTML = (html) => {
|
|
296
|
-
return new DOMParser().parseFromString(html, "text/html").body.childNodes;
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
const settingsBtn = parseHTML(
|
|
300
|
-
\`<button id="settings-btn" class="icon-only btn-xs btn-outline" aria-label="Settings">
|
|
301
|
-
<pds-icon icon="gear"></pds-icon>
|
|
302
|
-
</button>\`,
|
|
303
|
-
)[0];
|
|
304
|
-
|
|
305
|
-
document.body.appendChild(settingsBtn);
|
|
306
|
-
|
|
307
|
-
const drawer = document.createElement("pds-drawer");
|
|
308
|
-
drawer.setAttribute("position", "right");
|
|
309
|
-
|
|
310
|
-
drawer.innerHTML = /*html*/ \`<div slot="drawer-header">Settings</div>\n <div slot="drawer-content"><my-theme></my-theme></div>\`;
|
|
311
|
-
document.body.appendChild(drawer);
|
|
312
|
-
|
|
313
|
-
settingsBtn.addEventListener("click", () => {
|
|
314
|
-
drawer.open = true;
|
|
315
|
-
});
|
|
316
|
-
`;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
function buildPdsConfig() {
|
|
320
|
-
return buildStarterPdsConfig();
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
function buildEsbuildDevCjs() {
|
|
324
|
-
return `const esbuild = require('esbuild');
|
|
325
|
-
const http = require('http');
|
|
326
|
-
|
|
327
|
-
const reloadPort = 4174;
|
|
328
|
-
const reloadClients = new Set();
|
|
329
|
-
|
|
330
|
-
function startReloadServer() {
|
|
331
|
-
const server = http.createServer((req, res) => {
|
|
332
|
-
if (req.url !== '/events') {
|
|
333
|
-
res.writeHead(404);
|
|
334
|
-
res.end();
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
res.writeHead(200, {
|
|
339
|
-
'Content-Type': 'text/event-stream',
|
|
340
|
-
'Cache-Control': 'no-cache',
|
|
341
|
-
Connection: 'keep-alive',
|
|
342
|
-
'Access-Control-Allow-Origin': '*'
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
res.write('retry: 1000\\n\\n');
|
|
346
|
-
reloadClients.add(res);
|
|
347
|
-
|
|
348
|
-
req.on('close', () => {
|
|
349
|
-
reloadClients.delete(res);
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
server.listen(reloadPort, () => {
|
|
354
|
-
console.log('Live reload listening on http://localhost:' + reloadPort + '/events');
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
function notifyReload() {
|
|
359
|
-
for (const client of reloadClients) {
|
|
360
|
-
client.write('data: reload\\n\\n');
|
|
103
|
+
await copyFileIfMissing(sourcePath, targetPath);
|
|
361
104
|
}
|
|
362
105
|
}
|
|
363
106
|
|
|
364
|
-
function
|
|
365
|
-
|
|
366
|
-
name: 'live-reload',
|
|
367
|
-
setup(build) {
|
|
368
|
-
build.onEnd((result) => {
|
|
369
|
-
if (!result.errors.length) {
|
|
370
|
-
notifyReload();
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
async function start() {
|
|
378
|
-
startReloadServer();
|
|
379
|
-
const ctx = await esbuild.context({
|
|
380
|
-
entryPoints: ['src/js/app.js'],
|
|
381
|
-
outdir: 'public/assets/js',
|
|
382
|
-
bundle: true,
|
|
383
|
-
format: 'esm',
|
|
384
|
-
sourcemap: true,
|
|
385
|
-
publicPath: '/assets/js',
|
|
386
|
-
external: ['/assets/my/*'],
|
|
387
|
-
logLevel: 'info',
|
|
388
|
-
plugins: [liveReloadPlugin()]
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
await ctx.watch();
|
|
392
|
-
const { host, port } = await ctx.serve({ servedir: 'public', port: 4173 });
|
|
393
|
-
console.log('Dev server running at http://' + host + ':' + port);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
start().catch((err) => {
|
|
397
|
-
console.error(err);
|
|
398
|
-
process.exit(1);
|
|
399
|
-
});
|
|
400
|
-
`;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
function buildEsbuildDevEsm() {
|
|
404
|
-
return `import esbuild from 'esbuild';
|
|
405
|
-
import http from 'http';
|
|
406
|
-
|
|
407
|
-
const reloadPort = 4174;
|
|
408
|
-
const reloadClients = new Set();
|
|
409
|
-
|
|
410
|
-
function startReloadServer() {
|
|
411
|
-
const server = http.createServer((req, res) => {
|
|
412
|
-
if (req.url !== '/events') {
|
|
413
|
-
res.writeHead(404);
|
|
414
|
-
res.end();
|
|
415
|
-
return;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
res.writeHead(200, {
|
|
419
|
-
'Content-Type': 'text/event-stream',
|
|
420
|
-
'Cache-Control': 'no-cache',
|
|
421
|
-
Connection: 'keep-alive',
|
|
422
|
-
'Access-Control-Allow-Origin': '*'
|
|
423
|
-
});
|
|
424
|
-
|
|
425
|
-
res.write('retry: 1000\\n\\n');
|
|
426
|
-
reloadClients.add(res);
|
|
427
|
-
|
|
428
|
-
req.on('close', () => {
|
|
429
|
-
reloadClients.delete(res);
|
|
430
|
-
});
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
server.listen(reloadPort, () => {
|
|
434
|
-
console.log('Live reload listening on http://localhost:' + reloadPort + '/events');
|
|
435
|
-
});
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
function notifyReload() {
|
|
439
|
-
for (const client of reloadClients) {
|
|
440
|
-
client.write('data: reload\\n\\n');
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
function liveReloadPlugin() {
|
|
445
|
-
return {
|
|
446
|
-
name: 'live-reload',
|
|
447
|
-
setup(build) {
|
|
448
|
-
build.onEnd((result) => {
|
|
449
|
-
if (!result.errors.length) {
|
|
450
|
-
notifyReload();
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
startReloadServer();
|
|
458
|
-
|
|
459
|
-
const ctx = await esbuild.context({
|
|
460
|
-
entryPoints: ['src/js/app.js'],
|
|
461
|
-
outdir: 'public/assets/js',
|
|
462
|
-
bundle: true,
|
|
463
|
-
format: 'esm',
|
|
464
|
-
sourcemap: true,
|
|
465
|
-
publicPath: '/assets/js',
|
|
466
|
-
external: ['/assets/my/*'],
|
|
467
|
-
logLevel: 'info',
|
|
468
|
-
plugins: [liveReloadPlugin()]
|
|
469
|
-
});
|
|
107
|
+
async function copyBootstrapTemplate({ version, generatedAt, isModule }) {
|
|
108
|
+
await copyTemplateDirectory(templateRoot, projectRoot, { version, generatedAt });
|
|
470
109
|
|
|
471
|
-
|
|
472
|
-
const
|
|
473
|
-
|
|
110
|
+
const esbuildTemplate = isModule ? 'esbuild-dev.mjs' : 'esbuild-dev.cjs';
|
|
111
|
+
const esbuildSource = path.join(templateRoot, esbuildTemplate);
|
|
112
|
+
const esbuildTarget = path.join(projectRoot, 'esbuild-dev.js');
|
|
113
|
+
await copyFileIfMissing(esbuildSource, esbuildTarget);
|
|
474
114
|
}
|
|
475
115
|
|
|
476
116
|
async function ensurePackageScripts(pkg, pkgPath) {
|
|
@@ -630,29 +270,7 @@ async function main() {
|
|
|
630
270
|
const version = await getPdsCoreVersion();
|
|
631
271
|
const generatedAt = new Date().toLocaleString();
|
|
632
272
|
|
|
633
|
-
await
|
|
634
|
-
path.join(projectRoot, 'public', 'index.html'),
|
|
635
|
-
buildIndexHtml({ version, generatedAt })
|
|
636
|
-
);
|
|
637
|
-
await writeFileIfMissing(path.join(projectRoot, 'public', 'assets', 'css', 'app.css'), buildAppCss());
|
|
638
|
-
await writeFileIfMissing(path.join(projectRoot, 'src', 'js', 'app.js'), buildAppJs());
|
|
639
|
-
await writeFileIfMissing(path.join(projectRoot, 'pds.config.js'), buildPdsConfig());
|
|
640
|
-
await writeFileIfMissing(
|
|
641
|
-
path.join(projectRoot, 'public', 'assets', 'js', 'dev-reload.js'),
|
|
642
|
-
buildDevReloadJs()
|
|
643
|
-
);
|
|
644
|
-
await writeFileIfMissing(
|
|
645
|
-
path.join(projectRoot, 'public', 'assets', 'my', 'my-home.js'),
|
|
646
|
-
buildMyHome()
|
|
647
|
-
);
|
|
648
|
-
await writeFileIfMissing(
|
|
649
|
-
path.join(projectRoot, 'public', 'assets', 'my', 'my-theme.js'),
|
|
650
|
-
buildMyTheme()
|
|
651
|
-
);
|
|
652
|
-
|
|
653
|
-
const esbuildDevPath = path.join(projectRoot, 'esbuild-dev.js');
|
|
654
|
-
const esbuildDevContent = isModule ? buildEsbuildDevEsm() : buildEsbuildDevCjs();
|
|
655
|
-
await writeFileIfMissing(esbuildDevPath, esbuildDevContent);
|
|
273
|
+
await copyBootstrapTemplate({ version, generatedAt, isModule });
|
|
656
274
|
|
|
657
275
|
await ensurePdsAssets();
|
|
658
276
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
const esbuild = require("esbuild");
|
|
2
|
+
const http = require("http");
|
|
3
|
+
|
|
4
|
+
const reloadPort = 4174;
|
|
5
|
+
const reloadClients = new Set();
|
|
6
|
+
|
|
7
|
+
function startReloadServer() {
|
|
8
|
+
const server = http.createServer((req, res) => {
|
|
9
|
+
if (req.url !== "/events") {
|
|
10
|
+
res.writeHead(404);
|
|
11
|
+
res.end();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
res.writeHead(200, {
|
|
16
|
+
"Content-Type": "text/event-stream",
|
|
17
|
+
"Cache-Control": "no-cache",
|
|
18
|
+
Connection: "keep-alive",
|
|
19
|
+
"Access-Control-Allow-Origin": "*",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
res.write("retry: 1000\n\n");
|
|
23
|
+
reloadClients.add(res);
|
|
24
|
+
|
|
25
|
+
req.on("close", () => {
|
|
26
|
+
reloadClients.delete(res);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
server.listen(reloadPort, () => {
|
|
31
|
+
console.log("Live reload listening on http://localhost:" + reloadPort + "/events");
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function notifyReload() {
|
|
36
|
+
for (const client of reloadClients) {
|
|
37
|
+
client.write("data: reload\n\n");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function liveReloadPlugin() {
|
|
42
|
+
return {
|
|
43
|
+
name: "live-reload",
|
|
44
|
+
setup(build) {
|
|
45
|
+
build.onEnd((result) => {
|
|
46
|
+
if (!result.errors.length) {
|
|
47
|
+
notifyReload();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function start() {
|
|
55
|
+
startReloadServer();
|
|
56
|
+
const ctx = await esbuild.context({
|
|
57
|
+
entryPoints: ["src/js/app.js"],
|
|
58
|
+
outdir: "public/assets/js",
|
|
59
|
+
bundle: true,
|
|
60
|
+
format: "esm",
|
|
61
|
+
sourcemap: true,
|
|
62
|
+
publicPath: "/assets/js",
|
|
63
|
+
external: ["/assets/my/*"],
|
|
64
|
+
logLevel: "info",
|
|
65
|
+
plugins: [liveReloadPlugin()],
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await ctx.watch();
|
|
69
|
+
const { host, port } = await ctx.serve({ servedir: "public", port: 4173 });
|
|
70
|
+
console.log("Dev server running at http://" + host + ":" + port);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
start().catch((err) => {
|
|
74
|
+
console.error(err);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import esbuild from "esbuild";
|
|
2
|
+
import http from "http";
|
|
3
|
+
|
|
4
|
+
const reloadPort = 4174;
|
|
5
|
+
const reloadClients = new Set();
|
|
6
|
+
|
|
7
|
+
function startReloadServer() {
|
|
8
|
+
const server = http.createServer((req, res) => {
|
|
9
|
+
if (req.url !== "/events") {
|
|
10
|
+
res.writeHead(404);
|
|
11
|
+
res.end();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
res.writeHead(200, {
|
|
16
|
+
"Content-Type": "text/event-stream",
|
|
17
|
+
"Cache-Control": "no-cache",
|
|
18
|
+
Connection: "keep-alive",
|
|
19
|
+
"Access-Control-Allow-Origin": "*",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
res.write("retry: 1000\n\n");
|
|
23
|
+
reloadClients.add(res);
|
|
24
|
+
|
|
25
|
+
req.on("close", () => {
|
|
26
|
+
reloadClients.delete(res);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
server.listen(reloadPort, () => {
|
|
31
|
+
console.log("Live reload listening on http://localhost:" + reloadPort + "/events");
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function notifyReload() {
|
|
36
|
+
for (const client of reloadClients) {
|
|
37
|
+
client.write("data: reload\n\n");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function liveReloadPlugin() {
|
|
42
|
+
return {
|
|
43
|
+
name: "live-reload",
|
|
44
|
+
setup(build) {
|
|
45
|
+
build.onEnd((result) => {
|
|
46
|
+
if (!result.errors.length) {
|
|
47
|
+
notifyReload();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
startReloadServer();
|
|
55
|
+
|
|
56
|
+
const ctx = await esbuild.context({
|
|
57
|
+
entryPoints: ["src/js/app.js"],
|
|
58
|
+
outdir: "public/assets/js",
|
|
59
|
+
bundle: true,
|
|
60
|
+
format: "esm",
|
|
61
|
+
sourcemap: true,
|
|
62
|
+
publicPath: "/assets/js",
|
|
63
|
+
external: ["/assets/my/*"],
|
|
64
|
+
logLevel: "info",
|
|
65
|
+
plugins: [liveReloadPlugin()],
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await ctx.watch();
|
|
69
|
+
const { host, port } = await ctx.serve({ servedir: "public", port: 4173 });
|