@absolutejs/absolute 0.19.0-beta.695 → 0.19.0-beta.697

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 (39) hide show
  1. package/README.md +1 -1
  2. package/dist/angular/browser.js +48 -40
  3. package/dist/angular/browser.js.map +4 -4
  4. package/dist/angular/index.js +2308 -2232
  5. package/dist/angular/index.js.map +14 -13
  6. package/dist/angular/server.js +2279 -2203
  7. package/dist/angular/server.js.map +14 -14
  8. package/dist/build.js +42796 -6393
  9. package/dist/build.js.map +9 -20
  10. package/dist/cli/index.js +9 -2
  11. package/dist/core/streamingSlotRegistrar.js +24 -16
  12. package/dist/core/streamingSlotRegistrar.js.map +2 -2
  13. package/dist/core/streamingSlotRegistry.js +42 -29
  14. package/dist/core/streamingSlotRegistry.js.map +2 -2
  15. package/dist/index.js +42693 -5631
  16. package/dist/index.js.map +19 -24
  17. package/dist/react/components/index.js +24 -16
  18. package/dist/react/components/index.js.map +2 -2
  19. package/dist/react/index.js +922 -868
  20. package/dist/react/index.js.map +12 -12
  21. package/dist/react/server.js +903 -848
  22. package/dist/react/server.js.map +11 -11
  23. package/dist/src/build/compileTailwind.d.ts +3 -0
  24. package/dist/src/core/pageHandlers.d.ts +0 -2
  25. package/dist/src/core/ssrCache.d.ts +3 -0
  26. package/dist/svelte/index.js +963 -899
  27. package/dist/svelte/index.js.map +14 -13
  28. package/dist/svelte/server.js +777 -712
  29. package/dist/svelte/server.js.map +12 -12
  30. package/dist/types/build.d.ts +5 -4
  31. package/dist/types/index.d.ts +0 -1
  32. package/dist/types/island.d.ts +14 -11
  33. package/dist/vue/components/index.js +24 -16
  34. package/dist/vue/components/index.js.map +2 -2
  35. package/dist/vue/index.js +1040 -976
  36. package/dist/vue/index.js.map +12 -12
  37. package/dist/vue/server.js +908 -841
  38. package/dist/vue/server.js.map +11 -11
  39. package/package.json +16 -8
@@ -78,99 +78,6 @@ var __legacyMetadataTS = (k, v) => {
78
78
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
79
79
  var __require = import.meta.require;
80
80
 
81
- // src/core/streamingSlotRegistrar.ts
82
- var STREAMING_SLOT_REGISTRAR_KEY, STREAMING_SLOT_WARNING_STORAGE_KEY, STREAMING_SLOT_COLLECTION_STORAGE_KEY, getRegisteredStreamingSlotRegistrar = () => {
83
- const value = Reflect.get(globalThis, STREAMING_SLOT_REGISTRAR_KEY);
84
- if (typeof value === "function" || value === null) {
85
- return value;
86
- }
87
- return;
88
- }, isObjectRecord = (value) => Boolean(value) && typeof value === "object", isStreamingSlotWarningController = (value) => isObjectRecord(value) && ("maybeWarn" in value) && typeof value.maybeWarn === "function", isStreamingSlotCollectionController = (value) => isObjectRecord(value) && ("isCollecting" in value) && typeof value.isCollecting === "function", getWarningController = () => {
89
- const value = Reflect.get(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY);
90
- if (value === null || typeof value === "undefined")
91
- return;
92
- return isStreamingSlotWarningController(value) ? value : undefined;
93
- }, getCollectionController = () => {
94
- const value = Reflect.get(globalThis, STREAMING_SLOT_COLLECTION_STORAGE_KEY);
95
- if (value === null || typeof value === "undefined")
96
- return;
97
- return isStreamingSlotCollectionController(value) ? value : undefined;
98
- }, hasRegisteredStreamingSlotRegistrar = () => typeof getRegisteredStreamingSlotRegistrar() === "function", isStreamingSlotCollectionActive = () => getCollectionController()?.isCollecting() === true, registerStreamingSlot = (slot) => {
99
- getRegisteredStreamingSlotRegistrar()?.(slot);
100
- }, setStreamingSlotCollectionController = (controller) => {
101
- Reflect.set(globalThis, STREAMING_SLOT_COLLECTION_STORAGE_KEY, controller);
102
- }, setStreamingSlotRegistrar = (nextRegistrar) => {
103
- Reflect.set(globalThis, STREAMING_SLOT_REGISTRAR_KEY, nextRegistrar);
104
- }, setStreamingSlotWarningController = (controller) => {
105
- Reflect.set(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY, controller);
106
- }, warnMissingStreamingSlotCollector = (primitiveName) => {
107
- if (isStreamingSlotCollectionActive()) {
108
- return;
109
- }
110
- getWarningController()?.maybeWarn(primitiveName);
111
- };
112
- var init_streamingSlotRegistrar = __esm(() => {
113
- STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
114
- STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
115
- STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
116
- });
117
-
118
- // src/core/streamingSlotRegistry.ts
119
- var STREAMING_SLOT_STORAGE_KEY, isObjectRecord2 = (value) => Boolean(value) && typeof value === "object", isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function", getStorageGlobal = () => {
120
- const value = Reflect.get(globalThis, STREAMING_SLOT_STORAGE_KEY);
121
- if (value === null || typeof value === "undefined") {
122
- return value;
123
- }
124
- return isAsyncLocalStorage(value) ? value : undefined;
125
- }, isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string", ensureAsyncLocalStorage = async () => {
126
- const storage = getStorageGlobal();
127
- if (typeof storage !== "undefined") {
128
- return storage;
129
- }
130
- if (!isServerRuntime()) {
131
- Reflect.set(globalThis, STREAMING_SLOT_STORAGE_KEY, null);
132
- return getStorageGlobal();
133
- }
134
- const mod = await import("async_hooks");
135
- Reflect.set(globalThis, STREAMING_SLOT_STORAGE_KEY, new mod.AsyncLocalStorage);
136
- return getStorageGlobal();
137
- }, getActiveSlotStore = () => {
138
- const storage = getStorageGlobal();
139
- if (!storage)
140
- return;
141
- return storage.getStore();
142
- }, registerStreamingSlot2 = (slot) => {
143
- const store = getActiveSlotStore();
144
- if (!store)
145
- return;
146
- store.set(slot.id, slot);
147
- }, hasActiveStreamingSlotRegistry = () => getActiveSlotStore() !== undefined, runWithStreamingSlotRegistry = async (task) => {
148
- const storage = await ensureAsyncLocalStorage();
149
- if (!storage) {
150
- const slots = [];
151
- return {
152
- result: await task(),
153
- slots
154
- };
155
- }
156
- return storage.run(new Map, async () => {
157
- const result = await task();
158
- const store = storage.getStore();
159
- return {
160
- result,
161
- slots: store ? [...store.values()] : []
162
- };
163
- });
164
- };
165
- var init_streamingSlotRegistry = __esm(() => {
166
- init_streamingSlotRegistrar();
167
- STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
168
- setStreamingSlotRegistrar(registerStreamingSlot2);
169
- setStreamingSlotCollectionController({
170
- isCollecting: () => getActiveSlotStore() !== undefined
171
- });
172
- });
173
-
174
81
  // src/constants.ts
175
82
  var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HTTP_STATUS_OK = 200, HTTP_STATUS_BAD_REQUEST = 400, HTTP_STATUS_NOT_FOUND = 404, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, REACT_STREAM_SLOT_FAST_DELAY_MS = 5, REACT_STREAM_SLOT_SLOW_DELAY_MS = 20, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000;
