vite-react-ssg 0.7.3 → 0.8.0-beta.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 (44) hide show
  1. package/README.md +7 -1
  2. package/dist/chunks/jsdomGlobal.cjs +10 -65
  3. package/dist/chunks/jsdomGlobal.mjs +10 -65
  4. package/dist/client/single-page.cjs +8 -6
  5. package/dist/client/single-page.d.cts +3 -4
  6. package/dist/client/single-page.d.mts +3 -4
  7. package/dist/client/single-page.d.ts +3 -4
  8. package/dist/client/single-page.mjs +9 -7
  9. package/dist/index.cjs +19 -12
  10. package/dist/index.d.cts +3 -4
  11. package/dist/index.d.mts +3 -4
  12. package/dist/index.d.ts +3 -4
  13. package/dist/index.mjs +17 -10
  14. package/dist/node/cli.cjs +9 -8
  15. package/dist/node/cli.mjs +7 -6
  16. package/dist/node.cjs +22 -1713
  17. package/dist/node.d.cts +1 -2
  18. package/dist/node.d.mts +1 -2
  19. package/dist/node.d.ts +1 -2
  20. package/dist/node.mjs +17 -1707
  21. package/dist/shared/vite-react-ssg.4y2OEiyV.mjs +31 -0
  22. package/dist/shared/{vite-react-ssg.a292c181.mjs → vite-react-ssg.B6SGTWpD.mjs} +5 -4
  23. package/dist/shared/vite-react-ssg.BoLst82g.mjs +1036 -0
  24. package/dist/shared/{vite-react-ssg.c1d49976.cjs → vite-react-ssg.BuZVBVT6.cjs} +5 -8
  25. package/dist/shared/{vite-react-ssg.054e813a.mjs → vite-react-ssg.C0y5wbxl.mjs} +1 -30
  26. package/dist/shared/{vite-react-ssg.0408f7e1.cjs → vite-react-ssg.C2GpVZF1.cjs} +0 -34
  27. package/dist/shared/vite-react-ssg.CFQGqC60.cjs +36 -0
  28. package/dist/shared/vite-react-ssg.CjIppNIS.mjs +30 -0
  29. package/dist/shared/vite-react-ssg.D0EGioth.cjs +35 -0
  30. package/dist/shared/vite-react-ssg.Dyp0kt3B.cjs +1045 -0
  31. package/dist/shared/{vite-react-ssg.de54c34e.d.cts → vite-react-ssg.Txy2EJkI.d.cts} +25 -6
  32. package/dist/shared/{vite-react-ssg.de54c34e.d.mts → vite-react-ssg.Txy2EJkI.d.mts} +25 -6
  33. package/dist/shared/{vite-react-ssg.de54c34e.d.ts → vite-react-ssg.Txy2EJkI.d.ts} +25 -6
  34. package/dist/tanstack.cjs +150 -0
  35. package/dist/tanstack.d.cts +29 -0
  36. package/dist/tanstack.d.mts +29 -0
  37. package/dist/tanstack.d.ts +29 -0
  38. package/dist/tanstack.mjs +143 -0
  39. package/package.json +30 -17
  40. /package/dist/shared/{vite-react-ssg.579feabb.mjs → vite-react-ssg.C6pK7rvr.mjs} +0 -0
  41. /package/dist/shared/{vite-react-ssg.bee8a5a9.cjs → vite-react-ssg.CjsEygxB.cjs} +0 -0
  42. /package/dist/shared/{vite-react-ssg.faf3855a.d.cts → vite-react-ssg.Cm9gBlfg.d.cts} +0 -0
  43. /package/dist/shared/{vite-react-ssg.faf3855a.d.mts → vite-react-ssg.Cm9gBlfg.d.mts} +0 -0
  44. /package/dist/shared/{vite-react-ssg.faf3855a.d.ts → vite-react-ssg.Cm9gBlfg.d.ts} +0 -0
