@reckona/mreact-router 0.0.155 → 0.0.157
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/adapters/cloudflare.d.ts.map +1 -1
- package/dist/adapters/cloudflare.js +60 -4
- package/dist/adapters/cloudflare.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -0
- package/dist/client.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +5 -1
- package/dist/render.js.map +1 -1
- package/package.json +11 -11
- package/src/adapters/cloudflare.ts +79 -3
- package/src/client.ts +8 -0
- package/src/render.ts +6 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reckona/mreact-router",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.157",
|
|
4
4
|
"description": "File-system app router, SSR, actions, and deployment adapters for mreact.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jsx",
|
|
@@ -105,20 +105,20 @@
|
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
107
|
"typescript": "^6.0.3",
|
|
108
|
-
"@reckona/mreact": "0.0.
|
|
109
|
-
"@reckona/mreact-
|
|
110
|
-
"@reckona/mreact-
|
|
111
|
-
"@reckona/mreact-
|
|
112
|
-
"@reckona/mreact-
|
|
113
|
-
"@reckona/mreact
|
|
114
|
-
"@reckona/mreact-reactive-dom": "0.0.
|
|
115
|
-
"@reckona/mreact-server": "0.0.
|
|
116
|
-
"@reckona/mreact-shared": "0.0.
|
|
108
|
+
"@reckona/mreact-compat": "0.0.157",
|
|
109
|
+
"@reckona/mreact-devtools": "0.0.157",
|
|
110
|
+
"@reckona/mreact-query": "0.0.157",
|
|
111
|
+
"@reckona/mreact-reactive-core": "0.0.157",
|
|
112
|
+
"@reckona/mreact-compiler": "0.0.157",
|
|
113
|
+
"@reckona/mreact": "0.0.157",
|
|
114
|
+
"@reckona/mreact-reactive-dom": "0.0.157",
|
|
115
|
+
"@reckona/mreact-server": "0.0.157",
|
|
116
|
+
"@reckona/mreact-shared": "0.0.157"
|
|
117
117
|
},
|
|
118
118
|
"peerDependencies": {
|
|
119
119
|
"vite": ">=8 <9"
|
|
120
120
|
},
|
|
121
121
|
"optionalDependencies": {
|
|
122
|
-
"@reckona/mreact-router-native": "0.0.
|
|
122
|
+
"@reckona/mreact-router-native": "0.0.157"
|
|
123
123
|
}
|
|
124
124
|
}
|
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
__MREACT_QUERY_STATE_SCRIPT_ID,
|
|
6
6
|
createQueryClient,
|
|
7
7
|
dehydrate,
|
|
8
|
+
installQueryAsyncStorage,
|
|
8
9
|
isQueryClientScopeUnavailableError,
|
|
9
10
|
runWithQueryClient,
|
|
10
11
|
type DehydratedQueryClient,
|
|
12
|
+
type QueryAsyncStorage,
|
|
11
13
|
type QueryClient,
|
|
12
14
|
} from "@reckona/mreact-query";
|
|
13
15
|
import type {
|
|
@@ -489,18 +491,92 @@ function injectCloudflareQueryStateScript(html: string, state: DehydratedQueryCl
|
|
|
489
491
|
: `${html}${script}`;
|
|
490
492
|
}
|
|
491
493
|
|
|
492
|
-
function runWithCloudflareQueryClient<T>(
|
|
494
|
+
async function runWithCloudflareQueryClient<T>(
|
|
495
|
+
queryClient: QueryClient,
|
|
496
|
+
fn: () => T,
|
|
497
|
+
): Promise<Awaited<T>> {
|
|
493
498
|
try {
|
|
494
|
-
return runWithQueryClient(queryClient, fn);
|
|
499
|
+
return await runWithQueryClient(queryClient, fn);
|
|
495
500
|
} catch (error) {
|
|
496
501
|
if (isQueryClientScopeUnavailableError(error)) {
|
|
497
|
-
|
|
502
|
+
installQueryAsyncStorage(cloudflareQueryClientStorage);
|
|
503
|
+
return await runWithSerializedCloudflareQueryClient(queryClient, fn);
|
|
498
504
|
}
|
|
499
505
|
|
|
500
506
|
throw error;
|
|
501
507
|
}
|
|
502
508
|
}
|
|
503
509
|
|
|
510
|
+
const cloudflareQueryClientStorage = createCloudflareQueryClientStorage();
|
|
511
|
+
let cloudflareQueryClientFallbackQueue: Promise<void> = Promise.resolve();
|
|
512
|
+
|
|
513
|
+
async function runWithSerializedCloudflareQueryClient<T>(
|
|
514
|
+
queryClient: QueryClient,
|
|
515
|
+
fn: () => T,
|
|
516
|
+
): Promise<Awaited<T>> {
|
|
517
|
+
const previous = cloudflareQueryClientFallbackQueue;
|
|
518
|
+
let releaseCurrent!: () => void;
|
|
519
|
+
const current = new Promise<void>((resolve) => {
|
|
520
|
+
releaseCurrent = resolve;
|
|
521
|
+
});
|
|
522
|
+
cloudflareQueryClientFallbackQueue = previous.then(() => current, () => current);
|
|
523
|
+
|
|
524
|
+
await previous;
|
|
525
|
+
|
|
526
|
+
try {
|
|
527
|
+
return await runWithQueryClient(queryClient, fn);
|
|
528
|
+
} finally {
|
|
529
|
+
releaseCurrent();
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function createCloudflareQueryClientStorage(): QueryAsyncStorage<QueryClient> {
|
|
534
|
+
const stores: QueryClient[] = [];
|
|
535
|
+
|
|
536
|
+
return {
|
|
537
|
+
getStore() {
|
|
538
|
+
return stores.at(-1);
|
|
539
|
+
},
|
|
540
|
+
run<TResult>(store: QueryClient, callback: () => TResult): TResult {
|
|
541
|
+
stores.push(store);
|
|
542
|
+
let popSynchronously = true;
|
|
543
|
+
|
|
544
|
+
try {
|
|
545
|
+
const result = callback();
|
|
546
|
+
|
|
547
|
+
if (isPromiseLike(result)) {
|
|
548
|
+
popSynchronously = false;
|
|
549
|
+
return Promise.resolve(result).finally(() => {
|
|
550
|
+
removeCloudflareQueryClientStore(stores, store);
|
|
551
|
+
}) as TResult;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
return result;
|
|
555
|
+
} finally {
|
|
556
|
+
if (popSynchronously) {
|
|
557
|
+
removeCloudflareQueryClientStore(stores, store);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function removeCloudflareQueryClientStore(stores: QueryClient[], store: QueryClient): void {
|
|
565
|
+
const index = stores.lastIndexOf(store);
|
|
566
|
+
|
|
567
|
+
if (index >= 0) {
|
|
568
|
+
stores.splice(index, 1);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
|
|
573
|
+
return (
|
|
574
|
+
(typeof value === "object" || typeof value === "function") &&
|
|
575
|
+
value !== null &&
|
|
576
|
+
typeof (value as { then?: unknown }).then === "function"
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
504
580
|
async function dispatchCloudflareServerRoute<Env>(
|
|
505
581
|
module: CloudflareServerRouteModule<Env>,
|
|
506
582
|
request: Request,
|
package/src/client.ts
CHANGED
|
@@ -3786,6 +3786,13 @@ function __mreactApplyOutOfOrderFragments(root) {
|
|
|
3786
3786
|
continue;
|
|
3787
3787
|
}
|
|
3788
3788
|
|
|
3789
|
+
const completionMarker = Array.from(root.querySelectorAll("[data-mreact-oob-complete]"))
|
|
3790
|
+
.find((candidate) => candidate.getAttribute("data-mreact-oob-complete") === id);
|
|
3791
|
+
|
|
3792
|
+
if (completionMarker === undefined) {
|
|
3793
|
+
continue;
|
|
3794
|
+
}
|
|
3795
|
+
|
|
3789
3796
|
const placeholder = Array.from(root.querySelectorAll("[data-mreact-oob-placeholder]"))
|
|
3790
3797
|
.find((candidate) => candidate.getAttribute("data-mreact-oob-placeholder") === id);
|
|
3791
3798
|
|
|
@@ -3795,6 +3802,7 @@ function __mreactApplyOutOfOrderFragments(root) {
|
|
|
3795
3802
|
|
|
3796
3803
|
placeholder.replaceWith(fragment.content.cloneNode(true));
|
|
3797
3804
|
fragment.remove();
|
|
3805
|
+
completionMarker.remove();
|
|
3798
3806
|
}
|
|
3799
3807
|
}
|
|
3800
3808
|
|
package/src/render.ts
CHANGED
|
@@ -3500,9 +3500,12 @@ async function renderVisibleOutOfOrderFragment<T>(
|
|
|
3500
3500
|
);
|
|
3501
3501
|
await fragmentSink.drain();
|
|
3502
3502
|
|
|
3503
|
-
sink.append(
|
|
3504
|
-
|
|
3505
|
-
|
|
3503
|
+
sink.append(renderVisibleOutOfOrderFragmentHtml(id, fragmentSink.toString()));
|
|
3504
|
+
}
|
|
3505
|
+
|
|
3506
|
+
function renderVisibleOutOfOrderFragmentHtml(id: string, html: string): string {
|
|
3507
|
+
const escapedId = escapeHtmlAttribute(id);
|
|
3508
|
+
return `<template data-mreact-oob-fragment="${escapedId}">${html}</template><mreact-oob-complete hidden data-mreact-oob-complete="${escapedId}"></mreact-oob-complete>`;
|
|
3506
3509
|
}
|
|
3507
3510
|
|
|
3508
3511
|
async function appendServerStreamModule(
|