176
83
  var init_constants = __esm(() => {
@@ -179,332 +86,134 @@ var init_constants = __esm(() => {
179
86
  TWO_THIRDS = 2 / 3;
180
87
  });
181
88
 
182
- // src/core/islandPageContext.ts
183
- var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="true"', MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__", ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__", CLOSING_HEAD_TAG = "</head>", buildIslandsHeadMarkup = (manifest) => {
184
- const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
185
- const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
186
- const bootstrapPath = manifest[BOOTSTRAP_MANIFEST_KEY];
187
- const bootstrapScript = bootstrapPath ? `<script type="module" src="${bootstrapPath}"></script>` : "";
188
- return `${manifestScript}${islandStateScript}${bootstrapScript}`;
189
- }, injectHeadMarkup = (html, markup) => {
190
- const closingHeadIndex = html.indexOf("</head>");
191
- if (closingHeadIndex >= 0) {
192
- return `${html.slice(0, closingHeadIndex)}${markup}${html.slice(closingHeadIndex)}`;
89
+ // src/core/devRouteRegistrationCallsite.ts
90
+ var exports_devRouteRegistrationCallsite = {};
91
+ __export(exports_devRouteRegistrationCallsite, {
92
+ patchElysiaRouteRegistrationCallsites: () => patchElysiaRouteRegistrationCallsites,
93
+ getCurrentRouteRegistrationCallsite: () => getCurrentRouteRegistrationCallsite
94
+ });
95
+ import { AsyncLocalStorage } from "async_hooks";
96
+ import { Elysia } from "elysia";
97
+ var ROUTE_CALLSITE_STORAGE_KEY, ROUTE_CALLSITE_PATCHED_KEY, ROUTE_METHOD_NAMES, isObjectRecord3 = (value) => Boolean(value) && typeof value === "object", isAsyncLocalStorage2 = (value) => isObjectRecord3(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function", getRouteCallsiteStorage = () => {
98
+ const value = Reflect.get(globalThis, ROUTE_CALLSITE_STORAGE_KEY);
99
+ if (value === null || typeof value === "undefined") {
100
+ return;
193
101
  }
194
- const openingBodyIndex = html.indexOf("<body");
195
- if (openingBodyIndex >= 0) {
196
- const bodyStart = html.indexOf(">", openingBodyIndex);
197
- if (bodyStart >= 0) {
198
- return `${html.slice(0, openingBodyIndex)}<head>${markup}</head>${html.slice(openingBodyIndex)}`;
102
+ return isAsyncLocalStorage2(value) ? value : undefined;
103
+ }, ensureRouteCallsiteStorage = () => {
104
+ const existing = getRouteCallsiteStorage();
105
+ if (existing) {
106
+ return existing;
107
+ }
108
+ const storage = new AsyncLocalStorage;
109
+ Reflect.set(globalThis, ROUTE_CALLSITE_STORAGE_KEY, storage);
110
+ return storage;
111
+ }, normalizeCallsitePath = (value) => value.replace(`${process.cwd()}/`, "").replace(process.cwd(), "").replace(/^\.\/+/, ""), extractRouteRegistrationCallsite = (stack) => {
112
+ const frames = stack.split(`
113
+ `).slice(1).map((line) => line.trim());
114
+ for (const frame of frames) {
115
+ if (frame.includes("/node_modules/") || frame.includes("/dist/") || frame.includes("/src/core/devRouteRegistrationCallsite.")) {
116
+ continue;
117
+ }
118
+ const locationMatch = frame.match(/\((\/[^)]+:\d+:\d+)\)$/) ?? frame.match(/at (\/[^ ]+:\d+:\d+)$/);
119
+ if (locationMatch?.[1]) {
120
+ return normalizeCallsitePath(locationMatch[1]);
199
121
  }
200
122
  }
201
- return `<!DOCTYPE html><html><head>${markup}</head><body>${html}</body></html>`;
202
- }, streamChunkToString = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true }), flushSafePendingText = (controller, encoder, pending, lookbehind) => {
203
- if (pending.length <= lookbehind) {
204
- return pending;
123
+ return;
124
+ }, captureRouteRegistrationCallsite = () => {
125
+ const { stack } = new Error;
126
+ if (!stack) {
127
+ return;
205
128
  }
206
- const safeText = pending.slice(0, pending.length - lookbehind);
207
- controller.enqueue(encoder.encode(safeText));
208
- return pending.slice(-lookbehind);
209
- }, updateInjectedState = (consumed, injected, pending) => {
210
- if (consumed.done) {
211
- return { done: true, injected, pending };
129
+ return extractRouteRegistrationCallsite(stack);
130
+ }, wrapRouteHandlerWithCallsite = (handler, callsite) => {
131
+ if (typeof handler !== "function" || !callsite) {
132
+ return handler;
212
133
  }
213
- return {
214
- done: false,
215
- injected: consumed.injected,
216
- pending: consumed.pending
134
+ const storage = ensureRouteCallsiteStorage();
135
+ return function wrappedRouteHandler(...args) {
136
+ return storage.run({ callsite }, () => Reflect.apply(handler, this, args));
217
137
  };
218
- }, readStreamChunk = async (reader) => {
219
- const { done, value } = await reader.read();
220
- if (done || !value) {
221
- return { done, value: undefined };
138
+ }, getCurrentRouteRegistrationCallsite = () => getRouteCallsiteStorage()?.getStore()?.callsite, patchElysiaRouteRegistrationCallsites = () => {
139
+ if (false) {}
140
+ if (Reflect.get(globalThis, ROUTE_CALLSITE_PATCHED_KEY) === true) {
141
+ return;
222
142
  }
223
- return { done, value };
224
- }, pipeStreamWithHeadInjection = (stream, markup) => {
225
- const encoder = new TextEncoder;
226
- const decoder = new TextDecoder;
227
- const lookbehind = CLOSING_HEAD_TAG.length - 1;
228
- const processPending = (controller, pending, injected) => {
229
- if (injected) {
230
- controller.enqueue(encoder.encode(pending));
231
- return { injected, pending: "" };
232
- }
233
- const headIndex = pending.indexOf(CLOSING_HEAD_TAG);
234
- if (headIndex >= 0) {
235
- const next = `${pending.slice(0, headIndex)}${markup}${pending.slice(headIndex)}`;
236
- controller.enqueue(encoder.encode(next));
237
- return { injected: true, pending: "" };
143
+ const prototype = Elysia.prototype;
144
+ for (const methodName of ROUTE_METHOD_NAMES) {
145
+ const originalMethod = prototype[methodName];
146
+ if (typeof originalMethod !== "function") {
147
+ continue;
238
148
  }
239
- return {
240
- injected,
241
- pending: flushSafePendingText(controller, encoder, pending, lookbehind)
149
+ prototype[methodName] = function patchedRouteMethod(path, handler, ...rest) {
150
+ const callsite = captureRouteRegistrationCallsite();
151
+ return Reflect.apply(originalMethod, this, [
152
+ path,
153
+ wrapRouteHandlerWithCallsite(handler, callsite),
154
+ ...rest
155
+ ]);
242
156
  };
157
+ }
158
+ Reflect.set(globalThis, ROUTE_CALLSITE_PATCHED_KEY, true);
159
+ };
160
+ var init_devRouteRegistrationCallsite = __esm(() => {
161
+ ROUTE_CALLSITE_STORAGE_KEY = Symbol.for("absolutejs.devRouteRegistrationCallsiteStorage");
162
+ ROUTE_CALLSITE_PATCHED_KEY = Symbol.for("absolutejs.devRouteRegistrationCallsitePatched");
163
+ ROUTE_METHOD_NAMES = [
164
+ "all",
165
+ "delete",
166
+ "get",
167
+ "head",
168
+ "options",
169
+ "patch",
170
+ "post",
171
+ "put"
172
+ ];
173
+ });
174
+
175
+ // src/client/streamSwap.ts
176
+ var streamSwapRuntime = () => {
177
+ const SLOT_PATCH_EVENT = "absolutejs:slot-patch";
178
+ if (window.__ABS_SLOT_RUNTIME__ === true)
179
+ return;
180
+ window.__ABS_SLOT_RUNTIME__ = true;
181
+ window.__ABS_SLOT_CONSUMERS__ = window.__ABS_SLOT_CONSUMERS__ ?? {};
182
+ window.__ABS_SLOT_PENDING__ = window.__ABS_SLOT_PENDING__ ?? {};
183
+ const consumers = window.__ABS_SLOT_CONSUMERS__;
184
+ const pending = window.__ABS_SLOT_PENDING__;
185
+ const isObjectRecord4 = (value) => Boolean(value) && typeof value === "object";
186
+ const isPatchedPendingEntry = (value) => {
187
+ if (!isObjectRecord4(value))
188
+ return false;
189
+ return value.domPatched === true && "payload" in value;
243
190
  };
244
- const finishHeadInjectionStream = (controller, pending, injected) => {
245
- let finalPending = pending + decoder.decode();
246
- if (!injected) {
247
- finalPending = injectHeadMarkup(finalPending, markup);
191
+ const unwrapPendingPayload = (value) => isPatchedPendingEntry(value) ? value.payload : value;
192
+ const canApplyImmediately = () => window.__ABS_SLOT_HYDRATION_PENDING__ !== true;
193
+ const isAngularDeferPayload = (payload) => {
194
+ if (!isObjectRecord4(payload))
195
+ return false;
196
+ return payload.kind === "angular-defer";
197
+ };
198
+ const isVueSuspensePayload = (payload) => {
199
+ if (!isObjectRecord4(payload))
200
+ return false;
201
+ return payload.kind === "vue-suspense";
202
+ };
203
+ const resolveHtml = (payload) => {
204
+ if (!isObjectRecord4(payload)) {
205
+ return typeof payload === "string" ? payload : "";
248
206
  }
249
- if (finalPending.length > 0) {
250
- controller.enqueue(encoder.encode(finalPending));
207
+ if (typeof payload.html === "string") {
208
+ return payload.html;
251
209
  }
252
- controller.close();
210
+ return "";
253
211
  };
254
- const consumeHeadChunk = async (controller, reader, pending, injected) => {
255
- const { done, value } = await readStreamChunk(reader);
256
- if (done || !value) {
257
- return { done, injected, pending };
258
- }
259
- const processed = processPending(controller, pending + streamChunkToString(value, decoder), injected);
260
- return {
261
- done,
262
- injected: processed.injected,
263
- pending: processed.pending
264
- };
265
- };
266
- const runHeadInjectionLoop = async (controller, reader) => {
267
- const consumeNextHeadChunk = async (injected, pending) => {
268
- const consumed = await consumeHeadChunk(controller, reader, pending, injected);
269
- const nextState = updateInjectedState(consumed, injected, pending);
270
- if (nextState.done) {
271
- return { injected, pending };
272
- }
273
- return consumeNextHeadChunk(nextState.injected, nextState.pending);
274
- };
275
- return consumeNextHeadChunk(false, "");
276
- };
277
- return new ReadableStream({
278
- async start(controller) {
279
- const reader = stream.getReader();
280
- try {
281
- const { injected, pending } = await runHeadInjectionLoop(controller, reader);
282
- finishHeadInjectionStream(controller, pending, injected);
283
- } catch (error) {
284
- controller.error(error);
285
- }
286
- }
287
- });
288
- }, pipeStreamWithIslandMarkerDetection = (stream, markup) => {
289
- const encoder = new TextEncoder;
290
- const decoder = new TextDecoder;
291
- const lookbehind = Math.max(ISLAND_MARKER.length, BYTES_PER_KILOBYTE);
292
- const processPending = (controller, pending, injected) => {
293
- if (injected) {
294
- controller.enqueue(encoder.encode(pending));
295
- return { injected, pending: "" };
296
- }
297
- const markerIndex = pending.indexOf(ISLAND_MARKER);
298
- if (markerIndex >= 0) {
299
- const tagStart = pending.lastIndexOf("<", markerIndex);
300
- const injectAt = tagStart >= 0 ? tagStart : markerIndex;
301
- const next = `${pending.slice(0, injectAt)}${markup}${pending.slice(injectAt)}`;
302
- controller.enqueue(encoder.encode(next));
303
- return { injected: true, pending: "" };
304
- }
305
- return {
306
- injected,
307
- pending: flushSafePendingText(controller, encoder, pending, lookbehind)
308
- };
309
- };
310
- const finishIslandMarkerStream = (controller, pending) => {
311
- const finalPending = pending + decoder.decode();
312
- if (finalPending.length > 0) {
313
- controller.enqueue(encoder.encode(finalPending));
314
- }
315
- controller.close();
316
- };
317
- const consumeIslandChunk = async (controller, reader, pending, injected) => {
318
- const { done, value } = await readStreamChunk(reader);
319
- if (done || !value) {
320
- return { done, injected, pending };
321
- }
322
- const processed = processPending(controller, pending + streamChunkToString(value, decoder), injected);
323
- return {
324
- done,
325
- injected: processed.injected,
326
- pending: processed.pending
327
- };
328
- };
329
- const runIslandMarkerLoop = async (controller, reader) => {
330
- const consumeNextIslandChunk = async (injected, pending) => {
331
- const consumed = await consumeIslandChunk(controller, reader, pending, injected);
332
- const nextState = updateInjectedState(consumed, injected, pending);
333
- if (nextState.done) {
334
- return { injected, pending };
335
- }
336
- return consumeNextIslandChunk(nextState.injected, nextState.pending);
337
- };
338
- return consumeNextIslandChunk(false, "");
339
- };
340
- return new ReadableStream({
341
- async start(controller) {
342
- const reader = stream.getReader();
343
- try {
344
- const { pending } = await runIslandMarkerLoop(controller, reader);
345
- finishIslandMarkerStream(controller, pending);
346
- } catch (error) {
347
- controller.error(error);
348
- }
349
- }
350
- });
351
- }, htmlContainsIslands = (html) => html.includes(ISLAND_MARKER), injectIslandPageContext = (html, options) => {
352
- const manifest = globalThis.__absoluteManifest;
353
- const hasIslands = options?.hasIslands ?? htmlContainsIslands(html);
354
- if (!manifest || !hasIslands) {
355
- return html;
356
- }
357
- if (html.includes(MANIFEST_MARKER) || html.includes(ISLAND_STATE_MARKER)) {
358
- return html;
359
- }
360
- return injectHeadMarkup(html, buildIslandsHeadMarkup(manifest));
361
- }, injectIslandPageContextStream = (stream, options) => {
362
- const manifest = globalThis.__absoluteManifest;
363
- if (!manifest)
364
- return stream;
365
- const markup = buildIslandsHeadMarkup(manifest);
366
- if (options?.hasIslands === true) {
367
- return pipeStreamWithHeadInjection(stream, markup);
368
- }
369
- if (options?.hasIslands === false) {
370
- return stream;
371
- }
372
- return pipeStreamWithIslandMarkerDetection(stream, markup);
373
- }, setCurrentIslandManifest = (manifest) => {
374
- globalThis.__absoluteManifest = manifest;
375
- };
376
- var init_islandPageContext = __esm(() => {
377
- init_constants();
378
- });
379
-
380
- // src/core/devRouteRegistrationCallsite.ts
381
- var exports_devRouteRegistrationCallsite = {};
382
- __export(exports_devRouteRegistrationCallsite, {
383
- patchElysiaRouteRegistrationCallsites: () => patchElysiaRouteRegistrationCallsites,
384
- getCurrentRouteRegistrationCallsite: () => getCurrentRouteRegistrationCallsite
385
- });
386
- import { AsyncLocalStorage } from "async_hooks";
387
- import { Elysia } from "elysia";
388
- var ROUTE_CALLSITE_STORAGE_KEY, ROUTE_CALLSITE_PATCHED_KEY, ROUTE_METHOD_NAMES, isObjectRecord3 = (value) => Boolean(value) && typeof value === "object", isAsyncLocalStorage2 = (value) => isObjectRecord3(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function", getRouteCallsiteStorage = () => {
389
- const value = Reflect.get(globalThis, ROUTE_CALLSITE_STORAGE_KEY);
390
- if (value === null || typeof value === "undefined") {
391
- return;
392
- }
393
- return isAsyncLocalStorage2(value) ? value : undefined;
394
- }, ensureRouteCallsiteStorage = () => {
395
- const existing = getRouteCallsiteStorage();
396
- if (existing) {
397
- return existing;
398
- }
399
- const storage = new AsyncLocalStorage;
400
- Reflect.set(globalThis, ROUTE_CALLSITE_STORAGE_KEY, storage);
401
- return storage;
402
- }, normalizeCallsitePath = (value) => value.replace(`${process.cwd()}/`, "").replace(process.cwd(), "").replace(/^\.\/+/, ""), extractRouteRegistrationCallsite = (stack) => {
403
- const frames = stack.split(`
404
- `).slice(1).map((line) => line.trim());
405
- for (const frame of frames) {
406
- if (frame.includes("/node_modules/") || frame.includes("/dist/") || frame.includes("/src/core/devRouteRegistrationCallsite.")) {
407
- continue;
408
- }
409
- const locationMatch = frame.match(/\((\/[^)]+:\d+:\d+)\)$/) ?? frame.match(/at (\/[^ ]+:\d+:\d+)$/);
410
- if (locationMatch?.[1]) {
411
- return normalizeCallsitePath(locationMatch[1]);
412
- }
413
- }
414
- return;
415
- }, captureRouteRegistrationCallsite = () => {
416
- const { stack } = new Error;
417
- if (!stack) {
418
- return;
419
- }
420
- return extractRouteRegistrationCallsite(stack);
421
- }, wrapRouteHandlerWithCallsite = (handler, callsite) => {
422
- if (typeof handler !== "function" || !callsite) {
423
- return handler;
424
- }
425
- const storage = ensureRouteCallsiteStorage();
426
- return function wrappedRouteHandler(...args) {
427
- return storage.run({ callsite }, () => Reflect.apply(handler, this, args));
428
- };
429
- }, getCurrentRouteRegistrationCallsite = () => getRouteCallsiteStorage()?.getStore()?.callsite, patchElysiaRouteRegistrationCallsites = () => {
430
- if (false) {}
431
- if (Reflect.get(globalThis, ROUTE_CALLSITE_PATCHED_KEY) === true) {
432
- return;
433
- }
434
- const prototype = Elysia.prototype;
435
- for (const methodName of ROUTE_METHOD_NAMES) {
436
- const originalMethod = prototype[methodName];
437
- if (typeof originalMethod !== "function") {
438
- continue;
439
- }
440
- prototype[methodName] = function patchedRouteMethod(path, handler, ...rest) {
441
- const callsite = captureRouteRegistrationCallsite();
442
- return Reflect.apply(originalMethod, this, [
443
- path,
444
- wrapRouteHandlerWithCallsite(handler, callsite),
445
- ...rest
446
- ]);
447
- };
448
- }
449
- Reflect.set(globalThis, ROUTE_CALLSITE_PATCHED_KEY, true);
450
- };
451
- var init_devRouteRegistrationCallsite = __esm(() => {
452
- ROUTE_CALLSITE_STORAGE_KEY = Symbol.for("absolutejs.devRouteRegistrationCallsiteStorage");
453
- ROUTE_CALLSITE_PATCHED_KEY = Symbol.for("absolutejs.devRouteRegistrationCallsitePatched");
454
- ROUTE_METHOD_NAMES = [
455
- "all",
456
- "delete",
457
- "get",
458
- "head",
459
- "options",
460
- "patch",
461
- "post",
462
- "put"
463
- ];
464
- });
465
-
466
- // src/client/streamSwap.ts
467
- var streamSwapRuntime = () => {
468
- const SLOT_PATCH_EVENT = "absolutejs:slot-patch";
469
- if (window.__ABS_SLOT_RUNTIME__ === true)
470
- return;
471
- window.__ABS_SLOT_RUNTIME__ = true;
472
- window.__ABS_SLOT_CONSUMERS__ = window.__ABS_SLOT_CONSUMERS__ ?? {};
473
- window.__ABS_SLOT_PENDING__ = window.__ABS_SLOT_PENDING__ ?? {};
474
- const consumers = window.__ABS_SLOT_CONSUMERS__;
475
- const pending = window.__ABS_SLOT_PENDING__;
476
- const isObjectRecord4 = (value) => Boolean(value) && typeof value === "object";
477
- const isPatchedPendingEntry = (value) => {
478
- if (!isObjectRecord4(value))
479
- return false;
480
- return value.domPatched === true && "payload" in value;
481
- };
482
- const unwrapPendingPayload = (value) => isPatchedPendingEntry(value) ? value.payload : value;
483
- const canApplyImmediately = () => window.__ABS_SLOT_HYDRATION_PENDING__ !== true;
484
- const isAngularDeferPayload = (payload) => {
485
- if (!isObjectRecord4(payload))
486
- return false;
487
- return payload.kind === "angular-defer";
488
- };
489
- const isVueSuspensePayload = (payload) => {
490
- if (!isObjectRecord4(payload))
491
- return false;
492
- return payload.kind === "vue-suspense";
493
- };
494
- const resolveHtml = (payload) => {
495
- if (!isObjectRecord4(payload)) {
496
- return typeof payload === "string" ? payload : "";
497
- }
498
- if (typeof payload.html === "string") {
499
- return payload.html;
500
- }
501
- return "";
502
- };
503
- const apply = (id, pendingEntry) => {
504
- const payload = unwrapPendingPayload(pendingEntry);
505
- if (!canApplyImmediately()) {
506
- pending[id] = payload;
507
- return;
212
+ const apply = (id, pendingEntry) => {
213
+ const payload = unwrapPendingPayload(pendingEntry);
214
+ if (!canApplyImmediately()) {
215
+ pending[id] = payload;
216
+ return;
508
217
  }
509
218
  const consumer = consumers[id];
510
219
  if (typeof consumer !== "function") {
@@ -886,264 +595,748 @@ var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG
886
595
  }
887
596
  return racers;
888
597
  };
889
- const flushTailLookbehind = (controller, tail) => {
890
- if (tail.length <= STREAM_TAIL_LOOKBEHIND) {
891
- return tail;
598
+ const flushTailLookbehind = (controller, tail) => {
599
+ if (tail.length <= STREAM_TAIL_LOOKBEHIND) {
600
+ return tail;
601
+ }
602
+ const content = tail.slice(0, tail.length - STREAM_TAIL_LOOKBEHIND);
603
+ controller.enqueue(encoder.encode(content));
604
+ return tail.slice(-STREAM_TAIL_LOOKBEHIND);
605
+ };
606
+ const finalizeCompletedBaseWinner = (controller, decodedTail, baseRead) => {
607
+ const footerStart = decodedTail.search(CLOSING_PAGE_TAG_REGEX);
608
+ if (footerStart < 0) {
609
+ enqueueEncodedText(controller, encoder, decodedTail);
610
+ return {
611
+ baseDone: true,
612
+ baseRead,
613
+ footer: "",
614
+ handled: true,
615
+ tail: ""
616
+ };
617
+ }
618
+ const content = decodedTail.slice(0, footerStart);
619
+ const nextFooter = decodedTail.slice(footerStart);
620
+ enqueueEncodedText(controller, encoder, content);
621
+ return {
622
+ baseDone: true,
623
+ baseRead,
624
+ footer: nextFooter,
625
+ handled: true,
626
+ tail: ""
627
+ };
628
+ };
629
+ const handleBaseWinner = (controller, winner, baseRead, tail, footer) => {
630
+ if (winner.kind !== "base") {
631
+ return { baseDone: false, baseRead, footer, handled: false, tail };
632
+ }
633
+ if (winner.done) {
634
+ return finalizeCompletedBaseWinner(controller, tail + decoder.decode(), baseRead);
635
+ }
636
+ if (!winner.value) {
637
+ return { baseDone: false, baseRead, footer, handled: true, tail };
638
+ }
639
+ const nextTail = flushTailLookbehind(controller, tail + streamChunkToString2(winner.value, decoder));
640
+ return {
641
+ baseDone: false,
642
+ baseRead: reader.read(),
643
+ footer,
644
+ handled: true,
645
+ tail: nextTail
646
+ };
647
+ };
648
+ const handleResolvedSlot = (controller, winner) => {
649
+ const index = pending.indexOf(winner.original);
650
+ if (index >= 0)
651
+ pending.splice(index, 1);
652
+ if (winner.result.payload === null) {
653
+ return;
654
+ }
655
+ emitSlotMetric({
656
+ bytes: winner.result.bytes,
657
+ durationMs: winner.result.durationMs,
658
+ slotId: winner.result.id,
659
+ type: "patched"
660
+ }, combinedOnSlotMetric);
661
+ controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.payload, nonce)));
662
+ };
663
+ const runPatchedStreamLoop = async (controller) => {
664
+ let baseDone = false;
665
+ let baseRead = reader.read();
666
+ let tail = "";
667
+ let footer = "";
668
+ const readNextRaceWinner = async () => {
669
+ const racers = createRaceCandidates(baseDone, baseRead);
670
+ if (racers.length === 0) {
671
+ return footer;
672
+ }
673
+ const winner = await Promise.race(racers);
674
+ const baseWinnerState = applyBaseWinnerState(handleBaseWinner(controller, winner, baseRead, tail, footer), winner, (slotWinner) => {
675
+ handleResolvedSlot(controller, slotWinner);
676
+ });
677
+ ({ baseDone, baseRead, footer, tail } = baseWinnerState);
678
+ if (baseDone && pending.length === 0) {
679
+ return footer;
680
+ }
681
+ return readNextRaceWinner();
682
+ };
683
+ return readNextRaceWinner();
684
+ };
685
+ return new ReadableStream({
686
+ async start(controller) {
687
+ try {
688
+ const footer = await runPatchedStreamLoop(controller);
689
+ enqueueEncodedText(controller, encoder, footer);
690
+ controller.close();
691
+ } catch (error) {
692
+ controller.error(error);
693
+ }
694
+ }
695
+ });
696
+ }, injectStreamingRuntimeIntoStream = (stream, nonce, runtimePlacement = "head", runtimePreludeScript) => {
697
+ const runtimeTag = renderStreamingSlotsRuntimeTag(nonce, runtimePreludeScript);
698
+ const encoder = new TextEncoder;
699
+ const decoder = new TextDecoder;
700
+ const closingTag = runtimePlacement === "body" ? CLOSING_BODY_TAG : CLOSING_HEAD_TAG2;
701
+ const lookbehind = (runtimePlacement === "body" ? CLOSING_BODY_TAG_LENGTH : CLOSING_HEAD_TAG_LENGTH) - 1;
702
+ const flushRuntimeLookbehind = (controller, pending) => {
703
+ if (pending.length <= lookbehind) {
704
+ return pending;
705
+ }
706
+ const safeText = pending.slice(0, pending.length - lookbehind);
707
+ controller.enqueue(encoder.encode(safeText));
708
+ return pending.slice(-lookbehind);
709
+ };
710
+ const injectRuntimeIntoPending = (pending) => runtimePlacement === "body" ? injectHtmlIntoBody(pending, runtimeTag) : injectHtmlIntoHead(pending, runtimeTag);
711
+ const processRuntimePending = (controller, pending, injected) => {
712
+ if (injected) {
713
+ controller.enqueue(encoder.encode(pending));
714
+ return { injected, pending: "" };
715
+ }
716
+ const closingTagIndex = pending.indexOf(closingTag);
717
+ if (closingTagIndex >= 0) {
718
+ const withRuntime = `${pending.slice(0, closingTagIndex)}${runtimeTag}${pending.slice(closingTagIndex)}`;
719
+ controller.enqueue(encoder.encode(withRuntime));
720
+ return { injected: true, pending: "" };
721
+ }
722
+ return {
723
+ injected,
724
+ pending: flushRuntimeLookbehind(controller, pending)
725
+ };
726
+ };
727
+ return new ReadableStream({
728
+ async start(controller) {
729
+ const reader = stream.getReader();
730
+ let injected = false;
731
+ let pending = "";
732
+ const enqueuePending = () => enqueueEncodedText(controller, encoder, pending);
733
+ const consumeRuntimeChunk = async () => {
734
+ const { done, value } = await readStreamingRuntimeChunk(reader);
735
+ if (done || !value) {
736
+ return done;
737
+ }
738
+ pending += streamChunkToString2(value, decoder);
739
+ ({ injected, pending } = processRuntimePending(controller, pending, injected));
740
+ return false;
741
+ };
742
+ const runRuntimeInjectionLoop = async () => {
743
+ const done = await consumeRuntimeChunk();
744
+ if (done) {
745
+ return;
746
+ }
747
+ await runRuntimeInjectionLoop();
748
+ };
749
+ try {
750
+ await runRuntimeInjectionLoop();
751
+ pending += decoder.decode();
752
+ pending = injected ? pending : injectRuntimeIntoPending(pending);
753
+ enqueuePending();
754
+ controller.close();
755
+ } catch (error) {
756
+ controller.error(error);
757
+ }
758
+ }
759
+ });
760
+ }, streamOutOfOrderSlots = ({
761
+ footerHtml = "",
762
+ headerHtml = "",
763
+ nonce,
764
+ policy,
765
+ onSlotMetric,
766
+ onError,
767
+ slots
768
+ }) => {
769
+ const resolvedPolicy = resolveStreamingSlotPolicy(policy);
770
+ const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
771
+ const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
772
+ const effectivePolicy = {
773
+ ...resolvedPolicy,
774
+ onSlotMetric: combinedOnSlotMetric
775
+ };
776
+ const preparedSlots = prepareSlots({
777
+ onError: combinedOnError,
778
+ onSlotMetric: combinedOnSlotMetric,
779
+ policy: effectivePolicy,
780
+ slots
781
+ });
782
+ const encoder = new TextEncoder;
783
+ const createPendingSlots = (controller) => preparedSlots.map((slot) => {
784
+ const fallback = renderStreamingSlotPlaceholder(slot.id, normalizeSlotText(slot.fallbackHtml, ""));
785
+ controller.enqueue(toUint8(fallback, encoder));
786
+ return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
787
+ });
788
+ const handleResolvedPreparedSlot = async (controller, pending) => {
789
+ const { original, result } = await nextResolvedSlot(pending);
790
+ const index = pending.indexOf(original);
791
+ if (index >= 0)
792
+ pending.splice(index, 1);
793
+ if (result.payload === null) {
794
+ return;
795
+ }
796
+ emitSlotMetric({
797
+ bytes: result.bytes,
798
+ durationMs: result.durationMs,
799
+ slotId: result.id,
800
+ type: "patched"
801
+ }, combinedOnSlotMetric);
802
+ controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.payload, nonce), encoder));
803
+ };
804
+ const streamPreparedSlots = async (controller) => {
805
+ const pending = createPendingSlots(controller);
806
+ const streamNextPreparedSlot = async () => {
807
+ if (pending.length === 0) {
808
+ return;
809
+ }
810
+ await handleResolvedPreparedSlot(controller, pending);
811
+ await streamNextPreparedSlot();
812
+ };
813
+ await streamNextPreparedSlot();
814
+ };
815
+ const resolveHeaderHtml = () => {
816
+ const needsRuntimeTag = preparedSlots.length > 0 && !headerHtml.includes(STREAMING_RUNTIME_GLOBAL);
817
+ if (!needsRuntimeTag) {
818
+ return headerHtml;
819
+ }
820
+ return injectHtmlIntoHead(headerHtml, renderStreamingSlotsRuntimeTag(nonce));
821
+ };
822
+ return new ReadableStream({
823
+ async start(controller) {
824
+ try {
825
+ const header = resolveHeaderHtml();
826
+ controller.enqueue(toUint8(header, encoder));
827
+ await streamPreparedSlots(controller);
828
+ enqueueEncodedText(controller, encoder, footerHtml);
829
+ controller.close();
830
+ } catch (error) {
831
+ controller.error(error);
832
+ }
833
+ }
834
+ });
835
+ };
836
+ var init_streamingSlots = __esm(() => {
837
+ init_constants();
838
+ init_escapeScriptContent();
839
+ CLOSING_BODY_TAG_LENGTH = CLOSING_BODY_TAG.length;
840
+ CLOSING_HEAD_TAG_LENGTH = CLOSING_HEAD_TAG2.length;
841
+ CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
842
+ currentStreamingSlotPolicy = {
843
+ errorHtml: undefined,
844
+ fallbackHtml: "",
845
+ maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES,
846
+ maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
847
+ timeoutMs: STREAMING_SLOT_TIMEOUT_MS
848
+ };
849
+ });
850
+
851
+ // src/utils/getDurationString.ts
852
+ var getDurationString = (duration) => {
853
+ let durationString;
854
+ if (duration < MILLISECONDS_IN_A_SECOND) {
855
+ durationString = `${duration.toFixed(TIME_PRECISION)}ms`;
856
+ } else if (duration < MILLISECONDS_IN_A_MINUTE) {
857
+ durationString = `${(duration / MILLISECONDS_IN_A_SECOND).toFixed(TIME_PRECISION)}s`;
858
+ } else {
859
+ durationString = `${(duration / MILLISECONDS_IN_A_MINUTE).toFixed(TIME_PRECISION)}m`;
860
+ }
861
+ return durationString;
862
+ };
863
+ var init_getDurationString = __esm(() => {
864
+ init_constants();
865
+ });
866
+
867
+ // src/utils/startupBanner.ts
868
+ var colors, MONTHS, formatTimestamp = () => {
869
+ const now = new Date;
870
+ const month = MONTHS[now.getMonth()];
871
+ const day = now.getDate().toString().padStart(2, "0");
872
+ let hours = now.getHours();
873
+ const minutes = now.getMinutes().toString().padStart(2, "0");
874
+ const seconds = now.getSeconds().toString().padStart(2, "0");
875
+ const ampm = hours >= HOURS_IN_HALF_DAY ? "PM" : "AM";
876
+ hours = hours % HOURS_IN_HALF_DAY || HOURS_IN_HALF_DAY;
877
+ return `${month} ${day} ${hours}:${minutes}:${seconds} ${ampm}`;
878
+ }, startupBanner = (options) => {
879
+ const {
880
+ version,
881
+ readyDuration,
882
+ buildDuration,
883
+ port,
884
+ host,
885
+ networkUrl,
886
+ protocol = "http"
887
+ } = options;
888
+ const name = `${colors.cyan}${colors.bold}ABSOLUTEJS${colors.reset}`;
889
+ const ver = `${colors.dim}v${version}${colors.reset}`;
890
+ const time = `${colors.dim}ready in${colors.reset} ${colors.bold}${getDurationString(readyDuration)}${colors.reset}`;
891
+ const build = typeof buildDuration === "number" && Number.isFinite(buildDuration) ? ` ${colors.dim}(build ${getDurationString(buildDuration)})${colors.reset}` : "";
892
+ console.log("");
893
+ console.log(` ${name} ${ver} ${time}${build}`);
894
+ console.log("");
895
+ console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Local:${colors.reset} ${protocol}://${host === "0.0.0.0" ? "localhost" : host}:${port}/`);
896
+ if (networkUrl) {
897
+ console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Network:${colors.reset} ${networkUrl}`);
898
+ }
899
+ console.log("");
900
+ };
901
+ var init_startupBanner = __esm(() => {
902
+ init_constants();
903
+ init_getDurationString();
904
+ colors = {
905
+ bold: "\x1B[1m",
906
+ cyan: "\x1B[36m",
907
+ dim: "\x1B[2m",
908
+ green: "\x1B[32m",
909
+ reset: "\x1B[0m"
910
+ };
911
+ MONTHS = [
912
+ "Jan",
913
+ "Feb",
914
+ "Mar",
915
+ "Apr",
916
+ "May",
917
+ "Jun",
918
+ "Jul",
919
+ "Aug",
920
+ "Sep",
921
+ "Oct",
922
+ "Nov",
923
+ "Dec"
924
+ ];
925
+ });
926
+
927
+ // src/utils/logger.ts
928
+ var colors2, frameworkColors, formatPath = (filePath) => {
929
+ const cwd = process.cwd();
930
+ let relative = filePath.startsWith(cwd) ? filePath.slice(cwd.length + 1) : filePath;
931
+ relative = relative.replace(/\\/g, "/");
932
+ if (!relative.startsWith("/")) {
933
+ relative = `/${relative}`;
934
+ }
935
+ return relative;
936
+ }, getFrameworkColor = (framework) => frameworkColors[framework] || colors2.white, log = (action, options) => {
937
+ const timestamp = `${colors2.dim}${formatTimestamp()}${colors2.reset}`;
938
+ const tag = `${colors2.cyan}[hmr]${colors2.reset}`;
939
+ let message = action;
940
+ if (options?.path) {
941
+ const pathColor = options.framework ? getFrameworkColor(options.framework) : colors2.white;
942
+ message += ` ${pathColor}${formatPath(options.path)}${colors2.reset}`;
943
+ }
944
+ if (options?.duration !== undefined) {
945
+ message += ` ${colors2.dim}(${options.duration}ms)${colors2.reset}`;
946
+ }
947
+ console.log(`${timestamp} ${tag} ${message}`);
948
+ }, logCssUpdate = (path, framework, duration) => {
949
+ log("css update", { duration, framework: framework ?? "css", path });
950
+ }, logError = (message, error) => {
951
+ const timestamp = `${colors2.dim}${formatTimestamp()}${colors2.reset}`;
952
+ const tag = `${colors2.red}[hmr]${colors2.reset}`;
953
+ const errorMsg = error instanceof Error ? error.message : error;
954
+ const fullMessage = `${colors2.red}error${colors2.reset} ${message}${errorMsg ? `: ${errorMsg}` : ""}`;
955
+ console.error(`${timestamp} ${tag} ${fullMessage}`);
956
+ }, logHmrUpdate = (path, framework, duration) => {
957
+ log("hmr update", { duration, framework, path });
958
+ }, logScriptUpdate = (path, framework, duration) => {
959
+ log("script update", { duration, framework, path });
960
+ }, logServerReload = () => {
961
+ log(`${colors2.cyan}server module reloaded${colors2.reset}`);
962
+ }, logWarn = (message) => {
963
+ const timestamp = `${colors2.dim}${formatTimestamp()}${colors2.reset}`;
964
+ const tag = `${colors2.yellow}[hmr]${colors2.reset}`;
965
+ console.log(`${timestamp} ${tag} ${colors2.yellow}warning ${message}${colors2.reset}`);
966
+ };
967
+ var init_logger = __esm(() => {
968
+ init_startupBanner();
969
+ colors2 = {
970
+ blue: "\x1B[34m",
971
+ bold: "\x1B[1m",
972
+ cyan: "\x1B[36m",
973
+ dim: "\x1B[2m",
974
+ green: "\x1B[32m",
975
+ magenta: "\x1B[35m",
976
+ red: "\x1B[31m",
977
+ reset: "\x1B[0m",
978
+ white: "\x1B[37m",
979
+ yellow: "\x1B[33m"
980
+ };
981
+ frameworkColors = {
982
+ angular: colors2.magenta,
983
+ assets: colors2.dim,
984
+ css: colors2.cyan,
985
+ html: colors2.white,
986
+ htmx: colors2.white,
987
+ react: colors2.blue,
988
+ svelte: colors2.yellow,
989
+ vue: colors2.green
990
+ };
991
+ });
992
+
993
+ // src/core/ssrCache.ts
994
+ var dirtyFrameworks, markSsrCacheDirty = (framework) => {
995
+ dirtyFrameworks.add(framework);
996
+ }, isSsrCacheDirty = (framework) => dirtyFrameworks.has(framework);
997
+ var init_ssrCache = __esm(() => {
998
+ dirtyFrameworks = new Set;
999
+ });
1000
+
1001
+ // src/utils/stringModifiers.ts
1002
+ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
1003
+ if (!str.includes("-") && !str.includes("_")) {
1004
+ return str.charAt(0).toUpperCase() + str.slice(1);
1005
+ }
1006
+ return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
1007
+ }, toScreamingSnake = (str) => str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase();
1008
+
1009
+ // src/core/streamingSlotRegistrar.ts
1010
+ var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
1011
+ var STREAMING_SLOT_WARNING_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotWarningController");
1012
+ var STREAMING_SLOT_COLLECTION_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotCollectionController");
1013
+ var getRegisteredStreamingSlotRegistrar = () => {
1014
+ const value = Reflect.get(globalThis, STREAMING_SLOT_REGISTRAR_KEY);
1015
+ if (typeof value === "function" || value === null) {
1016
+ return value;
1017
+ }
1018
+ return;
1019
+ };
1020
+ var isObjectRecord = (value) => Boolean(value) && typeof value === "object";
1021
+ var isStreamingSlotWarningController = (value) => isObjectRecord(value) && ("maybeWarn" in value) && typeof value.maybeWarn === "function";
1022
+ var isStreamingSlotCollectionController = (value) => isObjectRecord(value) && ("isCollecting" in value) && typeof value.isCollecting === "function";
1023
+ var getWarningController = () => {
1024
+ const value = Reflect.get(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY);
1025
+ if (value === null || typeof value === "undefined")
1026
+ return;
1027
+ return isStreamingSlotWarningController(value) ? value : undefined;
1028
+ };
1029
+ var getCollectionController = () => {
1030
+ const value = Reflect.get(globalThis, STREAMING_SLOT_COLLECTION_STORAGE_KEY);
1031
+ if (value === null || typeof value === "undefined")
1032
+ return;
1033
+ return isStreamingSlotCollectionController(value) ? value : undefined;
1034
+ };
1035
+ var hasRegisteredStreamingSlotRegistrar = () => typeof getRegisteredStreamingSlotRegistrar() === "function";
1036
+ var isStreamingSlotCollectionActive = () => getCollectionController()?.isCollecting() === true;
1037
+ var registerStreamingSlot = (slot) => {
1038
+ getRegisteredStreamingSlotRegistrar()?.(slot);
1039
+ };
1040
+ var setStreamingSlotCollectionController = (controller) => {
1041
+ Reflect.set(globalThis, STREAMING_SLOT_COLLECTION_STORAGE_KEY, controller);
1042
+ };
1043
+ var setStreamingSlotRegistrar = (nextRegistrar) => {
1044
+ Reflect.set(globalThis, STREAMING_SLOT_REGISTRAR_KEY, nextRegistrar);
1045
+ };
1046
+ var setStreamingSlotWarningController = (controller) => {
1047
+ Reflect.set(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY, controller);
1048
+ };
1049
+ var warnMissingStreamingSlotCollector = (primitiveName) => {
1050
+ if (isStreamingSlotCollectionActive()) {
1051
+ return;
1052
+ }
1053
+ getWarningController()?.maybeWarn(primitiveName);
1054
+ };
1055
+
1056
+ // src/core/streamingSlotRegistry.ts
1057
+ var STREAMING_SLOT_STORAGE_KEY = Symbol.for("absolutejs.streamingSlotAsyncLocalStorage");
1058
+ var isObjectRecord2 = (value) => Boolean(value) && typeof value === "object";
1059
+ var isAsyncLocalStorage = (value) => isObjectRecord2(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
1060
+ var getStorageGlobal = () => {
1061
+ const value = Reflect.get(globalThis, STREAMING_SLOT_STORAGE_KEY);
1062
+ if (value === null || typeof value === "undefined") {
1063
+ return value;
1064
+ }
1065
+ return isAsyncLocalStorage(value) ? value : undefined;
1066
+ };
1067
+ var isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string";
1068
+ var ensureAsyncLocalStorage = async () => {
1069
+ const storage = getStorageGlobal();
1070
+ if (typeof storage !== "undefined") {
1071
+ return storage;
1072
+ }
1073
+ if (!isServerRuntime()) {
1074
+ Reflect.set(globalThis, STREAMING_SLOT_STORAGE_KEY, null);
1075
+ return getStorageGlobal();
1076
+ }
1077
+ const mod = await import("async_hooks");
1078
+ Reflect.set(globalThis, STREAMING_SLOT_STORAGE_KEY, new mod.AsyncLocalStorage);
1079
+ return getStorageGlobal();
1080
+ };
1081
+ var getActiveSlotStore = () => {
1082
+ const storage = getStorageGlobal();
1083
+ if (!storage)
1084
+ return;
1085
+ return storage.getStore();
1086
+ };
1087
+ var registerStreamingSlot2 = (slot) => {
1088
+ const store = getActiveSlotStore();
1089
+ if (!store)
1090
+ return;
1091
+ store.set(slot.id, slot);
1092
+ };
1093
+ setStreamingSlotRegistrar(registerStreamingSlot2);
1094
+ setStreamingSlotCollectionController({
1095
+ isCollecting: () => getActiveSlotStore() !== undefined
1096
+ });
1097
+ var hasActiveStreamingSlotRegistry = () => getActiveSlotStore() !== undefined;
1098
+ var runWithStreamingSlotRegistry = async (task) => {
1099
+ const storage = await ensureAsyncLocalStorage();
1100
+ if (!storage) {
1101
+ const slots = [];
1102
+ return {
1103
+ result: await task(),
1104
+ slots
1105
+ };
1106
+ }
1107
+ return storage.run(new Map, async () => {
1108
+ const result = await task();
1109
+ const store = storage.getStore();
1110
+ return {
1111
+ result,
1112
+ slots: store ? [...store.values()] : []
1113
+ };
1114
+ });
1115
+ };
1116
+
1117
+ // src/core/islandPageContext.ts
1118
+ init_constants();
1119
+ var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient";
1120
+ var ISLAND_MARKER = 'data-island="true"';
1121
+ var MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__";
1122
+ var ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__";
1123
+ var CLOSING_HEAD_TAG = "</head>";
1124
+ var buildIslandsHeadMarkup = (manifest) => {
1125
+ const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
1126
+ const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
1127
+ const bootstrapPath = manifest[BOOTSTRAP_MANIFEST_KEY];
1128
+ const bootstrapScript = bootstrapPath ? `<script type="module" src="${bootstrapPath}"></script>` : "";
1129
+ return `${manifestScript}${islandStateScript}${bootstrapScript}`;
1130
+ };
1131
+ var injectHeadMarkup = (html, markup) => {
1132
+ const closingHeadIndex = html.indexOf("</head>");
1133
+ if (closingHeadIndex >= 0) {
1134
+ return `${html.slice(0, closingHeadIndex)}${markup}${html.slice(closingHeadIndex)}`;
1135
+ }
1136
+ const openingBodyIndex = html.indexOf("<body");
1137
+ if (openingBodyIndex >= 0) {
1138
+ const bodyStart = html.indexOf(">", openingBodyIndex);
1139
+ if (bodyStart >= 0) {
1140
+ return `${html.slice(0, openingBodyIndex)}<head>${markup}</head>${html.slice(openingBodyIndex)}`;
1141
+ }
1142
+ }
1143
+ return `<!DOCTYPE html><html><head>${markup}</head><body>${html}</body></html>`;
1144
+ };
1145
+ var streamChunkToString = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true });
1146
+ var flushSafePendingText = (controller, encoder, pending, lookbehind) => {
1147
+ if (pending.length <= lookbehind) {
1148
+ return pending;
1149
+ }
1150
+ const safeText = pending.slice(0, pending.length - lookbehind);
1151
+ controller.enqueue(encoder.encode(safeText));
1152
+ return pending.slice(-lookbehind);
1153
+ };
1154
+ var updateInjectedState = (consumed, injected, pending) => {
1155
+ if (consumed.done) {
1156
+ return { done: true, injected, pending };
1157
+ }
1158
+ return {
1159
+ done: false,
1160
+ injected: consumed.injected,
1161
+ pending: consumed.pending
1162
+ };
1163
+ };
1164
+ var readStreamChunk = async (reader) => {
1165
+ const { done, value } = await reader.read();
1166
+ if (done || !value) {
1167
+ return { done, value: undefined };
1168
+ }
1169
+ return { done, value };
1170
+ };
1171
+ var pipeStreamWithHeadInjection = (stream, markup) => {
1172
+ const encoder = new TextEncoder;
1173
+ const decoder = new TextDecoder;
1174
+ const lookbehind = CLOSING_HEAD_TAG.length - 1;
1175
+ const processPending = (controller, pending, injected) => {
1176
+ if (injected) {
1177
+ controller.enqueue(encoder.encode(pending));
1178
+ return { injected, pending: "" };
892
1179
  }
893
- const content = tail.slice(0, tail.length - STREAM_TAIL_LOOKBEHIND);
894
- controller.enqueue(encoder.encode(content));
895
- return tail.slice(-STREAM_TAIL_LOOKBEHIND);
896
- };
897
- const finalizeCompletedBaseWinner = (controller, decodedTail, baseRead) => {
898
- const footerStart = decodedTail.search(CLOSING_PAGE_TAG_REGEX);
899
- if (footerStart < 0) {
900
- enqueueEncodedText(controller, encoder, decodedTail);
901
- return {
902
- baseDone: true,
903
- baseRead,
904
- footer: "",
905
- handled: true,
906
- tail: ""
907
- };
1180
+ const headIndex = pending.indexOf(CLOSING_HEAD_TAG);
1181
+ if (headIndex >= 0) {
1182
+ const next = `${pending.slice(0, headIndex)}${markup}${pending.slice(headIndex)}`;
1183
+ controller.enqueue(encoder.encode(next));
1184
+ return { injected: true, pending: "" };
908
1185
  }
909
- const content = decodedTail.slice(0, footerStart);
910
- const nextFooter = decodedTail.slice(footerStart);
911
- enqueueEncodedText(controller, encoder, content);
912
1186
  return {
913
- baseDone: true,
914
- baseRead,
915
- footer: nextFooter,
916
- handled: true,
917
- tail: ""
1187
+ injected,
1188
+ pending: flushSafePendingText(controller, encoder, pending, lookbehind)
918
1189
  };
919
1190
  };
920
- const handleBaseWinner = (controller, winner, baseRead, tail, footer) => {
921
- if (winner.kind !== "base") {
922
- return { baseDone: false, baseRead, footer, handled: false, tail };
1191
+ const finishHeadInjectionStream = (controller, pending, injected) => {
1192
+ let finalPending = pending + decoder.decode();
1193
+ if (!injected) {
1194
+ finalPending = injectHeadMarkup(finalPending, markup);
923
1195
  }
924
- if (winner.done) {
925
- return finalizeCompletedBaseWinner(controller, tail + decoder.decode(), baseRead);
1196
+ if (finalPending.length > 0) {
1197
+ controller.enqueue(encoder.encode(finalPending));
926
1198
  }
927
- if (!winner.value) {
928
- return { baseDone: false, baseRead, footer, handled: true, tail };
1199
+ controller.close();
1200
+ };
1201
+ const consumeHeadChunk = async (controller, reader, pending, injected) => {
1202
+ const { done, value } = await readStreamChunk(reader);
1203
+ if (done || !value) {
1204
+ return { done, injected, pending };
929
1205
  }
930
- const nextTail = flushTailLookbehind(controller, tail + streamChunkToString2(winner.value, decoder));
1206
+ const processed = processPending(controller, pending + streamChunkToString(value, decoder), injected);
931
1207
  return {
932
- baseDone: false,
933
- baseRead: reader.read(),
934
- footer,
935
- handled: true,
936
- tail: nextTail
1208
+ done,
1209
+ injected: processed.injected,
1210
+ pending: processed.pending
937
1211
  };
938
1212
  };
939
- const handleResolvedSlot = (controller, winner) => {
940
- const index = pending.indexOf(winner.original);
941
- if (index >= 0)
942
- pending.splice(index, 1);
943
- if (winner.result.payload === null) {
944
- return;
945
- }
946
- emitSlotMetric({
947
- bytes: winner.result.bytes,
948
- durationMs: winner.result.durationMs,
949
- slotId: winner.result.id,
950
- type: "patched"
951
- }, combinedOnSlotMetric);
952
- controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.payload, nonce)));
953
- };
954
- const runPatchedStreamLoop = async (controller) => {
955
- let baseDone = false;
956
- let baseRead = reader.read();
957
- let tail = "";
958
- let footer = "";
959
- const readNextRaceWinner = async () => {
960
- const racers = createRaceCandidates(baseDone, baseRead);
961
- if (racers.length === 0) {
962
- return footer;
963
- }
964
- const winner = await Promise.race(racers);
965
- const baseWinnerState = applyBaseWinnerState(handleBaseWinner(controller, winner, baseRead, tail, footer), winner, (slotWinner) => {
966
- handleResolvedSlot(controller, slotWinner);
967
- });
968
- ({ baseDone, baseRead, footer, tail } = baseWinnerState);
969
- if (baseDone && pending.length === 0) {
970
- return footer;
1213
+ const runHeadInjectionLoop = async (controller, reader) => {
1214
+ const consumeNextHeadChunk = async (injected, pending) => {
1215
+ const consumed = await consumeHeadChunk(controller, reader, pending, injected);
1216
+ const nextState = updateInjectedState(consumed, injected, pending);
1217
+ if (nextState.done) {
1218
+ return { injected, pending };
971
1219
  }
972
- return readNextRaceWinner();
1220
+ return consumeNextHeadChunk(nextState.injected, nextState.pending);
973
1221
  };
974
- return readNextRaceWinner();
1222
+ return consumeNextHeadChunk(false, "");
975
1223
  };
976
1224
  return new ReadableStream({
977
1225
  async start(controller) {
1226
+ const reader = stream.getReader();
978
1227
  try {
979
- const footer = await runPatchedStreamLoop(controller);
980
- enqueueEncodedText(controller, encoder, footer);
981
- controller.close();
1228
+ const { injected, pending } = await runHeadInjectionLoop(controller, reader);
1229
+ finishHeadInjectionStream(controller, pending, injected);
982
1230
  } catch (error) {
983
1231
  controller.error(error);
984
1232
  }
985
1233
  }
986
1234
  });
987
- }, injectStreamingRuntimeIntoStream = (stream, nonce, runtimePlacement = "head", runtimePreludeScript) => {
988
- const runtimeTag = renderStreamingSlotsRuntimeTag(nonce, runtimePreludeScript);
1235
+ };
1236
+ var pipeStreamWithIslandMarkerDetection = (stream, markup) => {
989
1237
  const encoder = new TextEncoder;
990
1238
  const decoder = new TextDecoder;
991
- const closingTag = runtimePlacement === "body" ? CLOSING_BODY_TAG : CLOSING_HEAD_TAG2;
992
- const lookbehind = (runtimePlacement === "body" ? CLOSING_BODY_TAG_LENGTH : CLOSING_HEAD_TAG_LENGTH) - 1;
993
- const flushRuntimeLookbehind = (controller, pending) => {
994
- if (pending.length <= lookbehind) {
995
- return pending;
996
- }
997
- const safeText = pending.slice(0, pending.length - lookbehind);
998
- controller.enqueue(encoder.encode(safeText));
999
- return pending.slice(-lookbehind);
1000
- };
1001
- const injectRuntimeIntoPending = (pending) => runtimePlacement === "body" ? injectHtmlIntoBody(pending, runtimeTag) : injectHtmlIntoHead(pending, runtimeTag);
1002
- const processRuntimePending = (controller, pending, injected) => {
1239
+ const lookbehind = Math.max(ISLAND_MARKER.length, BYTES_PER_KILOBYTE);
1240
+ const processPending = (controller, pending, injected) => {
1003
1241
  if (injected) {
1004
1242
  controller.enqueue(encoder.encode(pending));
1005
1243
  return { injected, pending: "" };
1006
1244
  }
1007
- const closingTagIndex = pending.indexOf(closingTag);
1008
- if (closingTagIndex >= 0) {
1009
- const withRuntime = `${pending.slice(0, closingTagIndex)}${runtimeTag}${pending.slice(closingTagIndex)}`;
1010
- controller.enqueue(encoder.encode(withRuntime));
1245
+ const markerIndex = pending.indexOf(ISLAND_MARKER);
1246
+ if (markerIndex >= 0) {
1247
+ const tagStart = pending.lastIndexOf("<", markerIndex);
1248
+ const injectAt = tagStart >= 0 ? tagStart : markerIndex;
1249
+ const next = `${pending.slice(0, injectAt)}${markup}${pending.slice(injectAt)}`;
1250
+ controller.enqueue(encoder.encode(next));
1011
1251
  return { injected: true, pending: "" };
1012
1252
  }
1013
1253
  return {
1014
1254
  injected,
1015
- pending: flushRuntimeLookbehind(controller, pending)
1255
+ pending: flushSafePendingText(controller, encoder, pending, lookbehind)
1016
1256
  };
1017
1257
  };
1018
- return new ReadableStream({
1019
- async start(controller) {
1020
- const reader = stream.getReader();
1021
- let injected = false;
1022
- let pending = "";
1023
- const enqueuePending = () => enqueueEncodedText(controller, encoder, pending);
1024
- const consumeRuntimeChunk = async () => {
1025
- const { done, value } = await readStreamingRuntimeChunk(reader);
1026
- if (done || !value) {
1027
- return done;
1028
- }
1029
- pending += streamChunkToString2(value, decoder);
1030
- ({ injected, pending } = processRuntimePending(controller, pending, injected));
1031
- return false;
1032
- };
1033
- const runRuntimeInjectionLoop = async () => {
1034
- const done = await consumeRuntimeChunk();
1035
- if (done) {
1036
- return;
1037
- }
1038
- await runRuntimeInjectionLoop();
1039
- };
1040
- try {
1041
- await runRuntimeInjectionLoop();
1042
- pending += decoder.decode();
1043
- pending = injected ? pending : injectRuntimeIntoPending(pending);
1044
- enqueuePending();
1045
- controller.close();
1046
- } catch (error) {
1047
- controller.error(error);
1048
- }
1258
+ const finishIslandMarkerStream = (controller, pending) => {
1259
+ const finalPending = pending + decoder.decode();
1260
+ if (finalPending.length > 0) {
1261
+ controller.enqueue(encoder.encode(finalPending));
1049
1262
  }
1050
- });
1051
- }, streamOutOfOrderSlots = ({
1052
- footerHtml = "",
1053
- headerHtml = "",
1054
- nonce,
1055
- policy,
1056
- onSlotMetric,
1057
- onError,
1058
- slots
1059
- }) => {
1060
- const resolvedPolicy = resolveStreamingSlotPolicy(policy);
1061
- const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
1062
- const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
1063
- const effectivePolicy = {
1064
- ...resolvedPolicy,
1065
- onSlotMetric: combinedOnSlotMetric
1263
+ controller.close();
1066
1264
  };
1067
- const preparedSlots = prepareSlots({
1068
- onError: combinedOnError,
1069
- onSlotMetric: combinedOnSlotMetric,
1070
- policy: effectivePolicy,
1071
- slots
1072
- });
1073
- const encoder = new TextEncoder;
1074
- const createPendingSlots = (controller) => preparedSlots.map((slot) => {
1075
- const fallback = renderStreamingSlotPlaceholder(slot.id, normalizeSlotText(slot.fallbackHtml, ""));
1076
- controller.enqueue(toUint8(fallback, encoder));
1077
- return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
1078
- });
1079
- const handleResolvedPreparedSlot = async (controller, pending) => {
1080
- const { original, result } = await nextResolvedSlot(pending);
1081
- const index = pending.indexOf(original);
1082
- if (index >= 0)
1083
- pending.splice(index, 1);
1084
- if (result.payload === null) {
1085
- return;
1265
+ const consumeIslandChunk = async (controller, reader, pending, injected) => {
1266
+ const { done, value } = await readStreamChunk(reader);
1267
+ if (done || !value) {
1268
+ return { done, injected, pending };
1086
1269
  }
1087
- emitSlotMetric({
1088
- bytes: result.bytes,
1089
- durationMs: result.durationMs,
1090
- slotId: result.id,
1091
- type: "patched"
1092
- }, combinedOnSlotMetric);
1093
- controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.payload, nonce), encoder));
1270
+ const processed = processPending(controller, pending + streamChunkToString(value, decoder), injected);
1271
+ return {
1272
+ done,
1273
+ injected: processed.injected,
1274
+ pending: processed.pending
1275
+ };
1094
1276
  };
1095
- const streamPreparedSlots = async (controller) => {
1096
- const pending = createPendingSlots(controller);
1097
- const streamNextPreparedSlot = async () => {
1098
- if (pending.length === 0) {
1099
- return;
1277
+ const runIslandMarkerLoop = async (controller, reader) => {
1278
+ const consumeNextIslandChunk = async (injected, pending) => {
1279
+ const consumed = await consumeIslandChunk(controller, reader, pending, injected);
1280
+ const nextState = updateInjectedState(consumed, injected, pending);
1281
+ if (nextState.done) {
1282
+ return { injected, pending };
1100
1283
  }
1101
- await handleResolvedPreparedSlot(controller, pending);
1102
- await streamNextPreparedSlot();
1284
+ return consumeNextIslandChunk(nextState.injected, nextState.pending);
1103
1285
  };
1104
- await streamNextPreparedSlot();
1105
- };
1106
- const resolveHeaderHtml = () => {
1107
- const needsRuntimeTag = preparedSlots.length > 0 && !headerHtml.includes(STREAMING_RUNTIME_GLOBAL);
1108
- if (!needsRuntimeTag) {
1109
- return headerHtml;
1110
- }
1111
- return injectHtmlIntoHead(headerHtml, renderStreamingSlotsRuntimeTag(nonce));
1286
+ return consumeNextIslandChunk(false, "");
1112
1287
  };
1113
1288
  return new ReadableStream({
1114
1289
  async start(controller) {
1290
+ const reader = stream.getReader();
1115
1291
  try {
1116
- const header = resolveHeaderHtml();
1117
- controller.enqueue(toUint8(header, encoder));
1118
- await streamPreparedSlots(controller);
1119
- enqueueEncodedText(controller, encoder, footerHtml);
1120
- controller.close();
1292
+ const { pending } = await runIslandMarkerLoop(controller, reader);
1293
+ finishIslandMarkerStream(controller, pending);
1121
1294
  } catch (error) {
1122
1295
  controller.error(error);
1123
1296
  }
1124
1297
  }
1125
1298
  });
1126
1299
  };
1127
- var init_streamingSlots = __esm(() => {
1128
- init_constants();
1129
- init_escapeScriptContent();
1130
- CLOSING_BODY_TAG_LENGTH = CLOSING_BODY_TAG.length;
1131
- CLOSING_HEAD_TAG_LENGTH = CLOSING_HEAD_TAG2.length;
1132
- CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
1133
- currentStreamingSlotPolicy = {
1134
- errorHtml: undefined,
1135
- fallbackHtml: "",
1136
- maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES,
1137
- maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
1138
- timeoutMs: STREAMING_SLOT_TIMEOUT_MS
1139
- };
1140
- });
1300
+ var htmlContainsIslands = (html) => html.includes(ISLAND_MARKER);
1301
+ var injectIslandPageContext = (html, options) => {
1302
+ const manifest = globalThis.__absoluteManifest;
1303
+ const hasIslands = options?.hasIslands ?? htmlContainsIslands(html);
1304
+ if (!manifest || !hasIslands) {
1305
+ return html;
1306
+ }
1307
+ if (html.includes(MANIFEST_MARKER) || html.includes(ISLAND_STATE_MARKER)) {
1308
+ return html;
1309
+ }
1310
+ return injectHeadMarkup(html, buildIslandsHeadMarkup(manifest));
1311
+ };
1312
+ var injectIslandPageContextStream = (stream, options) => {
1313
+ const manifest = globalThis.__absoluteManifest;
1314
+ if (!manifest)
1315
+ return stream;
1316
+ const markup = buildIslandsHeadMarkup(manifest);
1317
+ if (options?.hasIslands === true) {
1318
+ return pipeStreamWithHeadInjection(stream, markup);
1319
+ }
1320
+ if (options?.hasIslands === false) {
1321
+ return stream;
1322
+ }
1323
+ return pipeStreamWithIslandMarkerDetection(stream, markup);
1324
+ };
1325
+ var setCurrentIslandManifest = (manifest) => {
1326
+ globalThis.__absoluteManifest = manifest;
1327
+ };
1328
+
1329
+ // src/react/pageHandler.ts
1330
+ init_devRouteRegistrationCallsite();
1141
1331
 
1142
1332
  // src/core/responseEnhancers.ts
1143
- var toResponse = async (responseLike) => responseLike, cloneHeaders = (response) => {
1333
+ init_streamingSlots();
1334
+ var toResponse = async (responseLike) => responseLike;
1335
+ var cloneHeaders = (response) => {
1144
1336
  const headers = new Headers(response.headers);
1145
1337
  return headers;
1146
- }, enhanceHtmlResponseWithStreamingSlots = (response, {
1338
+ };
1339
+ var enhanceHtmlResponseWithStreamingSlots = (response, {
1147
1340
  nonce,
1148
1341
  onError,
1149
1342
  runtimePlacement,
@@ -1166,14 +1359,17 @@ var toResponse = async (responseLike) => responseLike, cloneHeaders = (response)
1166
1359
  status: response.status,
1167
1360
  statusText: response.statusText
1168
1361
  });
1169
- }, withStreamingSlots = async (responseLike, options = {}) => enhanceHtmlResponseWithStreamingSlots(await toResponse(responseLike), options), mergeStreamingSlots = (registered, explicit) => {
1362
+ };
1363
+ var withStreamingSlots = async (responseLike, options = {}) => enhanceHtmlResponseWithStreamingSlots(await toResponse(responseLike), options);
1364
+ var mergeStreamingSlots = (registered, explicit) => {
1170
1365
  const merged = new Map;
1171
1366
  for (const slot of registered)
1172
1367
  merged.set(slot.id, slot);
1173
1368
  for (const slot of explicit)
1174
1369
  merged.set(slot.id, slot);
1175
1370
  return [...merged.values()];
1176
- }, withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
1371
+ };
1372
+ var withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
1177
1373
  const { result, slots } = await runWithStreamingSlotRegistry(renderResponse);
1178
1374
  const explicit = options.streamingSlots ?? [];
1179
1375
  return withStreamingSlots(result, {
@@ -1181,162 +1377,21 @@ var toResponse = async (responseLike) => responseLike, cloneHeaders = (response)
1181
1377
  streamingSlots: mergeStreamingSlots(slots, explicit)
1182
1378
  });
1183
1379
  };
1184
- var init_responseEnhancers = __esm(() => {
1185
- init_streamingSlots();
1186
- init_streamingSlotRegistry();
1187
- });
1188
-
1189
- // src/utils/getDurationString.ts
1190
- var getDurationString = (duration) => {
1191
- let durationString;
1192
- if (duration < MILLISECONDS_IN_A_SECOND) {
1193
- durationString = `${duration.toFixed(TIME_PRECISION)}ms`;
1194
- } else if (duration < MILLISECONDS_IN_A_MINUTE) {
1195
- durationString = `${(duration / MILLISECONDS_IN_A_SECOND).toFixed(TIME_PRECISION)}s`;
1196
- } else {
1197
- durationString = `${(duration / MILLISECONDS_IN_A_MINUTE).toFixed(TIME_PRECISION)}m`;
1198
- }
1199
- return durationString;
1200
- };
1201
- var init_getDurationString = __esm(() => {
1202
- init_constants();
1203
- });
1204
-
1205
- // src/utils/startupBanner.ts
1206
- var colors, MONTHS, formatTimestamp = () => {
1207
- const now = new Date;
1208
- const month = MONTHS[now.getMonth()];
1209
- const day = now.getDate().toString().padStart(2, "0");
1210
- let hours = now.getHours();
1211
- const minutes = now.getMinutes().toString().padStart(2, "0");
1212
- const seconds = now.getSeconds().toString().padStart(2, "0");
1213
- const ampm = hours >= HOURS_IN_HALF_DAY ? "PM" : "AM";
1214
- hours = hours % HOURS_IN_HALF_DAY || HOURS_IN_HALF_DAY;
1215
- return `${month} ${day} ${hours}:${minutes}:${seconds} ${ampm}`;
1216
- }, startupBanner = (options) => {
1217
- const {
1218
- version,
1219
- readyDuration,
1220
- buildDuration,
1221
- port,
1222
- host,
1223
- networkUrl,
1224
- protocol = "http"
1225
- } = options;
1226
- const name = `${colors.cyan}${colors.bold}ABSOLUTEJS${colors.reset}`;
1227
- const ver = `${colors.dim}v${version}${colors.reset}`;
1228
- const time = `${colors.dim}ready in${colors.reset} ${colors.bold}${getDurationString(readyDuration)}${colors.reset}`;
1229
- const build = typeof buildDuration === "number" && Number.isFinite(buildDuration) ? ` ${colors.dim}(build ${getDurationString(buildDuration)})${colors.reset}` : "";
1230
- console.log("");
1231
- console.log(` ${name} ${ver} ${time}${build}`);
1232
- console.log("");
1233
- console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Local:${colors.reset} ${protocol}://${host === "0.0.0.0" ? "localhost" : host}:${port}/`);
1234
- if (networkUrl) {
1235
- console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Network:${colors.reset} ${networkUrl}`);
1236
- }
1237
- console.log("");
1238
- };
1239
- var init_startupBanner = __esm(() => {
1240
- init_constants();
1241
- init_getDurationString();
1242
- colors = {
1243
- bold: "\x1B[1m",
1244
- cyan: "\x1B[36m",
1245
- dim: "\x1B[2m",
1246
- green: "\x1B[32m",
1247
- reset: "\x1B[0m"
1248
- };
1249
- MONTHS = [
1250
- "Jan",
1251
- "Feb",
1252
- "Mar",
1253
- "Apr",
1254
- "May",
1255
- "Jun",
1256
- "Jul",
1257
- "Aug",
1258
- "Sep",
1259
- "Oct",
1260
- "Nov",
1261
- "Dec"
1262
- ];
1263
- });
1264
-
1265
- // src/utils/logger.ts
1266
- var colors2, frameworkColors, formatPath = (filePath) => {
1267
- const cwd = process.cwd();
1268
- let relative = filePath.startsWith(cwd) ? filePath.slice(cwd.length + 1) : filePath;
1269
- relative = relative.replace(/\\/g, "/");
1270
- if (!relative.startsWith("/")) {
1271
- relative = `/${relative}`;
1272
- }
1273
- return relative;
1274
- }, getFrameworkColor = (framework) => frameworkColors[framework] || colors2.white, log = (action, options) => {
1275
- const timestamp = `${colors2.dim}${formatTimestamp()}${colors2.reset}`;
1276
- const tag = `${colors2.cyan}[hmr]${colors2.reset}`;
1277
- let message = action;
1278
- if (options?.path) {
1279
- const pathColor = options.framework ? getFrameworkColor(options.framework) : colors2.white;
1280
- message += ` ${pathColor}${formatPath(options.path)}${colors2.reset}`;
1281
- }
1282
- if (options?.duration !== undefined) {
1283
- message += ` ${colors2.dim}(${options.duration}ms)${colors2.reset}`;
1284
- }
1285
- console.log(`${timestamp} ${tag} ${message}`);
1286
- }, logCssUpdate = (path, framework, duration) => {
1287
- log("css update", { duration, framework: framework ?? "css", path });
1288
- }, logError = (message, error) => {
1289
- const timestamp = `${colors2.dim}${formatTimestamp()}${colors2.reset}`;
1290
- const tag = `${colors2.red}[hmr]${colors2.reset}`;
1291
- const errorMsg = error instanceof Error ? error.message : error;
1292
- const fullMessage = `${colors2.red}error${colors2.reset} ${message}${errorMsg ? `: ${errorMsg}` : ""}`;
1293
- console.error(`${timestamp} ${tag} ${fullMessage}`);
1294
- }, logHmrUpdate = (path, framework, duration) => {
1295
- log("hmr update", { duration, framework, path });
1296
- }, logScriptUpdate = (path, framework, duration) => {
1297
- log("script update", { duration, framework, path });
1298
- }, logServerReload = () => {
1299
- log(`${colors2.cyan}server module reloaded${colors2.reset}`);
1300
- }, logWarn = (message) => {
1301
- const timestamp = `${colors2.dim}${formatTimestamp()}${colors2.reset}`;
1302
- const tag = `${colors2.yellow}[hmr]${colors2.reset}`;
1303
- console.log(`${timestamp} ${tag} ${colors2.yellow}warning ${message}${colors2.reset}`);
1304
- };
1305
- var init_logger = __esm(() => {
1306
- init_startupBanner();
1307
- colors2 = {
1308
- blue: "\x1B[34m",
1309
- bold: "\x1B[1m",
1310
- cyan: "\x1B[36m",
1311
- dim: "\x1B[2m",
1312
- green: "\x1B[32m",
1313
- magenta: "\x1B[35m",
1314
- red: "\x1B[31m",
1315
- reset: "\x1B[0m",
1316
- white: "\x1B[37m",
1317
- yellow: "\x1B[33m"
1318
- };
1319
- frameworkColors = {
1320
- angular: colors2.magenta,
1321
- assets: colors2.dim,
1322
- css: colors2.cyan,
1323
- html: colors2.white,
1324
- htmx: colors2.white,
1325
- react: colors2.blue,
1326
- svelte: colors2.yellow,
1327
- vue: colors2.green
1328
- };
1329
- });
1330
1380
 
1331
1381
  // src/core/streamingSlotWarningScope.ts
1382
+ init_logger();
1332
1383
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
1333
- var STREAMING_SLOT_WARNING_STORAGE_KEY2, isObjectRecord4 = (value) => Boolean(value) && typeof value === "object", isAsyncLocalStorage3 = (value) => isObjectRecord4(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function", getWarningStorage = () => {
1384
+ var STREAMING_SLOT_WARNING_STORAGE_KEY2 = Symbol.for("absolutejs.streamingSlotWarningAsyncLocalStorage");
1385
+ var isObjectRecord4 = (value) => Boolean(value) && typeof value === "object";
1386
+ var isAsyncLocalStorage3 = (value) => isObjectRecord4(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
1387
+ var getWarningStorage = () => {
1334
1388
  const value = Reflect.get(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY2);
1335
1389
  if (value === null || typeof value === "undefined") {
1336
1390
  return;
1337
1391
  }
1338
1392
  return isAsyncLocalStorage3(value) ? value : undefined;
1339
- }, ensureWarningStorage = () => {
1393
+ };
1394
+ var ensureWarningStorage = () => {
1340
1395
  const existing = getWarningStorage();
1341
1396
  if (existing) {
1342
1397
  return existing;
@@ -1344,13 +1399,16 @@ var STREAMING_SLOT_WARNING_STORAGE_KEY2, isObjectRecord4 = (value) => Boolean(va
1344
1399
  const storage = new AsyncLocalStorage2;
1345
1400
  Reflect.set(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY2, storage);
1346
1401
  return storage;
1347
- }, normalizeCallsitePath2 = (value) => value.replace(`${process.cwd()}/`, "").replace(process.cwd(), "").replace(/^\.\/+/, ""), formatWarningCallsite = (callsite) => {
1402
+ };
1403
+ var normalizeCallsitePath2 = (value) => value.replace(`${process.cwd()}/`, "").replace(process.cwd(), "").replace(/^\.\/+/, "");
1404
+ var formatWarningCallsite = (callsite) => {
1348
1405
  const match = callsite.match(/^(.*?)(:\d+:\d+)$/);
1349
1406
  if (!match) {
1350
1407
  return `\x1B[36m${callsite}\x1B[0m`;
1351
1408
  }
1352
1409
  return `\x1B[36m${match[1]}\x1B[33m${match[2]}\x1B[0m`;
1353
- }, extractCallsiteFromStack = (stack) => {
1410
+ };
1411
+ var extractCallsiteFromStack = (stack) => {
1354
1412
  const frames = stack.split(`
1355
1413
  `).slice(1).map((line) => line.trim());
1356
1414
  for (const frame of frames) {
@@ -1363,29 +1421,30 @@ var STREAMING_SLOT_WARNING_STORAGE_KEY2, isObjectRecord4 = (value) => Boolean(va
1363
1421
  }
1364
1422
  }
1365
1423
  return;
1366
- }, buildMissingCollectorWarning = (primitiveName, handlerCallsite) => `${primitiveName} rendered during SSR without streaming slot collection enabled. Add { collectStreamingSlots: true } to this page handler to enable out-of-order streaming for this route.${handlerCallsite ? ` Update ${formatWarningCallsite(handlerCallsite)}.` : ""}`, captureStreamingSlotWarningCallsite = () => {
1424
+ };
1425
+ var buildMissingCollectorWarning = (primitiveName, handlerCallsite) => `${primitiveName} rendered during SSR without streaming slot collection enabled. Add { collectStreamingSlots: true } to this page handler to enable out-of-order streaming for this route.${handlerCallsite ? ` Update ${formatWarningCallsite(handlerCallsite)}.` : ""}`;
1426
+ setStreamingSlotWarningController({
1427
+ maybeWarn: (primitiveName) => {
1428
+ const store = getWarningStorage()?.getStore();
1429
+ if (!store || store.hasWarned) {
1430
+ return;
1431
+ }
1432
+ store.hasWarned = true;
1433
+ logWarn(buildMissingCollectorWarning(primitiveName, store.handlerCallsite));
1434
+ }
1435
+ });
1436
+ var captureStreamingSlotWarningCallsite = () => {
1367
1437
  if (false) {}
1368
1438
  const { stack } = new Error;
1369
1439
  if (!stack) {
1370
1440
  return;
1371
1441
  }
1372
1442
  return extractCallsiteFromStack(stack);
1373
- }, runWithStreamingSlotWarningScope = (task, metadata) => ensureWarningStorage().run({ handlerCallsite: metadata?.handlerCallsite, hasWarned: false }, task);
1374
- var init_streamingSlotWarningScope = __esm(() => {
1375
- init_logger();
1376
- init_streamingSlotRegistrar();
1377
- STREAMING_SLOT_WARNING_STORAGE_KEY2 = Symbol.for("absolutejs.streamingSlotWarningAsyncLocalStorage");
1378
- setStreamingSlotWarningController({
1379
- maybeWarn: (primitiveName) => {
1380
- const store = getWarningStorage()?.getStore();
1381
- if (!store || store.hasWarned) {
1382
- return;
1383
- }
1384
- store.hasWarned = true;
1385
- logWarn(buildMissingCollectorWarning(primitiveName, store.handlerCallsite));
1386
- }
1387
- });
1388
- });
1443
+ };
1444
+ var runWithStreamingSlotWarningScope = (task, metadata) => ensureWarningStorage().run({ handlerCallsite: metadata?.handlerCallsite, hasWarned: false }, task);
1445
+
1446
+ // src/react/pageHandler.ts
1447
+ init_ssrCache();
1389
1448
 
1390
1449
  // src/utils/ssrErrorPage.ts
1391
1450
  var ssrErrorPage = (framework, error) => {
@@ -1439,39 +1498,40 @@ body{min-height:100vh;background:linear-gradient(135deg,rgba(15,23,42,0.98) 0%,r
1439
1498
  </html>`;
1440
1499
  };
1441
1500
 
1442
- // src/utils/stringModifiers.ts
1443
- var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), toPascal = (str) => {
1444
- if (!str.includes("-") && !str.includes("_")) {
1445
- return str.charAt(0).toUpperCase() + str.slice(1);
1446
- }
1447
- return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
1448
- }, toScreamingSnake = (str) => str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase();
1449
-
1450
1501
  // src/utils/resolveConvention.ts
1451
1502
  import { basename } from "path";
1452
- var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boolean(value) && typeof value === "object", getMap = () => {
1503
+ var CONVENTIONS_KEY = "__absoluteConventions";
1504
+ var isConventionsMap = (value) => Boolean(value) && typeof value === "object";
1505
+ var getMap = () => {
1453
1506
  const value = Reflect.get(globalThis, CONVENTIONS_KEY);
1454
1507
  if (isConventionsMap(value))
1455
1508
  return value;
1456
1509
  const empty = {};
1457
1510
  return empty;
1458
- }, derivePageName = (pagePath) => {
1511
+ };
1512
+ var derivePageName = (pagePath) => {
1459
1513
  const base = basename(pagePath);
1460
1514
  const dotIndex = base.indexOf(".");
1461
1515
  const name = dotIndex > 0 ? base.slice(0, dotIndex) : base;
1462
1516
  return toPascal(name);
1463
- }, resolveErrorConventionPath = (framework, pageName) => {
1517
+ };
1518
+ var resolveErrorConventionPath = (framework, pageName) => {
1464
1519
  const conventions = getMap()[framework];
1465
1520
  if (!conventions)
1466
1521
  return;
1467
1522
  return conventions.pages?.[pageName]?.error ?? conventions.defaults?.error;
1468
- }, resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound, setConventions = (map) => {
1523
+ };
1524
+ var resolveNotFoundConventionPath = (framework) => getMap()[framework]?.defaults?.notFound;
1525
+ var setConventions = (map) => {
1469
1526
  Reflect.set(globalThis, CONVENTIONS_KEY, map);
1470
- }, isDev = () => true, buildErrorProps = (error) => {
1527
+ };
1528
+ var isDev = () => true;
1529
+ var buildErrorProps = (error) => {
1471
1530
  const message = error instanceof Error ? error.message : String(error);
1472
1531
  const stack = isDev() && error instanceof Error ? error.stack : undefined;
1473
1532
  return { error: { message, stack } };
1474
- }, renderReactError = async (conventionPath, errorProps) => {
1533
+ };
1534
+ var renderReactError = async (conventionPath, errorProps) => {
1475
1535
  const { createElement } = await import("react");
1476
1536
  const { renderToReadableStream } = await import("react-dom/server");
1477
1537
  const mod = await import(conventionPath);
@@ -1483,7 +1543,8 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1483
1543
  headers: { "Content-Type": "text/html" },
1484
1544
  status: 500
1485
1545
  });
1486
- }, renderSvelteError = async (conventionPath, errorProps) => {
1546
+ };
1547
+ var renderSvelteError = async (conventionPath, errorProps) => {
1487
1548
  const { render } = await import("svelte/server");
1488
1549
  const mod = await import(conventionPath);
1489
1550
  const ErrorComponent = mod.default;
@@ -1495,14 +1556,16 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1495
1556
  headers: { "Content-Type": "text/html" },
1496
1557
  status: 500
1497
1558
  });
1498
- }, unescapeVueStyles = (ssrBody) => {
1559
+ };
1560
+ var unescapeVueStyles = (ssrBody) => {
1499
1561
  let styles = "";
1500
1562
  const body = ssrBody.replace(/<style>([\s\S]*?)<\/style>/g, (_, css) => {
1501
1563
  styles += `<style>${css.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">")}</style>`;
1502
1564
  return "";
1503
1565
  });
1504
1566
  return { body, styles };
1505
- }, renderVueError = async (conventionPath, errorProps) => {
1567
+ };
1568
+ var renderVueError = async (conventionPath, errorProps) => {
1506
1569
  const { createSSRApp, h } = await import("vue");
1507
1570
  const { renderToString } = await import("vue/server-renderer");
1508
1571
  const mod = await import(conventionPath);
@@ -1517,7 +1580,8 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1517
1580
  headers: { "Content-Type": "text/html" },
1518
1581
  status: 500
1519
1582
  });
1520
- }, renderAngularError = async (conventionPath, errorProps) => {
1583
+ };
1584
+ var renderAngularError = async (conventionPath, errorProps) => {
1521
1585
  const mod = await import(conventionPath);
1522
1586
  const renderError = mod.default ?? mod.renderError;
1523
1587
  if (typeof renderError !== "function")
@@ -1527,14 +1591,22 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1527
1591
  headers: { "Content-Type": "text/html" },
1528
1592
  status: 500
1529
1593
  });
1530
- }, logConventionRenderError = (framework, label, renderError) => {
1594
+ };
1595
+ var logConventionRenderError = (framework, label, renderError) => {
1531
1596
  const message = renderError instanceof Error ? renderError.message : "";
1532
1597
  if (message.includes("Cannot find module") || message.includes("Cannot find package") || message.includes("not found in module")) {
1533
1598
  console.error(`[SSR] Convention ${label} page for ${framework} failed: missing framework package. Ensure the ${framework} runtime is installed (e.g. bun add ${framework === "react" ? "react react-dom" : framework}).`);
1534
1599
  return;
1535
1600
  }
1536
1601
  console.error(`[SSR] Failed to render ${framework} convention ${label} page:`, renderError);
1537
- }, ERROR_RENDERERS, renderConventionError = async (framework, pageName, error) => {
1602
+ };
1603
+ var ERROR_RENDERERS = {
1604
+ angular: renderAngularError,
1605
+ react: renderReactError,
1606
+ svelte: renderSvelteError,
1607
+ vue: renderVueError
1608
+ };
1609
+ var renderConventionError = async (framework, pageName, error) => {
1538
1610
  const conventionPath = resolveErrorConventionPath(framework, pageName);
1539
1611
  if (!conventionPath)
1540
1612
  return null;
@@ -1548,7 +1620,8 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1548
1620
  logConventionRenderError(framework, "error", renderError);
1549
1621
  }
1550
1622
  return null;
1551
- }, renderReactNotFound = async (conventionPath) => {
1623
+ };
1624
+ var renderReactNotFound = async (conventionPath) => {
1552
1625
  const { createElement } = await import("react");
1553
1626
  const { renderToReadableStream } = await import("react-dom/server");
1554
1627
  const mod = await import(conventionPath);
@@ -1560,7 +1633,8 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1560
1633
  headers: { "Content-Type": "text/html" },
1561
1634
  status: 404
1562
1635
  });
1563
- }, renderSvelteNotFound = async (conventionPath) => {
1636
+ };
1637
+ var renderSvelteNotFound = async (conventionPath) => {
1564
1638
  const { render } = await import("svelte/server");
1565
1639
  const mod = await import(conventionPath);
1566
1640
  const NotFoundComponent = mod.default;
@@ -1570,7 +1644,8 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1570
1644
  headers: { "Content-Type": "text/html" },
1571
1645
  status: 404
1572
1646
  });
1573
- }, renderVueNotFound = async (conventionPath) => {
1647
+ };
1648
+ var renderVueNotFound = async (conventionPath) => {
1574
1649
  const { createSSRApp, h } = await import("vue");
1575
1650
  const { renderToString } = await import("vue/server-renderer");
1576
1651
  const mod = await import(conventionPath);
@@ -1585,7 +1660,8 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1585
1660
  headers: { "Content-Type": "text/html" },
1586
1661
  status: 404
1587
1662
  });
1588
- }, renderAngularNotFound = async (conventionPath) => {
1663
+ };
1664
+ var renderAngularNotFound = async (conventionPath) => {
1589
1665
  const mod = await import(conventionPath);
1590
1666
  const renderNotFound = mod.default ?? mod.renderNotFound;
1591
1667
  if (typeof renderNotFound !== "function")
@@ -1595,7 +1671,14 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1595
1671
  headers: { "Content-Type": "text/html" },
1596
1672
  status: 404
1597
1673
  });