package/dist/node.mjs CHANGED
@@ -1,1707 +1,17 @@
1
- import { join, isAbsolute, parse, dirname } from 'node:path';
2
- import { createRequire } from 'node:module';
3
- import { gray, yellow, blue, dim, cyan, red, green, reset, bold, bgLightCyan } from 'kolorist';
4
- import fs from 'fs-extra';
5
- import { resolveConfig, createLogger, build as build$1, mergeConfig, version as version$1, send, createServer } from 'vite';
6
- import { JSDOM } from 'jsdom';
7
- import { s as serializeState } from './shared/vite-react-ssg.579feabb.mjs';
8
- import { a as withTrailingSlash, r as removeLeadingSlash, c as convertRoutesToDataRoutes, j as joinUrlSegments } from './shared/vite-react-ssg.054e813a.mjs';
9
- import { readFileSync } from 'node:fs';
10
- import React from 'react';
11
- import { HelmetProvider } from 'react-helmet-async';
12
- import { Writable, Readable } from 'node:stream';
13
- import { renderToPipeableStream } from 'react-dom/server';
14
- import { matchRoutes, json } from 'react-router-dom';
15
- import { once } from 'node:events';
16
-
17
- function getDefaultExportFromCjs (x) {
18
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
19
- }
20
-
21
- var eventemitter3 = {exports: {}};
22
-
23
- (function (module) {
24
-
25
- var has = Object.prototype.hasOwnProperty
26
- , prefix = '~';
27
-
28
- /**
29
- * Constructor to create a storage for our `EE` objects.
30
- * An `Events` instance is a plain object whose properties are event names.
31
- *
32
- * @constructor
33
- * @private
34
- */
35
- function Events() {}
36
-
37
- //
38
- // We try to not inherit from `Object.prototype`. In some engines creating an
39
- // instance in this way is faster than calling `Object.create(null)` directly.
40
- // If `Object.create(null)` is not supported we prefix the event names with a
41
- // character to make sure that the built-in object properties are not
42
- // overridden or used as an attack vector.
43
- //
44
- if (Object.create) {
45
- Events.prototype = Object.create(null);
46
-
47
- //
48
- // This hack is needed because the `__proto__` property is still inherited in
49
- // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
50
- //
51
- if (!new Events().__proto__) prefix = false;
52
- }
53
-
54
- /**
55
- * Representation of a single event listener.
56
- *
57
- * @param {Function} fn The listener function.
58
- * @param {*} context The context to invoke the listener with.
59
- * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
60
- * @constructor
61
- * @private
62
- */
63
- function EE(fn, context, once) {
64
- this.fn = fn;
65
- this.context = context;
66
- this.once = once || false;
67
- }
68
-
69
- /**
70
- * Add a listener for a given event.
71
- *
72
- * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
73
- * @param {(String|Symbol)} event The event name.
74
- * @param {Function} fn The listener function.
75
- * @param {*} context The context to invoke the listener with.
76
- * @param {Boolean} once Specify if the listener is a one-time listener.
77
- * @returns {EventEmitter}
78
- * @private
79
- */
80
- function addListener(emitter, event, fn, context, once) {
81
- if (typeof fn !== 'function') {
82
- throw new TypeError('The listener must be a function');
83
- }
84
-
85
- var listener = new EE(fn, context || emitter, once)
86
- , evt = prefix ? prefix + event : event;
87
-
88
- if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
89
- else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
90
- else emitter._events[evt] = [emitter._events[evt], listener];
91
-
92
- return emitter;
93
- }
94
-
95
- /**
96
- * Clear event by name.
97
- *
98
- * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
99
- * @param {(String|Symbol)} evt The Event name.
100
- * @private
101
- */
102
- function clearEvent(emitter, evt) {
103
- if (--emitter._eventsCount === 0) emitter._events = new Events();
104
- else delete emitter._events[evt];
105
- }
106
-
107
- /**
108
- * Minimal `EventEmitter` interface that is molded against the Node.js
109
- * `EventEmitter` interface.
110
- *
111
- * @constructor
112
- * @public
113
- */
114
- function EventEmitter() {
115
- this._events = new Events();
116
- this._eventsCount = 0;
117
- }
118
-
119
- /**
120
- * Return an array listing the events for which the emitter has registered
121
- * listeners.
122
- *
123
- * @returns {Array}
124
- * @public
125
- */
126
- EventEmitter.prototype.eventNames = function eventNames() {
127
- var names = []
128
- , events
129
- , name;
130
-
131
- if (this._eventsCount === 0) return names;
132
-
133
- for (name in (events = this._events)) {
134
- if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
135
- }
136
-
137
- if (Object.getOwnPropertySymbols) {
138
- return names.concat(Object.getOwnPropertySymbols(events));
139
- }
140
-
141
- return names;
142
- };
143
-
144
- /**
145
- * Return the listeners registered for a given event.
146
- *
147
- * @param {(String|Symbol)} event The event name.
148
- * @returns {Array} The registered listeners.
149
- * @public
150
- */
151
- EventEmitter.prototype.listeners = function listeners(event) {
152
- var evt = prefix ? prefix + event : event
153
- , handlers = this._events[evt];
154
-
155
- if (!handlers) return [];
156
- if (handlers.fn) return [handlers.fn];
157
-
158
- for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
159
- ee[i] = handlers[i].fn;
160
- }
161
-
162
- return ee;
163
- };
164
-
165
- /**
166
- * Return the number of listeners listening to a given event.
167
- *
168
- * @param {(String|Symbol)} event The event name.
169
- * @returns {Number} The number of listeners.
170
- * @public
171
- */
172
- EventEmitter.prototype.listenerCount = function listenerCount(event) {
173
- var evt = prefix ? prefix + event : event
174
- , listeners = this._events[evt];
175
-
176
- if (!listeners) return 0;
177
- if (listeners.fn) return 1;
178
- return listeners.length;
179
- };
180
-
181
- /**
182
- * Calls each of the listeners registered for a given event.
183
- *
184
- * @param {(String|Symbol)} event The event name.
185
- * @returns {Boolean} `true` if the event had listeners, else `false`.
186
- * @public
187
- */
188
- EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
189
- var evt = prefix ? prefix + event : event;
190
-
191
- if (!this._events[evt]) return false;
192
-
193
- var listeners = this._events[evt]
194
- , len = arguments.length
195
- , args
196
- , i;
197
-
198
- if (listeners.fn) {
199
- if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
200
-
201
- switch (len) {
202
- case 1: return listeners.fn.call(listeners.context), true;
203
- case 2: return listeners.fn.call(listeners.context, a1), true;
204
- case 3: return listeners.fn.call(listeners.context, a1, a2), true;
205
- case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
206
- case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
207
- case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
208
- }
209
-
210
- for (i = 1, args = new Array(len -1); i < len; i++) {
211
- args[i - 1] = arguments[i];
212
- }
213
-
214
- listeners.fn.apply(listeners.context, args);
215
- } else {
216
- var length = listeners.length
217
- , j;
218
-
219
- for (i = 0; i < length; i++) {
220
- if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
221
-
222
- switch (len) {
223
- case 1: listeners[i].fn.call(listeners[i].context); break;
224
- case 2: listeners[i].fn.call(listeners[i].context, a1); break;
225
- case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
226
- case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
227
- default:
228
- if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
229
- args[j - 1] = arguments[j];
230
- }
231
-
232
- listeners[i].fn.apply(listeners[i].context, args);
233
- }
234
- }
235
- }
236
-
237
- return true;
238
- };
239
-
240
- /**
241
- * Add a listener for a given event.
242
- *
243
- * @param {(String|Symbol)} event The event name.
244
- * @param {Function} fn The listener function.
245
- * @param {*} [context=this] The context to invoke the listener with.
246
- * @returns {EventEmitter} `this`.
247
- * @public
248
- */
249
- EventEmitter.prototype.on = function on(event, fn, context) {
250
- return addListener(this, event, fn, context, false);
251
- };
252
-
253
- /**
254
- * Add a one-time listener for a given event.
255
- *
256
- * @param {(String|Symbol)} event The event name.
257
- * @param {Function} fn The listener function.
258
- * @param {*} [context=this] The context to invoke the listener with.
259
- * @returns {EventEmitter} `this`.
260
- * @public
261
- */
262
- EventEmitter.prototype.once = function once(event, fn, context) {
263
- return addListener(this, event, fn, context, true);
264
- };
265
-
266
- /**
267
- * Remove the listeners of a given event.
268
- *
269
- * @param {(String|Symbol)} event The event name.
270
- * @param {Function} fn Only remove the listeners that match this function.
271
- * @param {*} context Only remove the listeners that have this context.
272
- * @param {Boolean} once Only remove one-time listeners.
273
- * @returns {EventEmitter} `this`.
274
- * @public
275
- */
276
- EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
277
- var evt = prefix ? prefix + event : event;
278
-
279
- if (!this._events[evt]) return this;
280
- if (!fn) {
281
- clearEvent(this, evt);
282
- return this;
283
- }
284
-
285
- var listeners = this._events[evt];
286
-
287
- if (listeners.fn) {
288
- if (
289
- listeners.fn === fn &&
290
- (!once || listeners.once) &&
291
- (!context || listeners.context === context)
292
- ) {
293
- clearEvent(this, evt);
294
- }
295
- } else {
296
- for (var i = 0, events = [], length = listeners.length; i < length; i++) {
297
- if (
298
- listeners[i].fn !== fn ||
299
- (once && !listeners[i].once) ||
300
- (context && listeners[i].context !== context)
301
- ) {
302
- events.push(listeners[i]);
303
- }
304
- }
305
-
306
- //
307
- // Reset the array, or remove it completely if we have no more listeners.
308
- //
309
- if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
310
- else clearEvent(this, evt);
311
- }
312
-
313
- return this;
314
- };
315
-
316
- /**
317
- * Remove all listeners, or those of the specified event.
318
- *
319
- * @param {(String|Symbol)} [event] The event name.
320
- * @returns {EventEmitter} `this`.
321
- * @public
322
- */
323
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
324
- var evt;
325
-
326
- if (event) {
327
- evt = prefix ? prefix + event : event;
328
- if (this._events[evt]) clearEvent(this, evt);
329
- } else {
330
- this._events = new Events();
331
- this._eventsCount = 0;
332
- }
333
-
334
- return this;
335
- };
336
-
337
- //
338
- // Alias methods names because people roll like that.
339
- //
340
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
341
- EventEmitter.prototype.addListener = EventEmitter.prototype.on;
342
-
343
- //
344
- // Expose the prefix.
345
- //
346
- EventEmitter.prefixed = prefix;
347
-
348
- //
349
- // Allow `EventEmitter` to be imported as module namespace.
350
- //
351
- EventEmitter.EventEmitter = EventEmitter;
352
-
353
- //
354
- // Expose the module.
355
- //
356
- {
357
- module.exports = EventEmitter;
358
- }
359
- } (eventemitter3));
360
-
361
- var eventemitter3Exports = eventemitter3.exports;
362
- const EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
363
-
364
- class TimeoutError extends Error {
365
- constructor(message) {
366
- super(message);
367
- this.name = 'TimeoutError';
368
- }
369
- }
370
-
371
- /**
372
- An error to be thrown when the request is aborted by AbortController.
373
- DOMException is thrown instead of this Error when DOMException is available.
374
- */
375
- class AbortError extends Error {
376
- constructor(message) {
377
- super();
378
- this.name = 'AbortError';
379
- this.message = message;
380
- }
381
- }
382
-
383
- /**
384
- TODO: Remove AbortError and just throw DOMException when targeting Node 18.
385
- */
386
- const getDOMException = errorMessage => globalThis.DOMException === undefined
387
- ? new AbortError(errorMessage)
388
- : new DOMException(errorMessage);
389
-
390
- /**
391
- TODO: Remove below function and just 'reject(signal.reason)' when targeting Node 18.
392
- */
393
- const getAbortedReason = signal => {
394
- const reason = signal.reason === undefined
395
- ? getDOMException('This operation was aborted.')
396
- : signal.reason;
397
-
398
- return reason instanceof Error ? reason : getDOMException(reason);
399
- };
400
-
401
- function pTimeout(promise, options) {
402
- const {
403
- milliseconds,
404
- fallback,
405
- message,
406
- customTimers = {setTimeout, clearTimeout},
407
- } = options;
408
-
409
- let timer;
410
-
411
- const wrappedPromise = new Promise((resolve, reject) => {
412
- if (typeof milliseconds !== 'number' || Math.sign(milliseconds) !== 1) {
413
- throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``);
414
- }
415
-
416
- if (options.signal) {
417
- const {signal} = options;
418
- if (signal.aborted) {
419
- reject(getAbortedReason(signal));
420
- }
421
-
422
- signal.addEventListener('abort', () => {
423
- reject(getAbortedReason(signal));
424
- });
425
- }
426
-
427
- if (milliseconds === Number.POSITIVE_INFINITY) {
428
- promise.then(resolve, reject);
429
- return;
430
- }
431
-
432
- // We create the error outside of `setTimeout` to preserve the stack trace.
433
- const timeoutError = new TimeoutError();
434
-
435
- timer = customTimers.setTimeout.call(undefined, () => {
436
- if (fallback) {
437
- try {
438
- resolve(fallback());
439
- } catch (error) {
440
- reject(error);
441
- }
442
-
443
- return;
444
- }
445
-
446
- if (typeof promise.cancel === 'function') {
447
- promise.cancel();
448
- }
449
-
450
- if (message === false) {
451
- resolve();
452
- } else if (message instanceof Error) {
453
- reject(message);
454
- } else {
455
- timeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`;
456
- reject(timeoutError);
457
- }
458
- }, milliseconds);
459
-
460
- (async () => {
461
- try {
462
- resolve(await promise);
463
- } catch (error) {
464
- reject(error);
465
- }
466
- })();
467
- });
468
-
469
- const cancelablePromise = wrappedPromise.finally(() => {
470
- cancelablePromise.clear();
471
- });
472
-
473
- cancelablePromise.clear = () => {
474
- customTimers.clearTimeout.call(undefined, timer);
475
- timer = undefined;
476
- };
477
-
478
- return cancelablePromise;
479
- }
480
-
481
- // Port of lower_bound from https://en.cppreference.com/w/cpp/algorithm/lower_bound
482
- // Used to compute insertion index to keep queue sorted after insertion
483
- function lowerBound(array, value, comparator) {
484
- let first = 0;
485
- let count = array.length;
486
- while (count > 0) {
487
- const step = Math.trunc(count / 2);
488
- let it = first + step;
489
- if (comparator(array[it], value) <= 0) {
490
- first = ++it;
491
- count -= step + 1;
492
- }
493
- else {
494
- count = step;
495
- }
496
- }
497
- return first;
498
- }
499
-
500
- class PriorityQueue {
501
- #queue = [];
502
- enqueue(run, options) {
503
- options = {
504
- priority: 0,
505
- ...options,
506
- };
507
- const element = {
508
- priority: options.priority,
509
- run,
510
- };
511
- if (this.size && this.#queue[this.size - 1].priority >= options.priority) {
512
- this.#queue.push(element);
513
- return;
514
- }
515
- const index = lowerBound(this.#queue, element, (a, b) => b.priority - a.priority);
516
- this.#queue.splice(index, 0, element);
517
- }
518
- dequeue() {
519
- const item = this.#queue.shift();
520
- return item?.run;
521
- }
522
- filter(options) {
523
- return this.#queue.filter((element) => element.priority === options.priority).map((element) => element.run);
524
- }
525
- get size() {
526
- return this.#queue.length;
527
- }
528
- }
529
-
530
- /**
531
- Promise queue with concurrency control.
532
- */
533
- class PQueue extends EventEmitter {
534
- #carryoverConcurrencyCount;
535
- #isIntervalIgnored;
536
- #intervalCount = 0;
537
- #intervalCap;
538
- #interval;
539
- #intervalEnd = 0;
540
- #intervalId;
541
- #timeoutId;
542
- #queue;
543
- #queueClass;
544
- #pending = 0;
545
- // The `!` is needed because of https://github.com/microsoft/TypeScript/issues/32194
546
- #concurrency;
547
- #isPaused;
548
- #throwOnTimeout;
549
- /**
550
- Per-operation timeout in milliseconds. Operations fulfill once `timeout` elapses if they haven't already.
551
-
552
- Applies to each future operation.
553
- */
554
- timeout;
555
- // TODO: The `throwOnTimeout` option should affect the return types of `add()` and `addAll()`
556
- constructor(options) {
557
- super();
558
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
559
- options = {
560
- carryoverConcurrencyCount: false,
561
- intervalCap: Number.POSITIVE_INFINITY,
562
- interval: 0,
563
- concurrency: Number.POSITIVE_INFINITY,
564
- autoStart: true,
565
- queueClass: PriorityQueue,
566
- ...options,
567
- };
568
- if (!(typeof options.intervalCap === 'number' && options.intervalCap >= 1)) {
569
- throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${options.intervalCap?.toString() ?? ''}\` (${typeof options.intervalCap})`);
570
- }
571
- if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) {
572
- throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${options.interval?.toString() ?? ''}\` (${typeof options.interval})`);
573
- }
574
- this.#carryoverConcurrencyCount = options.carryoverConcurrencyCount;
575
- this.#isIntervalIgnored = options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0;
576
- this.#intervalCap = options.intervalCap;
577
- this.#interval = options.interval;
578
- this.#queue = new options.queueClass();
579
- this.#queueClass = options.queueClass;
580
- this.concurrency = options.concurrency;
581
- this.timeout = options.timeout;
582
- this.#throwOnTimeout = options.throwOnTimeout === true;
583
- this.#isPaused = options.autoStart === false;
584
- }
585
- get #doesIntervalAllowAnother() {
586
- return this.#isIntervalIgnored || this.#intervalCount < this.#intervalCap;
587
- }
588
- get #doesConcurrentAllowAnother() {
589
- return this.#pending < this.#concurrency;
590
- }
591
- #next() {
592
- this.#pending--;
593
- this.#tryToStartAnother();
594
- this.emit('next');
595
- }
596
- #onResumeInterval() {
597
- this.#onInterval();
598
- this.#initializeIntervalIfNeeded();
599
- this.#timeoutId = undefined;
600
- }
601
- get #isIntervalPaused() {
602
- const now = Date.now();
603
- if (this.#intervalId === undefined) {
604
- const delay = this.#intervalEnd - now;
605
- if (delay < 0) {
606
- // Act as the interval was done
607
- // We don't need to resume it here because it will be resumed on line 160
608
- this.#intervalCount = (this.#carryoverConcurrencyCount) ? this.#pending : 0;
609
- }
610
- else {
611
- // Act as the interval is pending
612
- if (this.#timeoutId === undefined) {
613
- this.#timeoutId = setTimeout(() => {
614
- this.#onResumeInterval();
615
- }, delay);
616
- }
617
- return true;
618
- }
619
- }
620
- return false;
621
- }
622
- #tryToStartAnother() {
623
- if (this.#queue.size === 0) {
624
- // We can clear the interval ("pause")
625
- // Because we can redo it later ("resume")
626
- if (this.#intervalId) {
627
- clearInterval(this.#intervalId);
628
- }
629
- this.#intervalId = undefined;
630
- this.emit('empty');
631
- if (this.#pending === 0) {
632
- this.emit('idle');
633
- }
634
- return false;
635
- }
636
- if (!this.#isPaused) {
637
- const canInitializeInterval = !this.#isIntervalPaused;
638
- if (this.#doesIntervalAllowAnother && this.#doesConcurrentAllowAnother) {
639
- const job = this.#queue.dequeue();
640
- if (!job) {
641
- return false;
642
- }
643
- this.emit('active');
644
- job();
645
- if (canInitializeInterval) {
646
- this.#initializeIntervalIfNeeded();
647
- }
648
- return true;
649
- }
650
- }
651
- return false;
652
- }
653
- #initializeIntervalIfNeeded() {
654
- if (this.#isIntervalIgnored || this.#intervalId !== undefined) {
655
- return;
656
- }
657
- this.#intervalId = setInterval(() => {
658
- this.#onInterval();
659
- }, this.#interval);
660
- this.#intervalEnd = Date.now() + this.#interval;
661
- }
662
- #onInterval() {
663
- if (this.#intervalCount === 0 && this.#pending === 0 && this.#intervalId) {
664
- clearInterval(this.#intervalId);
665
- this.#intervalId = undefined;
666
- }
667
- this.#intervalCount = this.#carryoverConcurrencyCount ? this.#pending : 0;
668
- this.#processQueue();
669
- }
670
- /**
671
- Executes all queued functions until it reaches the limit.
672
- */
673
- #processQueue() {
674
- // eslint-disable-next-line no-empty
675
- while (this.#tryToStartAnother()) { }
676
- }
677
- get concurrency() {
678
- return this.#concurrency;
679
- }
680
- set concurrency(newConcurrency) {
681
- if (!(typeof newConcurrency === 'number' && newConcurrency >= 1)) {
682
- throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${newConcurrency}\` (${typeof newConcurrency})`);
683
- }
684
- this.#concurrency = newConcurrency;
685
- this.#processQueue();
686
- }
687
- async #throwOnAbort(signal) {
688
- return new Promise((_resolve, reject) => {
689
- signal.addEventListener('abort', () => {
690
- reject(signal.reason);
691
- }, { once: true });
692
- });
693
- }
694
- async add(function_, options = {}) {
695
- options = {
696
- timeout: this.timeout,
697
- throwOnTimeout: this.#throwOnTimeout,
698
- ...options,
699
- };
700
- return new Promise((resolve, reject) => {
701
- this.#queue.enqueue(async () => {
702
- this.#pending++;
703
- this.#intervalCount++;
704
- try {
705
- options.signal?.throwIfAborted();
706
- let operation = function_({ signal: options.signal });
707
- if (options.timeout) {
708
- operation = pTimeout(Promise.resolve(operation), { milliseconds: options.timeout });
709
- }
710
- if (options.signal) {
711
- operation = Promise.race([operation, this.#throwOnAbort(options.signal)]);
712
- }
713
- const result = await operation;
714
- resolve(result);
715
- this.emit('completed', result);
716
- }
717
- catch (error) {
718
- if (error instanceof TimeoutError && !options.throwOnTimeout) {
719
- resolve();
720
- return;
721
- }
722
- reject(error);
723
- this.emit('error', error);
724
- }
725
- finally {
726
- this.#next();
727
- }
728
- }, options);
729
- this.emit('add');
730
- this.#tryToStartAnother();
731
- });
732
- }
733
- async addAll(functions, options) {
734
- return Promise.all(functions.map(async (function_) => this.add(function_, options)));
735
- }
736
- /**
737
- Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.)
738
- */
739
- start() {
740
- if (!this.#isPaused) {
741
- return this;
742
- }
743
- this.#isPaused = false;
744
- this.#processQueue();
745
- return this;
746
- }
747
- /**
748
- Put queue execution on hold.
749
- */
750
- pause() {
751
- this.#isPaused = true;
752
- }
753
- /**
754
- Clear the queue.
755
- */
756
- clear() {
757
- this.#queue = new this.#queueClass();
758
- }
759
- /**
760
- Can be called multiple times. Useful if you for example add additional items at a later time.
761
-
762
- @returns A promise that settles when the queue becomes empty.
763
- */
764
- async onEmpty() {
765
- // Instantly resolve if the queue is empty
766
- if (this.#queue.size === 0) {
767
- return;
768
- }
769
- await this.#onEvent('empty');
770
- }
771
- /**
772
- @returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`.
773
-
774
- If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item.
775
-
776
- Note that this only limits the number of items waiting to start. There could still be up to `concurrency` jobs already running that this call does not include in its calculation.
777
- */
778
- async onSizeLessThan(limit) {
779
- // Instantly resolve if the queue is empty.
780
- if (this.#queue.size < limit) {
781
- return;
782
- }
783
- await this.#onEvent('next', () => this.#queue.size < limit);
784
- }
785
- /**
786
- The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet.
787
-
788
- @returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`.
789
- */
790
- async onIdle() {
791
- // Instantly resolve if none pending and if nothing else is queued
792
- if (this.#pending === 0 && this.#queue.size === 0) {
793
- return;
794
- }
795
- await this.#onEvent('idle');
796
- }
797
- async #onEvent(event, filter) {
798
- return new Promise(resolve => {
799
- const listener = () => {
800
- if (filter && !filter()) {
801
- return;
802
- }
803
- this.off(event, listener);
804
- resolve();
805
- };
806
- this.on(event, listener);
807
- });
808
- }
809
- /**
810
- Size of the queue, the number of queued items waiting to run.
811
- */
812
- get size() {
813
- return this.#queue.size;
814
- }
815
- /**
816
- Size of the queue, filtered by the given options.
817
-
818
- For example, this can be used to find the number of items remaining in the queue with a specific priority level.
819
- */
820
- sizeBy(options) {
821
- // eslint-disable-next-line unicorn/no-array-callback-reference
822
- return this.#queue.filter(options).length;
823
- }
824
- /**
825
- Number of running items (no longer in the queue).
826
- */
827
- get pending() {
828
- return this.#pending;
829
- }
830
- /**
831
- Whether the queue is currently paused.
832
- */
833
- get isPaused() {
834
- return this.#isPaused;
835
- }
836
- }
837
-
838
- function buildLog(text, count) {
839
- console.log(`
840
- ${gray("[vite-react-ssg]")} ${yellow(text)}${count ? blue(` (${count})`) : ""}`);
841
- }
842
- function getSize(str) {
843
- return `${(str.length / 1024).toFixed(2)} KiB`;
844
- }
845
- async function routesToPaths(routes) {
846
- if (!routes || routes.length === 0)
847
- return { paths: ["/"] };
848
- const paths = /* @__PURE__ */ new Set();
849
- const getPaths = async (routes2, prefix = "") => {
850
- prefix = prefix.replace(/\/$/g, "");
851
- for (let route of routes2) {
852
- if (route.lazy) {
853
- const lazyData = await route.lazy();
854
- if (lazyData) {
855
- route = {
856
- ...route,
857
- ...lazyData
858
- };
859
- }
860
- }
861
- let path = route.path;
862
- path = handlePath(path, prefix);
863
- if (route.getStaticPaths && isDynamicSegmentsRoute(path)) {
864
- const staticPaths = await route.getStaticPaths();
865
- for (let staticPath of staticPaths) {
866
- staticPath = handlePath(staticPath, prefix);
867
- if (Array.isArray(route.children))
868
- await getPaths(route.children, staticPath);
869
- }
870
- }
871
- if (route.index && !path) {
872
- paths.add("/");
873
- }
874
- if (Array.isArray(route.children))
875
- await getPaths(route.children, path);
876
- }
877
- };
878
- await getPaths(routes);
879
- return { paths: Array.from(paths) };
880
- function handlePath(path, prefix) {
881
- if (path != null) {
882
- path = prefix && !path.startsWith("/") ? `${prefix}${path ? `/${path}` : ""}` : path;
883
- paths.add(path);
884
- }
885
- return path;
886
- }
887
- }
888
- async function resolveAlias(config, entry) {
889
- const resolver = config.createResolver();
890
- const result = await resolver(entry, config.root);
891
- return result || join(config.root, entry);
892
- }
893
- const { version } = JSON.parse(
894
- readFileSync(new URL("../package.json", import.meta.url)).toString()
895
- );
896
- function createRequest(path) {
897
- const url = new URL(path, "http://vite-react-ssg.com");
898
- url.search = "";
899
- url.hash = "";
900
- url.pathname = path;
901
- return new Request(url.href);
902
- }
903
- const dynamicRE = /[:*?]/;
904
- function isDynamicSegmentsRoute(route) {
905
- if (!route)
906
- return false;
907
- return dynamicRE.test(route);
908
- }
909
-
910
- async function getCritters(outDir, options = {}) {
911
- try {
912
- const CrittersClass = (await import('critters')).default;
913
- return new CrittersClass({
914
- path: outDir,
915
- logLevel: "warn",
916
- external: true,
917
- inlineFonts: true,
918
- preloadFonts: true,
919
- ...options
920
- });
921
- } catch (e) {
922
- return void 0;
923
- }
924
- }
925
-
926
- var __defProp = Object.defineProperty;
927
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
928
- var __publicField = (obj, key, value) => {
929
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
930
- return value;
931
- };
932
- async function renderStaticApp(app) {
933
- const writableStream = new WritableAsPromise();
934
- const { pipe } = renderToPipeableStream(app, {
935
- onError(error) {
936
- writableStream.destroy(error);
937
- },
938
- onAllReady() {
939
- pipe(writableStream);
940
- }
941
- });
942
- return writableStream.getPromise();
943
- }
944
- class WritableAsPromise extends Writable {
945
- constructor() {
946
- super();
947
- __publicField(this, "_output");
948
- __publicField(this, "_deferred");
949
- this._output = "";
950
- this._deferred = {
951
- promise: null,
952
- resolve: () => null,
953
- reject: () => null
954
- };
955
- this._deferred.promise = new Promise((resolve, reject) => {
956
- this._deferred.resolve = resolve;
957
- this._deferred.reject = reject;
958
- });
959
- }
960
- _write(chunk, _enc, next) {
961
- this._output += chunk.toString();
962
- next();
963
- }
964
- _destroy(error, next) {
965
- if (error instanceof Error)
966
- this._deferred.reject(error);
967
- else
968
- next();
969
- }
970
- end() {
971
- this._deferred.resolve(this._output);
972
- return this.destroy();
973
- }
974
- getPromise() {
975
- return this._deferred.promise;
976
- }
977
- }
978
-
979
- async function render(routesOrApp, request, styleCollector, basename) {
980
- const helmetContext = {};
981
- let inner;
982
- let context = null;
983
- if (Array.isArray(routesOrApp)) {
984
- const { StaticRouterProvider, createStaticHandler, createStaticRouter } = await import('react-router-dom/server.js');
985
- const { dataRoutes, query } = createStaticHandler(routesOrApp, { basename });
986
- const _context = await query(request);
987
- if (_context instanceof Response)
988
- throw _context;
989
- context = _context;
990
- const router = createStaticRouter(dataRoutes, context);
991
- inner = /* @__PURE__ */ React.createElement(StaticRouterProvider, { router, context });
992
- } else {
993
- inner = routesOrApp;
994
- }
995
- let app = /* @__PURE__ */ React.createElement(HelmetProvider, { context: helmetContext }, inner);
996
- if (styleCollector)
997
- app = styleCollector.collect(app);
998
- const appHTML = await renderStaticApp(app);
999
- const { htmlAttributes, bodyAttributes, metaAttributes, styleTag } = extractHelmet(helmetContext, styleCollector);
1000
- return { appHTML, htmlAttributes, bodyAttributes, metaAttributes, styleTag, routerContext: context };
1001
- }
1002
- function extractHelmet(context, styleCollector) {
1003
- const { helmet } = context;
1004
- const htmlAttributes = helmet.htmlAttributes.toString();
1005
- const bodyAttributes = helmet.bodyAttributes.toString();
1006
- let titleString = helmet.title.toString();
1007
- if (titleString.split(">")[1] === "</title") {
1008
- titleString = "";
1009
- }
1010
- const metaStrings = [
1011
- titleString,
1012
- helmet.meta.toString(),
1013
- helmet.link.toString(),
1014
- helmet.script.toString()
1015
- ];
1016
- const styleTag = styleCollector?.toString?.("") ?? "";
1017
- const metaAttributes = metaStrings.filter(Boolean);
1018
- return { htmlAttributes, bodyAttributes, metaAttributes, styleTag };
1019
- }
1020
-
1021
- const SCRIPT_COMMENT_PLACEHOLDER = "/* SCRIPT_COMMENT_PLACEHOLDER */";
1022
- async function renderHTML({
1023
- rootContainerId,
1024
- indexHTML,
1025
- appHTML,
1026
- metaAttributes,
1027
- bodyAttributes,
1028
- htmlAttributes,
1029
- initialState
1030
- }) {
1031
- const stateScript = initialState ? `
1032
- <script>window.__INITIAL_STATE__=${initialState}<\/script>` : "";
1033
- const scriptPlaceHolder = `
1034
- <script>${SCRIPT_COMMENT_PLACEHOLDER}<\/script>`;
1035
- const headStartTag = "<head>";
1036
- const metaTags = metaAttributes.join("");
1037
- indexHTML = indexHTML.replace(headStartTag, headStartTag + metaTags);
1038
- const bodyStartTag = "<body";
1039
- indexHTML = indexHTML.replace(bodyStartTag, `${bodyStartTag} ${bodyAttributes}`);
1040
- const htmlStartTag = "<html";
1041
- indexHTML = indexHTML.replace(htmlStartTag, `${htmlStartTag} ${htmlAttributes}`);
1042
- const container = `<div id="${rootContainerId}"></div>`;
1043
- if (indexHTML.includes(container)) {
1044
- return indexHTML.replace(
1045
- container,
1046
- `<div id="${rootContainerId}" data-server-rendered="true">${appHTML}</div>${stateScript}${scriptPlaceHolder}`
1047
- );
1048
- }
1049
- const html5Parser = await import('html5parser');
1050
- const ast = html5Parser.parse(indexHTML);
1051
- let renderedOutput;
1052
- html5Parser.walk(ast, {
1053
- enter: (node) => {
1054
- if (!renderedOutput && node?.type === html5Parser.SyntaxKind.Tag && Array.isArray(node.attributes) && node.attributes.length > 0 && node.attributes.some((attr) => attr.name.value === "id" && attr.value?.value === rootContainerId)) {
1055
- const attributesStringified = [...node.attributes.map(({ name: { value: name }, value }) => `${name}="${value.value}"`)].join(" ");
1056
- const indexHTMLBefore = indexHTML.slice(0, node.start);
1057
- const indexHTMLAfter = indexHTML.slice(node.end);
1058
- renderedOutput = `${indexHTMLBefore}<${node.name} ${attributesStringified} data-server-rendered="true">${appHTML}</${node.name}>${stateScript}${indexHTMLAfter}`;
1059
- }
1060
- }
1061
- });
1062
- if (!renderedOutput)
1063
- throw new Error(`Could not find a tag with id="${rootContainerId}" to replace it with server-side rendered HTML`);
1064
- return renderedOutput;
1065
- }
1066
- async function detectEntry(root) {
1067
- const scriptSrcReg = /<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/gim;
1068
- const html = await fs.readFile(join(root, "index.html"), "utf-8");
1069
- const scripts = [...html.matchAll(scriptSrcReg)];
1070
- const [, entry] = scripts.find((matchResult) => {
1071
- const [script] = matchResult;
1072
- const [, scriptType] = script.match(/.*\stype=(?:'|")?([^>'"\s]+)/i) || [];
1073
- return scriptType === "module";
1074
- }) || [];
1075
- return entry || "src/main.ts";
1076
- }
1077
- function createLink$1(href) {
1078
- return `<link rel="stylesheet" href="${href}">`;
1079
- }
1080
-
1081
- function renderPreloadLinks(document, assets) {
1082
- const seen = /* @__PURE__ */ new Set();
1083
- if (assets) {
1084
- assets.forEach((file) => {
1085
- if (!seen.has(file)) {
1086
- seen.add(file);
1087
- renderPreloadLink(document, file);
1088
- }
1089
- });
1090
- }
1091
- }
1092
- function renderPreloadLink(document, file) {
1093
- if (file.endsWith(".js")) {
1094
- appendLink(document, {
1095
- rel: "modulepreload",
1096
- crossOrigin: "",
1097
- href: file
1098
- });
1099
- } else if (file.endsWith(".css")) {
1100
- appendLink(document, {
1101
- rel: "stylesheet",
1102
- href: file,
1103
- crossOrigin: ""
1104
- });
1105
- } else if (file.endsWith(".woff") || file.endsWith(".woff2") || file.endsWith(".ttf")) {
1106
- appendLink(document, {
1107
- rel: "preload",
1108
- as: "font",
1109
- type: "font/woff2",
1110
- href: file,
1111
- crossOrigin: ""
1112
- });
1113
- } else if (file.endsWith(".png") || file.endsWith(".jpg") || file.endsWith(".jpeg") || file.endsWith(".webp") || file.endsWith(".gif") || file.endsWith(".ico") || file.endsWith(".svg")) {
1114
- appendLink(document, {
1115
- rel: "preload",
1116
- as: "image",
1117
- href: file,
1118
- crossOrigin: ""
1119
- });
1120
- }
1121
- }
1122
- function createLink(document) {
1123
- return document.createElement("link");
1124
- }
1125
- function setAttrs(el, attrs) {
1126
- const keys = Object.keys(attrs);
1127
- for (const key of keys)
1128
- el.setAttribute(key, attrs[key]);
1129
- }
1130
- function appendLink(document, attrs) {
1131
- const exits = document.head.querySelector(`link[href='${attrs.file}']`);
1132
- if (exits)
1133
- return;
1134
- const link = createLink(document);
1135
- setAttrs(link, attrs);
1136
- document.head.appendChild(link);
1137
- }
1138
-
1139
- const DYNAMIC_IMPORT_REGEX = /import\("([^)]+)"\)/g;
1140
- function collectAssets({
1141
- routes,
1142
- locationArg,
1143
- base,
1144
- serverManifest,
1145
- manifest,
1146
- ssrManifest
1147
- }) {
1148
- const matches = matchRoutes([...routes], locationArg, base);
1149
- const routeEntries = matches?.map((item) => item.route.entry).filter(Boolean) ?? [];
1150
- const dynamicImports = /* @__PURE__ */ new Set();
1151
- matches?.forEach((item) => {
1152
- let lazyStr = "";
1153
- if (item.route.lazy) {
1154
- lazyStr += item.route.lazy.toString();
1155
- }
1156
- if (item.route.Component?._payload?._result) {
1157
- lazyStr += item.route.Component._payload._result.toString();
1158
- }
1159
- const match = lazyStr.matchAll(DYNAMIC_IMPORT_REGEX);
1160
- for (const m of match) {
1161
- dynamicImports.add(m[1].split("/").at(-1) ?? "");
1162
- }
1163
- });
1164
- const entries = /* @__PURE__ */ new Set();
1165
- routeEntries.forEach((e) => entries.add(e));
1166
- const manifestEntries = [...Object.entries(serverManifest)];
1167
- dynamicImports.forEach((name) => {
1168
- const result = manifestEntries.find(([_, value]) => value.file.endsWith(name));
1169
- if (result) {
1170
- entries.add(result[0]);
1171
- }
1172
- });
1173
- const modules = collectModulesForEntries(manifest, entries);
1174
- const assets = /* @__PURE__ */ new Set();
1175
- Array.from(modules).forEach((id) => {
1176
- const files = ssrManifest[id] || [];
1177
- files.forEach((file) => {
1178
- assets.add(file);
1179
- });
1180
- });
1181
- return assets;
1182
- }
1183
- function collectModulesForEntries(manifest, entries) {
1184
- const mods = /* @__PURE__ */ new Set();
1185
- if (!entries)
1186
- return mods;
1187
- for (const entry of entries)
1188
- collectModules(manifest, entry, mods);
1189
- return mods;
1190
- }
1191
- function collectModules(manifest, entry, mods = /* @__PURE__ */ new Set()) {
1192
- if (!entry)
1193
- return mods;
1194
- mods.add(entry);
1195
- manifest[entry]?.dynamicImports?.forEach((item) => {
1196
- collectModules(manifest, item, mods);
1197
- });
1198
- return mods;
1199
- }
1200
-
1201
- const dotVitedir = Number.parseInt(version$1) >= 5 ? [".vite"] : [];
1202
- function DefaultIncludedRoutes(paths, _routes) {
1203
- return paths.filter((i) => !i.includes(":") && !i.includes("*"));
1204
- }
1205
- async function build(ssgOptions = {}, viteConfig = {}) {
1206
- const mode = process.env.MODE || process.env.NODE_ENV || ssgOptions.mode || "production";
1207
- const config = await resolveConfig(viteConfig, "build", mode, mode);
1208
- const cwd = process.cwd();
1209
- const root = config.root || cwd;
1210
- const hash = Math.random().toString(36).substring(2, 12);
1211
- const ssgOut = join(root, ".vite-react-ssg-temp", hash);
1212
- const outDir = config.build.outDir || "dist";
1213
- const out = isAbsolute(outDir) ? outDir : join(root, outDir);
1214
- const configBase = config.base;
1215
- const {
1216
- script = "sync",
1217
- mock = false,
1218
- entry = await detectEntry(root),
1219
- formatting = "none",
1220
- crittersOptions = {},
1221
- includedRoutes: configIncludedRoutes = DefaultIncludedRoutes,
1222
- onBeforePageRender,
1223
- onPageRendered,
1224
- onFinished,
1225
- dirStyle = "flat",
1226
- includeAllRoutes = false,
1227
- format = "esm",
1228
- concurrency = 20,
1229
- rootContainerId = "root"
1230
- } = Object.assign({}, config.ssgOptions || {}, ssgOptions);
1231
- if (fs.existsSync(ssgOut))
1232
- await fs.remove(ssgOut);
1233
- const clientLogger = createLogger();
1234
- const loggerWarn = clientLogger.warn;
1235
- clientLogger.warn = (msg, options) => {
1236
- if (msg.includes("vite:resolve") && msg.includes("externalized for browser compatibility"))
1237
- return;
1238
- loggerWarn(msg, options);
1239
- };
1240
- buildLog("Build for client...");
1241
- await build$1(mergeConfig(viteConfig, {
1242
- build: {
1243
- manifest: true,
1244
- ssrManifest: true,
1245
- rollupOptions: {
1246
- input: {
1247
- app: join(root, "./index.html")
1248
- },
1249
- // @ts-expect-error rollup type
1250
- onLog(level, log, handler) {
1251
- if (log.message.includes("react-helmet-async"))
1252
- return;
1253
- handler(level, log);
1254
- }
1255
- }
1256
- },
1257
- customLogger: clientLogger,
1258
- mode: config.mode,
1259
- ssr: { noExternal: ["vite-react-ssg"] }
1260
- }));
1261
- if (mock) {
1262
- const { jsdomGlobal } = await import('./chunks/jsdomGlobal.mjs');
1263
- jsdomGlobal();
1264
- }
1265
- buildLog("Build for server...");
1266
- process.env.VITE_SSG = "true";
1267
- const ssrEntry = await resolveAlias(config, entry);
1268
- await build$1(mergeConfig(viteConfig, {
1269
- build: {
1270
- ssr: ssrEntry,
1271
- manifest: true,
1272
- outDir: ssgOut,
1273
- minify: false,
1274
- cssCodeSplit: false,
1275
- rollupOptions: {
1276
- output: format === "esm" ? {
1277
- entryFileNames: "[name].mjs",
1278
- format: "esm"
1279
- } : {
1280
- entryFileNames: "[name].cjs",
1281
- format: "cjs"
1282
- }
1283
- }
1284
- },
1285
- mode: config.mode,
1286
- ssr: { noExternal: ["vite-react-ssg"] }
1287
- }));
1288
- const prefix = format === "esm" && process.platform === "win32" ? "file://" : "";
1289
- const ext = format === "esm" ? ".mjs" : ".cjs";
1290
- const serverEntry = join(prefix, ssgOut, parse(ssrEntry).name + ext);
1291
- const serverManifest = JSON.parse(await fs.readFile(join(ssgOut, ...dotVitedir, "manifest.json"), "utf-8"));
1292
- const _require = createRequire(import.meta.url);
1293
- const { createRoot, includedRoutes: serverEntryIncludedRoutes } = format === "esm" ? await import(serverEntry) : _require(serverEntry);
1294
- const includedRoutes = serverEntryIncludedRoutes || configIncludedRoutes;
1295
- const { routes } = await createRoot(false);
1296
- const { paths } = await routesToPaths(routes);
1297
- let routesPaths = includeAllRoutes ? paths : await includedRoutes(paths, routes || []);
1298
- routesPaths = DefaultIncludedRoutes(routesPaths);
1299
- routesPaths = Array.from(new Set(routesPaths));
1300
- buildLog("Rendering Pages...", routesPaths.length);
1301
- const critters = crittersOptions !== false ? await getCritters(outDir, { publicPath: configBase, ...crittersOptions }) : void 0;
1302
- if (critters)
1303
- console.log(`${gray("[vite-react-ssg]")} ${blue("Critical CSS generation enabled via `critters`")}`);
1304
- const ssrManifest = JSON.parse(await fs.readFile(join(out, ...dotVitedir, "ssr-manifest.json"), "utf-8"));
1305
- const manifest = JSON.parse(await fs.readFile(join(out, ...dotVitedir, "manifest.json"), "utf-8"));
1306
- let indexHTML = await fs.readFile(join(out, "index.html"), "utf-8");
1307
- indexHTML = rewriteScripts(indexHTML, script);
1308
- const queue = new PQueue({ concurrency });
1309
- const crittersQueue = new PQueue({ concurrency: 1 });
1310
- const staticLoaderDataManifest = {};
1311
- for (const path of routesPaths) {
1312
- queue.add(async () => {
1313
- try {
1314
- const appCtx = await createRoot(false, path);
1315
- const { initialState, base, routes: routes2, triggerOnSSRAppRendered, transformState = serializeState, getStyleCollector, app } = appCtx;
1316
- const styleCollector = getStyleCollector ? await getStyleCollector() : null;
1317
- const transformedIndexHTML = await onBeforePageRender?.(path, indexHTML, appCtx) || indexHTML;
1318
- const fetchUrl = `${withTrailingSlash(base)}${removeLeadingSlash(path)}`;
1319
- const request = createRequest(fetchUrl);
1320
- const assets = !app ? collectAssets({ routes: [...routes2], locationArg: fetchUrl, base, serverManifest, manifest, ssrManifest }) : /* @__PURE__ */ new Set();
1321
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render(app ?? [...routes2], request, styleCollector, base);
1322
- staticLoaderDataManifest[path] = routerContext?.loaderData;
1323
- await triggerOnSSRAppRendered?.(path, appHTML, appCtx);
1324
- const renderedHTML = await renderHTML({
1325
- rootContainerId,
1326
- appHTML,
1327
- indexHTML: transformedIndexHTML,
1328
- metaAttributes,
1329
- bodyAttributes,
1330
- htmlAttributes,
1331
- initialState: null
1332
- });
1333
- const jsdom = new JSDOM(renderedHTML);
1334
- renderPreloadLinks(jsdom.window.document, assets);
1335
- const html = jsdom.serialize();
1336
- let transformed = await onPageRendered?.(path, html, appCtx) || html;
1337
- transformed = transformed.replace(SCRIPT_COMMENT_PLACEHOLDER, `window.__VITE_REACT_SSG_HASH__ = '${hash}'`);
1338
- if (critters) {
1339
- transformed = await crittersQueue.add(() => critters.process(transformed));
1340
- transformed = transformed.replace(/<link\srel="stylesheet"/g, '<link rel="stylesheet" crossorigin');
1341
- }
1342
- if (styleTag)
1343
- transformed = transformed.replace("<head>", `<head>${styleTag}`);
1344
- const formatted = await formatHtml(transformed, formatting);
1345
- const relativeRouteFile = `${(path.endsWith("/") ? `${path}index` : path).replace(/^\//g, "")}.html`;
1346
- const filename = dirStyle === "nested" ? join(path.replace(/^\//g, ""), "index.html") : relativeRouteFile;
1347
- await fs.ensureDir(join(out, dirname(filename)));
1348
- await fs.writeFile(join(out, filename), formatted, "utf-8");
1349
- config.logger.info(
1350
- `${dim(`${outDir}/`)}${cyan(filename.padEnd(15, " "))} ${dim(getSize(formatted))}`
1351
- );
1352
- } catch (err) {
1353
- throw new Error(`${gray("[vite-react-ssg]")} ${red(`Error on page: ${cyan(path)}`)}
1354
- ${err.stack}`);
1355
- }
1356
- });
1357
- }
1358
- await queue.start().onIdle();
1359
- buildLog("Generating static loader data manifest...");
1360
- const staticLoaderDataManifestString = JSON.stringify(staticLoaderDataManifest, null, 0);
1361
- await fs.writeFile(join(out, `static-loader-data-manifest-${hash}.json`), staticLoaderDataManifestString);
1362
- config.logger.info(
1363
- `${dim(`${outDir}/`)}${cyan(`static-loader-data-manifest-${hash}.json`.padEnd(15, " "))} ${dim(getSize(staticLoaderDataManifestString))}`
1364
- );
1365
- await fs.remove(join(root, ".vite-react-ssg-temp"));
1366
- const pwaPlugin = config.plugins.find((i) => i.name === "vite-plugin-pwa")?.api;
1367
- if (pwaPlugin && !pwaPlugin.disabled && pwaPlugin.generateSW) {
1368
- buildLog("Regenerate PWA...");
1369
- await pwaPlugin.generateSW();
1370
- }
1371
- console.log(`
1372
- ${gray("[vite-react-ssg]")} ${green("Build finished.")}`);
1373
- await onFinished?.();
1374
- const waitInSeconds = 15;
1375
- const timeout = setTimeout(() => {
1376
- console.log(`${gray("[vite-react-ssg]")} ${yellow(`Build process still running after ${waitInSeconds}s`)}. There might be something misconfigured in your setup. Force exit.`);
1377
- process.exit(0);
1378
- }, waitInSeconds * 1e3);
1379
- timeout.unref();
1380
- }
1381
- function rewriteScripts(indexHTML, mode) {
1382
- if (!mode || mode === "sync")
1383
- return indexHTML;
1384
- return indexHTML.replace(/<script type="module" /g, `<script type="module" ${mode} `);
1385
- }
1386
- async function formatHtml(html, formatting) {
1387
- if (formatting === "prettify") {
1388
- try {
1389
- const prettier = (await import('prettier/esm/standalone.mjs')).default;
1390
- const parserHTML = (await import('prettier/esm/parser-html.mjs')).default;
1391
- return prettier.format(html, { semi: false, parser: "html", plugins: [parserHTML] });
1392
- } catch (e) {
1393
- console.error(`${gray("[vite-react-ssg]")} ${red(`Error formatting html: ${e?.message}`)}`);
1394
- return html;
1395
- }
1396
- }
1397
- return html;
1398
- }
1399
-
1400
- function invariant(value, message) {
1401
- if (value === false || value === null || typeof value === "undefined") {
1402
- console.error(
1403
- "The following error is a bug in Vite-react-ssg; please open an issue! https://github.com/Daydreamer-riri/vite-react-ssg/issues/new"
1404
- );
1405
- throw new Error(message);
1406
- }
1407
- }
1408
-
1409
- function fromNodeHeaders(nodeHeaders) {
1410
- const headers = new Headers();
1411
- for (const [key, values] of Object.entries(nodeHeaders)) {
1412
- if (values) {
1413
- if (Array.isArray(values)) {
1414
- for (const value of values)
1415
- headers.append(key, value);
1416
- } else {
1417
- headers.set(key, values);
1418
- }
1419
- }
1420
- }
1421
- return headers;
1422
- }
1423
- function fromNodeRequest(nodeReq) {
1424
- const origin = nodeReq.headers.origin && nodeReq.headers.origin !== "null" ? nodeReq.headers.origin : `http://${nodeReq.headers.host}`;
1425
- invariant(
1426
- nodeReq.originalUrl,
1427
- "Expected `nodeReq.originalUrl` to be defined"
1428
- );
1429
- const url = new URL(nodeReq.originalUrl, origin);
1430
- const init = {
1431
- method: nodeReq.method,
1432
- headers: fromNodeHeaders(nodeReq.headers)
1433
- };
1434
- return new Request(url.href, init);
1435
- }
1436
- async function toNodeRequest(res, nodeRes) {
1437
- nodeRes.statusCode = res.status;
1438
- nodeRes.statusMessage = res.statusText;
1439
- for (const [name, value] of res.headers) {
1440
- nodeRes.setHeader(name, value);
1441
- }
1442
- if (res.body) {
1443
- const responseBody = res.body;
1444
- const readable = Readable.from(responseBody);
1445
- readable.pipe(nodeRes);
1446
- await once(readable, "end");
1447
- } else {
1448
- nodeRes.end();
1449
- }
1450
- }
1451
-
1452
- function ssrServerPlugin({
1453
- template,
1454
- ssrEntry,
1455
- onBeforePageRender,
1456
- entry,
1457
- rootContainerId,
1458
- onPageRendered
1459
- }) {
1460
- return {
1461
- name: "vite-react-ssg:dev-server-remix",
1462
- configureServer(server) {
1463
- const renderMiddleware = async (req, res, _next) => {
1464
- try {
1465
- const url = req.originalUrl;
1466
- const createRoot = await server.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
1467
- const appCtx = await createRoot(false, url);
1468
- const { routes, getStyleCollector, base, app } = appCtx;
1469
- const searchParams = new URLSearchParams(url.split("?")[1]);
1470
- if (!app && searchParams.has("_data")) {
1471
- const request = fromNodeRequest(req);
1472
- const url2 = new URL(request.url);
1473
- const routeId = decodeURIComponent(searchParams.get("_data"));
1474
- const matches = matchRoutes(
1475
- convertRoutesToDataRoutes([...routes], (route) => route),
1476
- {
1477
- pathname: url2.pathname,
1478
- search: url2.search,
1479
- hash: url2.hash,
1480
- state: null,
1481
- key: "default"
1482
- },
1483
- base
1484
- );
1485
- if (!matches) {
1486
- res.statusCode = 404;
1487
- res.end(`Route not found: ${routeId}`);
1488
- return;
1489
- }
1490
- const match = matches.find((m) => m.route.id === routeId);
1491
- if (!match) {
1492
- res.statusCode = 404;
1493
- res.end(`Route not found: ${routeId}`);
1494
- return;
1495
- }
1496
- const loader = match.route.loader ?? await match.route.lazy?.().then((m) => m.loader);
1497
- if (!loader) {
1498
- res.statusCode = 200;
1499
- res.end(`There is no loader for the route: ${routeId}`);
1500
- return;
1501
- }
1502
- const response = await callRouteLoader({
1503
- loader,
1504
- params: match.params,
1505
- request,
1506
- routeId
1507
- });
1508
- await toNodeRequest(response, res);
1509
- return;
1510
- }
1511
- const indexHTML = await server.transformIndexHtml(url, template);
1512
- const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
1513
- const styleCollector = getStyleCollector ? await getStyleCollector() : null;
1514
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render(app ?? [...routes], fromNodeRequest(req), styleCollector, base);
1515
- metaAttributes.push(styleTag);
1516
- const mods = await Promise.all(
1517
- [ssrEntry, entry].map(async (entry2) => await server.moduleGraph.getModuleByUrl(entry2))
1518
- );
1519
- const assetsUrls = /* @__PURE__ */ new Set();
1520
- const collectAssets = async (mod) => {
1521
- if (!mod || !mod?.ssrTransformResult)
1522
- return;
1523
- const { deps = [], dynamicDeps = [] } = mod?.ssrTransformResult;
1524
- const allDeps = [...deps, ...dynamicDeps];
1525
- for (const dep of allDeps) {
1526
- if (dep.endsWith(".css") || dep.endsWith(".scss") || dep.endsWith(".sass") || dep.endsWith(".less")) {
1527
- assetsUrls.add(dep);
1528
- } else if (dep.endsWith(".ts") || dep.endsWith(".tsx")) {
1529
- const depModule = await server.moduleGraph.getModuleByUrl(dep);
1530
- depModule && await collectAssets(depModule);
1531
- }
1532
- }
1533
- };
1534
- await Promise.all(mods.map(async (mod) => collectAssets(mod)));
1535
- const preloadLink = [...assetsUrls].map((item) => createLink$1(joinUrlSegments(server.config.base, item)));
1536
- metaAttributes.push(...preloadLink);
1537
- const renderedHTML = await renderHTML({
1538
- rootContainerId,
1539
- appHTML,
1540
- indexHTML: transformedIndexHTML,
1541
- metaAttributes,
1542
- bodyAttributes,
1543
- htmlAttributes,
1544
- initialState: null
1545
- });
1546
- const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
1547
- res.statusCode = 200;
1548
- res.setHeader("Content-Type", "text/html");
1549
- const isDev = "pluginContainer" in server;
1550
- const headers = isDev ? server.config.server.headers : server.config.preview.headers;
1551
- send(req, res, transformed, "html", { headers });
1552
- } catch (e) {
1553
- server.ssrFixStacktrace(e);
1554
- console.error(`[vite-react-ssg] error: ${e.stack}`);
1555
- res.statusCode = 500;
1556
- res.end(e.stack);
1557
- }
1558
- };
1559
- return () => {
1560
- server.middlewares.use(renderMiddleware);
1561
- };
1562
- }
1563
- };
1564
- }
1565
- async function callRouteLoader({
1566
- // loadContext,
1567
- loader,
1568
- params,
1569
- request,
1570
- routeId
1571
- // singleFetch,
1572
- // response,
1573
- }) {
1574
- const result = await loader({
1575
- request: stripDataParam(stripIndexParam(request)),
1576
- // context: loadContext,
1577
- params
1578
- // Only provided when single fetch is enabled, and made available via
1579
- // `defineLoader` types, not `LoaderFunctionArgs`
1580
- // ...(singleFetch ? { response } : null),
1581
- });
1582
- if (result === void 0) {
1583
- throw new Error(
1584
- `You defined a loader for route "${routeId}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`
1585
- );
1586
- }
1587
- return isResponse(result) ? result : json(result);
1588
- }
1589
- function isResponse(value) {
1590
- return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
1591
- }
1592
- function stripIndexParam(request) {
1593
- const url = new URL(request.url);
1594
- const indexValues = url.searchParams.getAll("index");
1595
- url.searchParams.delete("index");
1596
- const indexValuesToKeep = [];
1597
- for (const indexValue of indexValues) {
1598
- if (indexValue) {
1599
- indexValuesToKeep.push(indexValue);
1600
- }
1601
- }
1602
- for (const toKeep of indexValuesToKeep) {
1603
- url.searchParams.append("index", toKeep);
1604
- }
1605
- const init = {
1606
- method: request.method,
1607
- body: request.body,
1608
- headers: request.headers,
1609
- signal: request.signal
1610
- };
1611
- if (init.body) {
1612
- init.duplex = "half";
1613
- }
1614
- return new Request(url.href, init);
1615
- }
1616
- function stripDataParam(request) {
1617
- const url = new URL(request.url);
1618
- url.searchParams.delete("_data");
1619
- const init = {
1620
- method: request.method,
1621
- body: request.body,
1622
- headers: request.headers,
1623
- signal: request.signal
1624
- };
1625
- if (init.body) {
1626
- init.duplex = "half";
1627
- }
1628
- return new Request(url.href, init);
1629
- }
1630
-
1631
- async function dev(ssgOptions = {}, viteConfig = {}, customOptions) {
1632
- const mode = process.env.MODE || process.env.NODE_ENV || ssgOptions.mode || "development";
1633
- const config = await resolveConfig(viteConfig, "serve", mode, mode);
1634
- const cwd = process.cwd();
1635
- const root = config.root || cwd;
1636
- const {
1637
- entry = await detectEntry(root),
1638
- onBeforePageRender,
1639
- onPageRendered,
1640
- rootContainerId = "root",
1641
- mock = false
1642
- } = Object.assign({}, config.ssgOptions || {}, ssgOptions);
1643
- const ssrEntry = await resolveAlias(config, entry);
1644
- const template = await fs.readFile(join(root, "index.html"), "utf-8");
1645
- let viteServer;
1646
- globalThis.__ssr_start_time = performance.now();
1647
- createServer$1().catch((err) => {
1648
- console.error(
1649
- `${red(`failed to start server. error:`)}
1650
- ${err.stack}`
1651
- );
1652
- process.exit(1);
1653
- });
1654
- async function createServer$1() {
1655
- process.env.__DEV_MODE_SSR = "true";
1656
- if (mock) {
1657
- const { jsdomGlobal } = await import('./chunks/jsdomGlobal.mjs');
1658
- jsdomGlobal();
1659
- }
1660
- viteServer = await createServer({
1661
- ...viteConfig,
1662
- plugins: [
1663
- ...viteConfig.plugins ?? [],
1664
- ssrServerPlugin({
1665
- template,
1666
- ssrEntry,
1667
- onBeforePageRender,
1668
- onPageRendered,
1669
- entry,
1670
- rootContainerId
1671
- })
1672
- ]
1673
- });
1674
- await viteServer.listen();
1675
- printServerInfo(viteServer, !!customOptions);
1676
- viteServer.bindCLIShortcuts({ print: true });
1677
- return viteServer;
1678
- }
1679
- }
1680
- async function printServerInfo(server, onlyUrl = false) {
1681
- if (onlyUrl)
1682
- return server.printUrls();
1683
- const info = server.config.logger.info;
1684
- let ssrReadyMessage = " -- SSR";
1685
- if (globalThis.__ssr_start_time) {
1686
- ssrReadyMessage += ` ready in ${reset(bold(`${Math.round(
1687
- // @ts-expect-error global var
1688
- performance.now() - globalThis.__ssr_start_time
1689
- )}ms`))}`;
1690
- }
1691
- info(
1692
- `
1693
- ${bgLightCyan(` VITE-REACT-SSG v${version} `)}`,
1694
- { clear: !server.config.logger.hasWarned }
1695
- );
1696
- info(
1697
- `${cyan(`
1698
- VITE v${version$1}`) + dim(ssrReadyMessage)}
1699
- `
1700
- );
1701
- info(
1702
- green(" dev server running at:")
1703
- );
1704
- server.printUrls();
1705
- }
1706
-
1707
- export { build, dev };
1
+ export { b as build, d as dev } from './shared/vite-react-ssg.BoLst82g.mjs';
2
+ import 'node:path';
3
+ import 'node:module';
4
+ import 'kolorist';
5
+ import 'p-queue';
6
+ import 'fs-extra';
7
+ import 'vite';
8
+ import 'jsdom';
9
+ import './shared/vite-react-ssg.C6pK7rvr.mjs';
10
+ import './shared/vite-react-ssg.CjIppNIS.mjs';
11
+ import 'react/jsx-runtime';
12
+ import 'react-helmet-async';
13
+ import 'node:stream';
14
+ import 'react-dom/server';
15
+ import 'node:events';
16
+ import './shared/vite-react-ssg.C0y5wbxl.mjs';
17
+ import './shared/vite-react-ssg.4y2OEiyV.mjs';