evikit 2.14.0 → 2.14.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.
Files changed (4) hide show
  1. package/README.md +4 -4
  2. package/index.css +112 -104
  3. package/package.json +1 -1
  4. package/server.js +34 -18
package/README.md CHANGED
@@ -335,7 +335,7 @@ PORT=8000
335
335
  Run it:
336
336
 
337
337
  ```sh
338
- npx cross-env NODE_ENV=production node --env-file=.env index.js
338
+ npx cross-env NODE_ENV=production node --env-file-if-exists=.env index.js
339
339
  ```
340
340
 
341
341
  You can add this command (without npx) as `start` script to your `package.json`.
@@ -1028,7 +1028,7 @@ Component:
1028
1028
  - btn btn-ghost btn-disabled
1029
1029
  - fieldset fieldset-legend label input
1030
1030
  - link
1031
- - lg:table table-zebra
1031
+ - table lg:table table-zebra
1032
1032
 
1033
1033
  Color:
1034
1034
 
@@ -1149,11 +1149,11 @@ The following commands should work now:
1149
1149
 
1150
1150
  ```sh
1151
1151
  # Run dev server with watch mode.
1152
- node --env-file=.env index.js dev
1152
+ node --env-file-if-exists=.env index.js dev
1153
1153
 
1154
1154
  # Build client for production.
1155
1155
  npx tsc
1156
- node --env-file=.env index.js build
1156
+ node --env-file-if-exists=.env index.js build
1157
1157
  ```
1158
1158
 
1159
1159
  You can change the `dev` and `build` scripts in your `package.json` accordingly.
package/index.css CHANGED
@@ -30,6 +30,117 @@ summary {
30
30
  list-style: revert;
31
31
  }
32
32
 
33
+ /* Component. */
34
+
35
+ .badge {
36
+ border-radius: 0.5rem;
37
+ display: inline-flex;
38
+ gap: 0.5rem;
39
+ font-size: 0.875rem;
40
+ padding: 0.0625rem 0.75rem;
41
+ }
42
+
43
+ .badge-info {
44
+ background-color: color-mix(in srgb, darkturquoise 6.25%, transparent);
45
+ }
46
+
47
+ .btn {
48
+ background-color: rgba(0, 0, 0, 0.03125);
49
+ border: 1px solid rgba(0, 0, 0, 0.0625);
50
+ border-radius: 0.25rem;
51
+ cursor: pointer;
52
+ display: inline-block;
53
+ font-size: 0.875rem;
54
+ font-weight: 600;
55
+ padding: 0.5rem 1rem;
56
+ }
57
+
58
+ .btn:focus,
59
+ .btn:hover {
60
+ background-color: rgba(0, 0, 0, 0.125);
61
+ }
62
+
63
+ .btn-ghost:not(:focus):not(:hover) {
64
+ background-color: transparent;
65
+ border-color: transparent;
66
+ }
67
+
68
+ .btn-disabled {
69
+ background-color: rgba(0, 0, 0, 0.03125);
70
+ border-color: rgba(0, 0, 0, 0.03125);
71
+ }
72
+
73
+ .fieldset {
74
+ border: none;
75
+ display: flex;
76
+ flex-direction: column;
77
+ gap: 0.25rem;
78
+ padding-bottom: 0.25rem;
79
+ padding-top: 0.25rem;
80
+ }
81
+
82
+ .fieldset-legend {
83
+ font-size: 0.75rem;
84
+ font-weight: bold;
85
+ }
86
+
87
+ .label {
88
+ display: table;
89
+ font-size: 0.75rem;
90
+ }
91
+
92
+ .input {
93
+ border: 1px solid rgba(0, 0, 0, 0.25);
94
+ border-radius: 0.25rem;
95
+ font-size: 0.875rem;
96
+ max-width: 100%;
97
+ padding: 0.5rem 0.75rem;
98
+ width: 20rem;
99
+ }
100
+
101
+ .link {
102
+ text-decoration: underline;
103
+ }
104
+
105
+ .table,
106
+ .lg\:table {
107
+ border-collapse: collapse;
108
+ font-size: 0.875rem;
109
+ width: 100%;
110
+ }
111
+
112
+ .table {
113
+ display: table;
114
+ }
115
+
116
+ @media (min-width: 992px) {
117
+ .lg\:table {
118
+ display: table;
119
+ }
120
+ }
121
+
122
+ .table thead th,
123
+ .lg\:table thead th {
124
+ font-weight: 700;
125
+ opacity: 0.5;
126
+ }
127
+
128
+ .table tr > *,
129
+ .lg\:table tr > * {
130
+ padding: 0.75rem;
131
+ }
132
+
133
+ .table-zebra tr:nth-child(even) {
134
+ background-color: rgba(0, 0, 0, 0.025);
135
+ border-bottom: 1px solid rgba(0, 0, 0, 0.075);
136
+ }
137
+
138
+ @media (prefers-color-scheme: dark) {
139
+ .table-zebra tr:nth-child(even) {
140
+ background-color: rgba(255, 255, 255, 0.05);
141
+ }
142
+ }
143
+
33
144
  /* Margin. */