1598
- }, NOT_FOUND_RENDERERS, renderConventionNotFound = async (framework) => {
1674
+ };
1675
+ var NOT_FOUND_RENDERERS = {
1676
+ angular: renderAngularNotFound,
1677
+ react: renderReactNotFound,
1678
+ svelte: renderSvelteNotFound,
1679
+ vue: renderVueNotFound
1680
+ };
1681
+ var renderConventionNotFound = async (framework) => {
1599
1682
  const conventionPath = resolveNotFoundConventionPath(framework);
1600
1683
  if (!conventionPath)
1601
1684
  return null;
@@ -1608,7 +1691,14 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1608
1691
  logConventionRenderError(framework, "not-found", renderError);
1609
1692
  }
1610
1693
  return null;
1611
- }, NOT_FOUND_PRIORITY, renderFirstNotFound = async () => {
1694
+ };
1695
+ var NOT_FOUND_PRIORITY = [
1696
+ "react",
1697
+ "svelte",
1698
+ "vue",
1699
+ "angular"
1700
+ ];
1701
+ var renderFirstNotFound = async () => {
1612
1702
  for (const framework of NOT_FOUND_PRIORITY) {
1613
1703
  if (!getMap()[framework]?.defaults?.notFound)
1614
1704
  continue;
@@ -1618,37 +1708,13 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
1618
1708
  }
1619
1709
  return null;
1620
1710
  };
1621
- var init_resolveConvention = __esm(() => {
1622
- ERROR_RENDERERS = {
1623
- angular: renderAngularError,
1624
- react: renderReactError,
1625
- svelte: renderSvelteError,
1626
- vue: renderVueError
1627
- };
1628
- NOT_FOUND_RENDERERS = {
1629
- angular: renderAngularNotFound,
1630
- react: renderReactNotFound,
1631
- svelte: renderSvelteNotFound,
1632
- vue: renderVueNotFound
1633
- };
1634
- NOT_FOUND_PRIORITY = [
1635
- "react",
1636
- "svelte",
1637
- "vue",
1638
- "angular"
1639
- ];
1640
- });
1641
1711
 
1642
1712
  // src/react/pageHandler.ts
1643
- var exports_pageHandler = {};
1644
- __export(exports_pageHandler, {
1645
- invalidateReactSsrCache: () => invalidateReactSsrCache,
1646
- handleReactPageRequest: () => handleReactPageRequest
1647
- });
1648
- var ssrDirty = false, buildRefreshSetup = () => {
1713
+ var buildRefreshSetup = () => {
1649
1714
  if (false) {}
1650
1715
  return "window.__REFRESH_BUFFER__=[];" + "window.$RefreshReg$=function(t,i){window.__REFRESH_BUFFER__.push([t,i])};" + "window.$RefreshSig$=function(){return function(t){return t}};";
1651
- }, buildDirtyResponse = (index, maybeProps) => {
1716
+ };
1717
+ var buildDirtyResponse = (index, maybeProps) => {
1652
1718
  const propsScript = maybeProps ? `window.__INITIAL_PROPS__=${JSON.stringify(maybeProps)};` : "";
1653
1719
  const dirtyFlag = "window.__SSR_DIRTY__=true;";
1654
1720
  const refreshSetup = buildRefreshSetup();
@@ -1657,7 +1723,8 @@ var ssrDirty = false, buildRefreshSetup = () => {
1657
1723
  return new Response(html, {
1658
1724
  headers: { "Content-Type": "text/html" }
1659
1725
  });
1660
- }, handleReactPageRequest = async (PageComponentOrInput, index, ...args) => {
1726
+ };
1727
+ var handleReactPageRequest = async (PageComponentOrInput, index, ...args) => {
1661
1728
  const {
1662
1729
  Page,
1663
1730
  index: resolvedIndex,
@@ -1674,7 +1741,7 @@ var ssrDirty = false, buildRefreshSetup = () => {
1674
1741
  Page: PageComponentOrInput,
1675
1742
  props: args[0]
1676
1743
  };
1677
- if (ssrDirty) {
1744
+ if (isSsrCacheDirty("react")) {
1678
1745
  return buildDirtyResponse(resolvedIndex, maybeProps);
1679
1746
  }
1680
1747
  try {
@@ -1709,22 +1776,10 @@ var ssrDirty = false, buildRefreshSetup = () => {
1709
1776
  status: 500
1710
1777
  });
1711
1778
  }
1712
- }, invalidateReactSsrCache = () => {
1713
- ssrDirty = true;
1714
- };
1715
- var init_pageHandler = __esm(() => {
1716
- init_islandPageContext();
1717
- init_devRouteRegistrationCallsite();
1718
- init_responseEnhancers();
1719
- init_streamingSlotWarningScope();
1720
- init_resolveConvention();
1721
- });
1722
-
1723
- // src/react/server.ts
1724
- init_pageHandler();
1779
+ };
1725
1780
  export {
1726
1781
  handleReactPageRequest
1727
1782
  };
1728
1783
 
1729
- //# debugId=B70552A53653340764756E2164756E21
1784
+ //# debugId=9355997A064C174964756E2164756E21
1730
1785
  //# sourceMappingURL=server.js.map