34
145
 
35
146
  .m-8 {
@@ -406,7 +517,7 @@ summary {
406
517
  }
407
518
 
408
519
  .row-span-2 {
409
- grid-row: 2;
520
+ grid-row: span 2;
410
521
  }
411
522
 
412
523
  .text-center {
@@ -479,109 +590,6 @@ summary {
479
590
  }
480
591
  }
481
592
 
482
- /* Component. */
483
-
484
- .badge {
485
- border-radius: 0.5rem;
486
- display: inline-flex;
487
- gap: 0.5rem;
488
- font-size: 0.875rem;
489
- padding: 0.0625rem 0.75rem;
490
- }
491
-
492
- .badge-info {
493
- background-color: color-mix(in srgb, darkturquoise 6.25%, transparent);
494
- }
495
-
496
- .btn {
497
- background-color: rgba(0, 0, 0, 0.03125);
498
- border: 1px solid rgba(0, 0, 0, 0.0625);
499
- border-radius: 0.25rem;
500
- cursor: pointer;
501
- font-size: 0.875rem;
502
- font-weight: 600;
503
- padding: 0.5rem 1rem;
504
- }
505
-
506
- .btn:focus,
507
- .btn:hover {
508
- background-color: rgba(0, 0, 0, 0.125);
509
- }
510
-
511
- .btn-ghost:not(:focus):not(:hover) {
512
- background-color: transparent;
513
- border-color: transparent;
514
- }
515
-
516
- .btn-disabled {
517
- background-color: rgba(0, 0, 0, 0.03125);
518
- border-color: rgba(0, 0, 0, 0.03125);
519
- }
520
-
521
- .fieldset {
522
- border: none;
523
- display: flex;
524
- flex-direction: column;
525
- gap: 0.25rem;
526
- padding-bottom: 0.25rem;
527
- padding-top: 0.25rem;
528
- }
529
-
530
- .fieldset-legend {
531
- font-size: 0.75rem;
532
- font-weight: bold;
533
- }
534
-
535
- .label {
536
- display: table;
537
- font-size: 0.75rem;
538
- }
539
-
540
- .input {
541
- border: 1px solid rgba(0, 0, 0, 0.25);
542
- border-radius: 0.25rem;
543
- font-size: 0.875rem;
544
- max-width: 100%;
545
- padding: 0.5rem 0.75rem;
546
- width: 20rem;
547
- }
548
-
549
- .link {
550
- text-decoration: underline;
551
- }
552
-
553
- .lg\:table {
554
- border-collapse: collapse;
555
- font-size: 0.875rem;
556
- width: 100%;
557
- }
558
-
559
- @media (min-width: 992px) {
560
- .lg\:table {
561
- display: table;
562
- }
563
- }
564
-
565
- .lg\:table thead th {
566
- font-weight: 700;
567
- opacity: 0.5;
568
- }
569
-
570
- .lg\:table tr > * {
571
- padding: 0.75rem;
572
- }
573
-
574
- .table-zebra tr:nth-child(even) {
575
- background-color: rgba(0, 0, 0, 0.025);
576
- border-bottom: 1px solid rgba(0, 0, 0, 0.075);
577
- }
578
-
579
- @media (prefers-color-scheme: dark) {
580
- .table-zebra tr:nth-child(even) {
581
- background-color: rgba(255, 255, 255, 0.05);
582
- }
583
- }
584
-
585
593
  /* Color. */
586
594
 
587
595
  .opacity-0 {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "evikit",
3
3
  "description": "Preact/SQLite SSR framework for small web apps",
4
- "version": "2.14.0",
4
+ "version": "2.14.2",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./index.js",
package/server.js CHANGED
@@ -213,8 +213,6 @@ let esbuild = false;
213
213
  /** @param {{ listen: (port: number, callback: () => void) => { close(): void, on(event: "error", callback: (error: unknown) => void ): void } }} app */
214
214
  export async function listen(app) {
215
215
  if (esbuild && cluster.isPrimary) {
216
- let esbuildPort = 0;
217
-
218
216
  async function makeHtml() {
219
217
  await writeFile(
220
218
  "./dist/index.html",
@@ -228,10 +226,22 @@ export async function listen(app) {
228
226
  '<script src="/src/prerender.js?' +
229
227
  (await sha256("./dist/src/prerender.js")) +
230
228
  '"></script>' +
231
- (esbuildPort
232
- ? '<script>new EventSource("http://localhost:' +
233
- esbuildPort +
234
- '/esbuild").addEventListener("change", () => location.reload());</script>'
229
+ (process.argv[2] == "dev"
230
+ ? `<script>
231
+ (async () => {
232
+ let nav;
233
+ addEventListener("beforeunload", () => {
234
+ nav = true;
235
+ });
236
+ try {
237
+ await (await fetch("/never-end")).text();
238
+ } catch (error) {
239
+ if (!nav) {
240
+ location.reload();
241
+ }
242
+ }
243
+ })();
244
+ </script>`
235
245
  : ""),
236
246
  ),
237
247
  );
@@ -251,7 +261,7 @@ export async function listen(app) {
251
261
  return;
252
262
  }
253
263
 
254
- if (process.argv[2] == "dev" && cluster.isPrimary) {
264
+ if (process.argv[2] == "dev") {
255
265
  const { context } = await import("esbuild");
256
266
 
257
267
  const { watch: watchApi } = await context({
@@ -263,26 +273,19 @@ export async function listen(app) {
263
273
  });
264
274
  await watchApi();
265
275
 
266
- const { serve: servePrerender, watch: watchPrerender } = await context({
276
+ const { watch: watchPrerender } = await context({
267
277
  bundle: true,
268
278
  entryPoints: ["./index.css", "./src/prerender.js"],
269
279
  outdir: "./dist",
270
280
  });
271
281
  await watchPrerender();
272
- ({ port: esbuildPort } = await servePrerender({
273
- cors: {
274
- origin:
275
- process.env["ORIGIN"] ||
276
- `http://localhost:${Number(process.env["PORT"]) || 5173}`,
277
- },
278
- }));
279
282
 
280
- let subprocess = cluster.fork();
281
283
  let lastHash =
282
284
  (await sha256("./dist/api.js")) +
283
285
  (await sha256("./dist/index.css")) +
284
286
  (await sha256("./dist/src/prerender.js"));
285
287
  await makeHtml();
288
+ let subprocess = cluster.fork();
286
289
  setInterval(async () => {
287
290
  const hash =
288
291
  (await sha256("./dist/api.js")) +
@@ -294,7 +297,7 @@ export async function listen(app) {
294
297
  subprocess.kill();
295
298
  subprocess = cluster.fork();
296
299
  }
297
- }, 1000);
300
+ }, 100);
298
301
  }
299
302
 
300
303
  await makeHtml();
@@ -321,7 +324,11 @@ export async function listen(app) {
321
324
  }
322
325
  });
323
326
  }
324
- } else if ((esbuild && !process.argv[2]) || cluster.isPrimary) {
327
+ } else if (
328
+ (esbuild && process.argv[2] == "dev" && !cluster.isPrimary) ||
329
+ (esbuild && !process.argv[2] && cluster.isPrimary) ||
330
+ (!esbuild && cluster.isPrimary)
331
+ ) {
325
332
  const server = app.listen(port, () => {
326
333
  if (cluster.isPrimary || process.env["i"] == "0") {
327
334
  console.log(
@@ -349,8 +356,17 @@ export function production({ html, prerender }) {
349
356
  * @param {import("node:http").ServerResponse<import("node:http").IncomingMessage>} res
350
357
  */
351
358
  return async function onRequest(req, res) {
359
+ if (esbuild && process.argv[2] == "dev" && req.url == "/never-end") {
360
+ res.write(".");
361
+ return;
362
+ }
352
363
  try {
353
364
  if (!html) {
365
+ if (!existsSync("./dist/index.html")) {
366
+ res.statusCode = 502;
367
+ res.end("502");
368
+ return;
369
+ }
354
370
  html = await readFile("./dist/index.html", "utf-8");
355
371
  }
356
372
  const rendered = await prerender({