@async/framework 0.11.11 → 0.11.13
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/CHANGELOG.md +29 -0
- package/README.md +8 -0
- package/browser.js +176 -109
- package/browser.min.js +1 -1
- package/browser.ts +176 -109
- package/browser.umd.js +176 -109
- package/browser.umd.min.js +1 -1
- package/framework.ts +176 -109
- package/package.json +1 -1
- package/server.js +176 -109
package/framework.ts
CHANGED
|
@@ -2576,12 +2576,17 @@ const __serverModule = (() => {
|
|
|
2576
2576
|
if (!element) {
|
|
2577
2577
|
return {};
|
|
2578
2578
|
}
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
value
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2579
|
+
const input = {};
|
|
2580
|
+
if ("value" in element) {
|
|
2581
|
+
input.value = element.value;
|
|
2582
|
+
}
|
|
2583
|
+
if ("checked" in element) {
|
|
2584
|
+
input.checked = element.checked;
|
|
2585
|
+
}
|
|
2586
|
+
if (element.dataset) {
|
|
2587
|
+
input.dataset = { ...element.dataset };
|
|
2588
|
+
}
|
|
2589
|
+
return input;
|
|
2585
2590
|
}
|
|
2586
2591
|
|
|
2587
2592
|
function createServerNamespace(run, root = {}, contextProvider = () => ({})) {
|
|
@@ -2768,38 +2773,76 @@ const __serverModule = (() => {
|
|
|
2768
2773
|
return output;
|
|
2769
2774
|
}
|
|
2770
2775
|
|
|
2771
|
-
function assertJsonTransportable(value, stack = new Set()) {
|
|
2772
|
-
if (
|
|
2773
|
-
|
|
2776
|
+
function assertJsonTransportable(value, path = "$", stack = new Set()) {
|
|
2777
|
+
if (value === null) {
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
const type = typeof value;
|
|
2782
|
+
if (type === "boolean" || type === "string") {
|
|
2783
|
+
return;
|
|
2774
2784
|
}
|
|
2775
|
-
if (
|
|
2785
|
+
if (type === "number") {
|
|
2786
|
+
if (!Number.isFinite(value)) {
|
|
2787
|
+
throw new Error(`Server proxy JSON transport does not support non-finite numbers at ${path}.`);
|
|
2788
|
+
}
|
|
2776
2789
|
return;
|
|
2777
2790
|
}
|
|
2791
|
+
if (type === "bigint") {
|
|
2792
|
+
throw new Error(`Server proxy JSON transport does not support BigInt values at ${path}.`);
|
|
2793
|
+
}
|
|
2794
|
+
if (type === "undefined") {
|
|
2795
|
+
throw new Error(`Server proxy JSON transport does not support undefined values at ${path}.`);
|
|
2796
|
+
}
|
|
2797
|
+
if (type === "function" || type === "symbol") {
|
|
2798
|
+
throw new Error(`Server proxy JSON transport does not support ${type} values at ${path}.`);
|
|
2799
|
+
}
|
|
2800
|
+
if (type !== "object") {
|
|
2801
|
+
throw new Error(`Server proxy JSON transport does not support ${type} values at ${path}.`);
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2778
2804
|
if (stack.has(value)) {
|
|
2779
|
-
throw new Error(
|
|
2805
|
+
throw new Error(`Server proxy JSON transport does not support circular values at ${path}.`);
|
|
2780
2806
|
}
|
|
2781
2807
|
stack.add(value);
|
|
2782
2808
|
|
|
2783
2809
|
const tag = Object.prototype.toString.call(value);
|
|
2784
2810
|
if (tag === "[object File]" || tag === "[object Blob]" || tag === "[object FormData]") {
|
|
2785
|
-
throw new Error(
|
|
2811
|
+
throw new Error(`Server proxy JSON transport does not support File, Blob, or FormData values yet at ${path}.`);
|
|
2786
2812
|
}
|
|
2787
2813
|
if (isUnsupportedJsonTransportObject(value, tag)) {
|
|
2788
|
-
throw new Error(
|
|
2814
|
+
throw new Error(`Server proxy JSON transport does not support URLSearchParams, Headers, Request, Response, ReadableStream, ArrayBuffer, or typed array values yet at ${path}.`);
|
|
2789
2815
|
}
|
|
2790
2816
|
if (Array.isArray(value)) {
|
|
2791
|
-
for (
|
|
2792
|
-
|
|
2817
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
2818
|
+
if (!Object.hasOwn(value, index)) {
|
|
2819
|
+
throw new Error(`Server proxy JSON transport does not support sparse arrays at ${path}[${index}].`);
|
|
2820
|
+
}
|
|
2821
|
+
assertJsonTransportable(value[index], `${path}[${index}]`, stack);
|
|
2793
2822
|
}
|
|
2794
2823
|
stack.delete(value);
|
|
2795
2824
|
return;
|
|
2796
2825
|
}
|
|
2797
|
-
|
|
2798
|
-
|
|
2826
|
+
|
|
2827
|
+
if (!isPlainJsonObject(value)) {
|
|
2828
|
+
throw new Error(`Server proxy JSON transport only supports plain objects at ${path}.`);
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
for (const [key, item] of Object.entries(value)) {
|
|
2832
|
+
assertJsonTransportable(item, propertyPath(path, key), stack);
|
|
2799
2833
|
}
|
|
2800
2834
|
stack.delete(value);
|
|
2801
2835
|
}
|
|
2802
2836
|
|
|
2837
|
+
function isPlainJsonObject(value) {
|
|
2838
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2839
|
+
return prototype === Object.prototype || prototype === null;
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
function propertyPath(path, key) {
|
|
2843
|
+
return /^[A-Za-z_$][\w$]*$/.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;
|
|
2844
|
+
}
|
|
2845
|
+
|
|
2803
2846
|
function isUnsupportedJsonTransportObject(value, tag = Object.prototype.toString.call(value)) {
|
|
2804
2847
|
return tag === "[object URLSearchParams]"
|
|
2805
2848
|
|| tag === "[object Headers]"
|
|
@@ -5984,101 +6027,25 @@ const __boundaryReceiverModule = (() => {
|
|
|
5984
6027
|
|
|
5985
6028
|
const normalized = validatePatch(patch);
|
|
5986
6029
|
const record = boundaryRecord(normalized.boundary);
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
};
|
|
5994
|
-
record.ignored += 1;
|
|
5995
|
-
record.lastStatus = result.status;
|
|
5996
|
-
remember(result);
|
|
5997
|
-
onIgnore?.(result, patch);
|
|
5998
|
-
return result;
|
|
5999
|
-
}
|
|
6000
|
-
|
|
6001
|
-
if (normalized.parentScope !== undefined && isScopeDestroyed(normalized.parentScope)) {
|
|
6002
|
-
const result = {
|
|
6003
|
-
status: "ignored-destroyed",
|
|
6004
|
-
boundary: normalized.boundary,
|
|
6005
|
-
seq: normalized.seq,
|
|
6006
|
-
parentScope: normalized.parentScope
|
|
6007
|
-
};
|
|
6008
|
-
record.ignored += 1;
|
|
6009
|
-
record.lastStatus = result.status;
|
|
6010
|
-
remember(result);
|
|
6011
|
-
onIgnore?.(result, patch);
|
|
6012
|
-
return result;
|
|
6013
|
-
}
|
|
6014
|
-
|
|
6015
|
-
record.lastSeq = normalized.seq;
|
|
6016
|
-
|
|
6017
|
-
if (Object.hasOwn(normalized, "error")) {
|
|
6018
|
-
const error = toStableError(normalized.error);
|
|
6019
|
-
const result = {
|
|
6020
|
-
status: "errored",
|
|
6021
|
-
boundary: normalized.boundary,
|
|
6022
|
-
seq: normalized.seq,
|
|
6023
|
-
error
|
|
6024
|
-
};
|
|
6025
|
-
record.errored += 1;
|
|
6026
|
-
record.lastStatus = result.status;
|
|
6027
|
-
remember(result);
|
|
6028
|
-
onError?.(error, result, patch);
|
|
6029
|
-
if (throwOnError) {
|
|
6030
|
-
throw error;
|
|
6031
|
-
}
|
|
6032
|
-
return result;
|
|
6033
|
-
}
|
|
6030
|
+
let releasePending;
|
|
6031
|
+
const previousPending = record.pending ?? Promise.resolve();
|
|
6032
|
+
const pending = new Promise((resolve) => {
|
|
6033
|
+
releasePending = resolve;
|
|
6034
|
+
});
|
|
6035
|
+
record.pending = pending;
|
|
6034
6036
|
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
for (const [path, value] of Object.entries(normalized.signals)) {
|
|
6040
|
-
signals.set(path, value);
|
|
6037
|
+
try {
|
|
6038
|
+
await previousPending;
|
|
6039
|
+
if (destroyed) {
|
|
6040
|
+
throw new Error("Boundary receiver has been destroyed.");
|
|
6041
6041
|
}
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
if (
|
|
6046
|
-
|
|
6042
|
+
return await applyBoundaryPatch(record, normalized, patch);
|
|
6043
|
+
} finally {
|
|
6044
|
+
releasePending();
|
|
6045
|
+
if (record.pending === pending) {
|
|
6046
|
+
record.pending = undefined;
|
|
6047
6047
|
}
|
|
6048
|
-
cache.restore(normalized.cache.browser);
|
|
6049
6048
|
}
|
|
6050
|
-
|
|
6051
|
-
if (normalized.html != null) {
|
|
6052
|
-
loader.swap(normalized.boundary, normalized.html);
|
|
6053
|
-
}
|
|
6054
|
-
|
|
6055
|
-
await flushScheduler(scheduler, normalized.scope);
|
|
6056
|
-
|
|
6057
|
-
if (normalized.redirect) {
|
|
6058
|
-
await followRedirect(normalized.redirect, router, loader);
|
|
6059
|
-
const result = {
|
|
6060
|
-
status: "redirected",
|
|
6061
|
-
boundary: normalized.boundary,
|
|
6062
|
-
seq: normalized.seq,
|
|
6063
|
-
redirect: normalized.redirect
|
|
6064
|
-
};
|
|
6065
|
-
record.applied += 1;
|
|
6066
|
-
record.lastStatus = result.status;
|
|
6067
|
-
remember(result);
|
|
6068
|
-
onApply?.(result, patch);
|
|
6069
|
-
return result;
|
|
6070
|
-
}
|
|
6071
|
-
|
|
6072
|
-
const result = {
|
|
6073
|
-
status: "applied",
|
|
6074
|
-
boundary: normalized.boundary,
|
|
6075
|
-
seq: normalized.seq
|
|
6076
|
-
};
|
|
6077
|
-
record.applied += 1;
|
|
6078
|
-
record.lastStatus = result.status;
|
|
6079
|
-
remember(result);
|
|
6080
|
-
onApply?.(result, patch);
|
|
6081
|
-
return result;
|
|
6082
6049
|
},
|
|
6083
6050
|
|
|
6084
6051
|
inspect() {
|
|
@@ -6126,6 +6093,105 @@ const __boundaryReceiverModule = (() => {
|
|
|
6126
6093
|
|
|
6127
6094
|
return receiver;
|
|
6128
6095
|
|
|
6096
|
+
async function applyBoundaryPatch(record, normalized, patch) {
|
|
6097
|
+
if (normalized.seq <= record.lastSeq) {
|
|
6098
|
+
const result = {
|
|
6099
|
+
status: "ignored-stale",
|
|
6100
|
+
boundary: normalized.boundary,
|
|
6101
|
+
seq: normalized.seq,
|
|
6102
|
+
lastSeq: record.lastSeq
|
|
6103
|
+
};
|
|
6104
|
+
record.ignored += 1;
|
|
6105
|
+
record.lastStatus = result.status;
|
|
6106
|
+
remember(result);
|
|
6107
|
+
onIgnore?.(result, patch);
|
|
6108
|
+
return result;
|
|
6109
|
+
}
|
|
6110
|
+
|
|
6111
|
+
if (normalized.parentScope !== undefined && isScopeDestroyed(normalized.parentScope)) {
|
|
6112
|
+
const result = {
|
|
6113
|
+
status: "ignored-destroyed",
|
|
6114
|
+
boundary: normalized.boundary,
|
|
6115
|
+
seq: normalized.seq,
|
|
6116
|
+
parentScope: normalized.parentScope
|
|
6117
|
+
};
|
|
6118
|
+
record.ignored += 1;
|
|
6119
|
+
record.lastStatus = result.status;
|
|
6120
|
+
remember(result);
|
|
6121
|
+
onIgnore?.(result, patch);
|
|
6122
|
+
return result;
|
|
6123
|
+
}
|
|
6124
|
+
|
|
6125
|
+
if (Object.hasOwn(normalized, "error")) {
|
|
6126
|
+
const error = toStableError(normalized.error);
|
|
6127
|
+
const result = {
|
|
6128
|
+
status: "errored",
|
|
6129
|
+
boundary: normalized.boundary,
|
|
6130
|
+
seq: normalized.seq,
|
|
6131
|
+
error
|
|
6132
|
+
};
|
|
6133
|
+
record.lastSeq = normalized.seq;
|
|
6134
|
+
record.errored += 1;
|
|
6135
|
+
record.lastStatus = result.status;
|
|
6136
|
+
remember(result);
|
|
6137
|
+
onError?.(error, result, patch);
|
|
6138
|
+
if (throwOnError) {
|
|
6139
|
+
throw error;
|
|
6140
|
+
}
|
|
6141
|
+
return result;
|
|
6142
|
+
}
|
|
6143
|
+
|
|
6144
|
+
if (normalized.signals) {
|
|
6145
|
+
if (!signals || typeof signals.set !== "function") {
|
|
6146
|
+
throw new Error("Boundary patch includes signals, but no signal registry is available.");
|
|
6147
|
+
}
|
|
6148
|
+
for (const [path, value] of Object.entries(normalized.signals)) {
|
|
6149
|
+
signals.set(path, value);
|
|
6150
|
+
}
|
|
6151
|
+
}
|
|
6152
|
+
|
|
6153
|
+
if (normalized.cache?.browser) {
|
|
6154
|
+
if (!cache || typeof cache.restore !== "function") {
|
|
6155
|
+
throw new Error("Boundary patch includes browser cache, but no cache registry is available.");
|
|
6156
|
+
}
|
|
6157
|
+
cache.restore(normalized.cache.browser);
|
|
6158
|
+
}
|
|
6159
|
+
|
|
6160
|
+
if (normalized.html != null) {
|
|
6161
|
+
loader.swap(normalized.boundary, normalized.html);
|
|
6162
|
+
}
|
|
6163
|
+
|
|
6164
|
+
await flushScheduler(scheduler, normalized.scope);
|
|
6165
|
+
|
|
6166
|
+
if (normalized.redirect) {
|
|
6167
|
+
const result = {
|
|
6168
|
+
status: "redirected",
|
|
6169
|
+
boundary: normalized.boundary,
|
|
6170
|
+
seq: normalized.seq,
|
|
6171
|
+
redirect: normalized.redirect
|
|
6172
|
+
};
|
|
6173
|
+
await followRedirect(normalized.redirect, router, loader);
|
|
6174
|
+
record.applied += 1;
|
|
6175
|
+
record.lastSeq = normalized.seq;
|
|
6176
|
+
record.lastStatus = result.status;
|
|
6177
|
+
remember(result);
|
|
6178
|
+
onApply?.(result, patch);
|
|
6179
|
+
return result;
|
|
6180
|
+
}
|
|
6181
|
+
|
|
6182
|
+
const result = {
|
|
6183
|
+
status: "applied",
|
|
6184
|
+
boundary: normalized.boundary,
|
|
6185
|
+
seq: normalized.seq
|
|
6186
|
+
};
|
|
6187
|
+
record.applied += 1;
|
|
6188
|
+
record.lastSeq = normalized.seq;
|
|
6189
|
+
record.lastStatus = result.status;
|
|
6190
|
+
remember(result);
|
|
6191
|
+
onApply?.(result, patch);
|
|
6192
|
+
return result;
|
|
6193
|
+
}
|
|
6194
|
+
|
|
6129
6195
|
function boundaryRecord(boundary) {
|
|
6130
6196
|
if (!boundaries.has(boundary)) {
|
|
6131
6197
|
boundaries.set(boundary, {
|
|
@@ -6133,7 +6199,8 @@ const __boundaryReceiverModule = (() => {
|
|
|
6133
6199
|
applied: 0,
|
|
6134
6200
|
ignored: 0,
|
|
6135
6201
|
errored: 0,
|
|
6136
|
-
lastStatus: undefined
|
|
6202
|
+
lastStatus: undefined,
|
|
6203
|
+
pending: undefined
|
|
6137
6204
|
});
|
|
6138
6205
|
}
|
|
6139
6206
|
return boundaries.get(boundary);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@async/framework",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.13",
|
|
4
4
|
"description": "No-build Loader app runtime with browser and server entrypoints, signals, command events, route partials, cache split, SSR activation, and streaming boundaries.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./server.js",
|
package/server.js
CHANGED
|
@@ -2575,12 +2575,17 @@ const __serverModule = (() => {
|
|
|
2575
2575
|
if (!element) {
|
|
2576
2576
|
return {};
|
|
2577
2577
|
}
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
value
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2578
|
+
const input = {};
|
|
2579
|
+
if ("value" in element) {
|
|
2580
|
+
input.value = element.value;
|
|
2581
|
+
}
|
|
2582
|
+
if ("checked" in element) {
|
|
2583
|
+
input.checked = element.checked;
|
|
2584
|
+
}
|
|
2585
|
+
if (element.dataset) {
|
|
2586
|
+
input.dataset = { ...element.dataset };
|
|
2587
|
+
}
|
|
2588
|
+
return input;
|
|
2584
2589
|
}
|
|
2585
2590
|
|
|
2586
2591
|
function createServerNamespace(run, root = {}, contextProvider = () => ({})) {
|
|
@@ -2767,38 +2772,76 @@ const __serverModule = (() => {
|
|
|
2767
2772
|
return output;
|
|
2768
2773
|
}
|
|
2769
2774
|
|
|
2770
|
-
function assertJsonTransportable(value, stack = new Set()) {
|
|
2771
|
-
if (
|
|
2772
|
-
|
|
2775
|
+
function assertJsonTransportable(value, path = "$", stack = new Set()) {
|
|
2776
|
+
if (value === null) {
|
|
2777
|
+
return;
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
const type = typeof value;
|
|
2781
|
+
if (type === "boolean" || type === "string") {
|
|
2782
|
+
return;
|
|
2773
2783
|
}
|
|
2774
|
-
if (
|
|
2784
|
+
if (type === "number") {
|
|
2785
|
+
if (!Number.isFinite(value)) {
|
|
2786
|
+
throw new Error(`Server proxy JSON transport does not support non-finite numbers at ${path}.`);
|
|
2787
|
+
}
|
|
2775
2788
|
return;
|
|
2776
2789
|
}
|
|
2790
|
+
if (type === "bigint") {
|
|
2791
|
+
throw new Error(`Server proxy JSON transport does not support BigInt values at ${path}.`);
|
|
2792
|
+
}
|
|
2793
|
+
if (type === "undefined") {
|
|
2794
|
+
throw new Error(`Server proxy JSON transport does not support undefined values at ${path}.`);
|
|
2795
|
+
}
|
|
2796
|
+
if (type === "function" || type === "symbol") {
|
|
2797
|
+
throw new Error(`Server proxy JSON transport does not support ${type} values at ${path}.`);
|
|
2798
|
+
}
|
|
2799
|
+
if (type !== "object") {
|
|
2800
|
+
throw new Error(`Server proxy JSON transport does not support ${type} values at ${path}.`);
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2777
2803
|
if (stack.has(value)) {
|
|
2778
|
-
throw new Error(
|
|
2804
|
+
throw new Error(`Server proxy JSON transport does not support circular values at ${path}.`);
|
|
2779
2805
|
}
|
|
2780
2806
|
stack.add(value);
|
|
2781
2807
|
|
|
2782
2808
|
const tag = Object.prototype.toString.call(value);
|
|
2783
2809
|
if (tag === "[object File]" || tag === "[object Blob]" || tag === "[object FormData]") {
|
|
2784
|
-
throw new Error(
|
|
2810
|
+
throw new Error(`Server proxy JSON transport does not support File, Blob, or FormData values yet at ${path}.`);
|
|
2785
2811
|
}
|
|
2786
2812
|
if (isUnsupportedJsonTransportObject(value, tag)) {
|
|
2787
|
-
throw new Error(
|
|
2813
|
+
throw new Error(`Server proxy JSON transport does not support URLSearchParams, Headers, Request, Response, ReadableStream, ArrayBuffer, or typed array values yet at ${path}.`);
|
|
2788
2814
|
}
|
|
2789
2815
|
if (Array.isArray(value)) {
|
|
2790
|
-
for (
|
|
2791
|
-
|
|
2816
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
2817
|
+
if (!Object.hasOwn(value, index)) {
|
|
2818
|
+
throw new Error(`Server proxy JSON transport does not support sparse arrays at ${path}[${index}].`);
|
|
2819
|
+
}
|
|
2820
|
+
assertJsonTransportable(value[index], `${path}[${index}]`, stack);
|
|
2792
2821
|
}
|
|
2793
2822
|
stack.delete(value);
|
|
2794
2823
|
return;
|
|
2795
2824
|
}
|
|
2796
|
-
|
|
2797
|
-
|
|
2825
|
+
|
|
2826
|
+
if (!isPlainJsonObject(value)) {
|
|
2827
|
+
throw new Error(`Server proxy JSON transport only supports plain objects at ${path}.`);
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
for (const [key, item] of Object.entries(value)) {
|
|
2831
|
+
assertJsonTransportable(item, propertyPath(path, key), stack);
|
|
2798
2832
|
}
|
|
2799
2833
|
stack.delete(value);
|
|
2800
2834
|
}
|
|
2801
2835
|
|
|
2836
|
+
function isPlainJsonObject(value) {
|
|
2837
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2838
|
+
return prototype === Object.prototype || prototype === null;
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2841
|
+
function propertyPath(path, key) {
|
|
2842
|
+
return /^[A-Za-z_$][\w$]*$/.test(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2802
2845
|
function isUnsupportedJsonTransportObject(value, tag = Object.prototype.toString.call(value)) {
|
|
2803
2846
|
return tag === "[object URLSearchParams]"
|
|
2804
2847
|
|| tag === "[object Headers]"
|
|
@@ -5983,101 +6026,25 @@ const __boundaryReceiverModule = (() => {
|
|
|
5983
6026
|
|
|
5984
6027
|
const normalized = validatePatch(patch);
|
|
5985
6028
|
const record = boundaryRecord(normalized.boundary);
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
};
|
|
5993
|
-
record.ignored += 1;
|
|
5994
|
-
record.lastStatus = result.status;
|
|
5995
|
-
remember(result);
|
|
5996
|
-
onIgnore?.(result, patch);
|
|
5997
|
-
return result;
|
|
5998
|
-
}
|
|
5999
|
-
|
|
6000
|
-
if (normalized.parentScope !== undefined && isScopeDestroyed(normalized.parentScope)) {
|
|
6001
|
-
const result = {
|
|
6002
|
-
status: "ignored-destroyed",
|
|
6003
|
-
boundary: normalized.boundary,
|
|
6004
|
-
seq: normalized.seq,
|
|
6005
|
-
parentScope: normalized.parentScope
|
|
6006
|
-
};
|
|
6007
|
-
record.ignored += 1;
|
|
6008
|
-
record.lastStatus = result.status;
|
|
6009
|
-
remember(result);
|
|
6010
|
-
onIgnore?.(result, patch);
|
|
6011
|
-
return result;
|
|
6012
|
-
}
|
|
6013
|
-
|
|
6014
|
-
record.lastSeq = normalized.seq;
|
|
6015
|
-
|
|
6016
|
-
if (Object.hasOwn(normalized, "error")) {
|
|
6017
|
-
const error = toStableError(normalized.error);
|
|
6018
|
-
const result = {
|
|
6019
|
-
status: "errored",
|
|
6020
|
-
boundary: normalized.boundary,
|
|
6021
|
-
seq: normalized.seq,
|
|
6022
|
-
error
|
|
6023
|
-
};
|
|
6024
|
-
record.errored += 1;
|
|
6025
|
-
record.lastStatus = result.status;
|
|
6026
|
-
remember(result);
|
|
6027
|
-
onError?.(error, result, patch);
|
|
6028
|
-
if (throwOnError) {
|
|
6029
|
-
throw error;
|
|
6030
|
-
}
|
|
6031
|
-
return result;
|
|
6032
|
-
}
|
|
6029
|
+
let releasePending;
|
|
6030
|
+
const previousPending = record.pending ?? Promise.resolve();
|
|
6031
|
+
const pending = new Promise((resolve) => {
|
|
6032
|
+
releasePending = resolve;
|
|
6033
|
+
});
|
|
6034
|
+
record.pending = pending;
|
|
6033
6035
|
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
for (const [path, value] of Object.entries(normalized.signals)) {
|
|
6039
|
-
signals.set(path, value);
|
|
6036
|
+
try {
|
|
6037
|
+
await previousPending;
|
|
6038
|
+
if (destroyed) {
|
|
6039
|
+
throw new Error("Boundary receiver has been destroyed.");
|
|
6040
6040
|
}
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
if (
|
|
6045
|
-
|
|
6041
|
+
return await applyBoundaryPatch(record, normalized, patch);
|
|
6042
|
+
} finally {
|
|
6043
|
+
releasePending();
|
|
6044
|
+
if (record.pending === pending) {
|
|
6045
|
+
record.pending = undefined;
|
|
6046
6046
|
}
|
|
6047
|
-
cache.restore(normalized.cache.browser);
|
|
6048
6047
|
}
|
|
6049
|
-
|
|
6050
|
-
if (normalized.html != null) {
|
|
6051
|
-
loader.swap(normalized.boundary, normalized.html);
|
|
6052
|
-
}
|
|
6053
|
-
|
|
6054
|
-
await flushScheduler(scheduler, normalized.scope);
|
|
6055
|
-
|
|
6056
|
-
if (normalized.redirect) {
|
|
6057
|
-
await followRedirect(normalized.redirect, router, loader);
|
|
6058
|
-
const result = {
|
|
6059
|
-
status: "redirected",
|
|
6060
|
-
boundary: normalized.boundary,
|
|
6061
|
-
seq: normalized.seq,
|
|
6062
|
-
redirect: normalized.redirect
|
|
6063
|
-
};
|
|
6064
|
-
record.applied += 1;
|
|
6065
|
-
record.lastStatus = result.status;
|
|
6066
|
-
remember(result);
|
|
6067
|
-
onApply?.(result, patch);
|
|
6068
|
-
return result;
|
|
6069
|
-
}
|
|
6070
|
-
|
|
6071
|
-
const result = {
|
|
6072
|
-
status: "applied",
|
|
6073
|
-
boundary: normalized.boundary,
|
|
6074
|
-
seq: normalized.seq
|
|
6075
|
-
};
|
|
6076
|
-
record.applied += 1;
|
|
6077
|
-
record.lastStatus = result.status;
|
|
6078
|
-
remember(result);
|
|
6079
|
-
onApply?.(result, patch);
|
|
6080
|
-
return result;
|
|
6081
6048
|
},
|
|
6082
6049
|
|
|
6083
6050
|
inspect() {
|
|
@@ -6125,6 +6092,105 @@ const __boundaryReceiverModule = (() => {
|
|
|
6125
6092
|
|
|
6126
6093
|
return receiver;
|
|
6127
6094
|
|
|
6095
|
+
async function applyBoundaryPatch(record, normalized, patch) {
|
|
6096
|
+
if (normalized.seq <= record.lastSeq) {
|
|
6097
|
+
const result = {
|
|
6098
|
+
status: "ignored-stale",
|
|
6099
|
+
boundary: normalized.boundary,
|
|
6100
|
+
seq: normalized.seq,
|
|
6101
|
+
lastSeq: record.lastSeq
|
|
6102
|
+
};
|
|
6103
|
+
record.ignored += 1;
|
|
6104
|
+
record.lastStatus = result.status;
|
|
6105
|
+
remember(result);
|
|
6106
|
+
onIgnore?.(result, patch);
|
|
6107
|
+
return result;
|
|
6108
|
+
}
|
|
6109
|
+
|
|
6110
|
+
if (normalized.parentScope !== undefined && isScopeDestroyed(normalized.parentScope)) {
|
|
6111
|
+
const result = {
|
|
6112
|
+
status: "ignored-destroyed",
|
|
6113
|
+
boundary: normalized.boundary,
|
|
6114
|
+
seq: normalized.seq,
|
|
6115
|
+
parentScope: normalized.parentScope
|
|
6116
|
+
};
|
|
6117
|
+
record.ignored += 1;
|
|
6118
|
+
record.lastStatus = result.status;
|
|
6119
|
+
remember(result);
|
|
6120
|
+
onIgnore?.(result, patch);
|
|
6121
|
+
return result;
|
|
6122
|
+
}
|
|
6123
|
+
|
|
6124
|
+
if (Object.hasOwn(normalized, "error")) {
|
|
6125
|
+
const error = toStableError(normalized.error);
|
|
6126
|
+
const result = {
|
|
6127
|
+
status: "errored",
|
|
6128
|
+
boundary: normalized.boundary,
|
|
6129
|
+
seq: normalized.seq,
|
|
6130
|
+
error
|
|
6131
|
+
};
|
|
6132
|
+
record.lastSeq = normalized.seq;
|
|
6133
|
+
record.errored += 1;
|
|
6134
|
+
record.lastStatus = result.status;
|
|
6135
|
+
remember(result);
|
|
6136
|
+
onError?.(error, result, patch);
|
|
6137
|
+
if (throwOnError) {
|
|
6138
|
+
throw error;
|
|
6139
|
+
}
|
|
6140
|
+
return result;
|
|
6141
|
+
}
|
|
6142
|
+
|
|
6143
|
+
if (normalized.signals) {
|
|
6144
|
+
if (!signals || typeof signals.set !== "function") {
|
|
6145
|
+
throw new Error("Boundary patch includes signals, but no signal registry is available.");
|
|
6146
|
+
}
|
|
6147
|
+
for (const [path, value] of Object.entries(normalized.signals)) {
|
|
6148
|
+
signals.set(path, value);
|
|
6149
|
+
}
|
|
6150
|
+
}
|
|
6151
|
+
|
|
6152
|
+
if (normalized.cache?.browser) {
|
|
6153
|
+
if (!cache || typeof cache.restore !== "function") {
|
|
6154
|
+
throw new Error("Boundary patch includes browser cache, but no cache registry is available.");
|
|
6155
|
+
}
|
|
6156
|
+
cache.restore(normalized.cache.browser);
|
|
6157
|
+
}
|
|
6158
|
+
|
|
6159
|
+
if (normalized.html != null) {
|
|
6160
|
+
loader.swap(normalized.boundary, normalized.html);
|
|
6161
|
+
}
|
|
6162
|
+
|
|
6163
|
+
await flushScheduler(scheduler, normalized.scope);
|
|
6164
|
+
|
|
6165
|
+
if (normalized.redirect) {
|
|
6166
|
+
const result = {
|
|
6167
|
+
status: "redirected",
|
|
6168
|
+
boundary: normalized.boundary,
|
|
6169
|
+
seq: normalized.seq,
|
|
6170
|
+
redirect: normalized.redirect
|
|
6171
|
+
};
|
|
6172
|
+
await followRedirect(normalized.redirect, router, loader);
|
|
6173
|
+
record.applied += 1;
|
|
6174
|
+
record.lastSeq = normalized.seq;
|
|
6175
|
+
record.lastStatus = result.status;
|
|
6176
|
+
remember(result);
|
|
6177
|
+
onApply?.(result, patch);
|
|
6178
|
+
return result;
|
|
6179
|
+
}
|
|
6180
|
+
|
|
6181
|
+
const result = {
|
|
6182
|
+
status: "applied",
|
|
6183
|
+
boundary: normalized.boundary,
|
|
6184
|
+
seq: normalized.seq
|
|
6185
|
+
};
|
|
6186
|
+
record.applied += 1;
|
|
6187
|
+
record.lastSeq = normalized.seq;
|
|
6188
|
+
record.lastStatus = result.status;
|
|
6189
|
+
remember(result);
|
|
6190
|
+
onApply?.(result, patch);
|
|
6191
|
+
return result;
|
|
6192
|
+
}
|
|
6193
|
+
|
|
6128
6194
|
function boundaryRecord(boundary) {
|
|
6129
6195
|
if (!boundaries.has(boundary)) {
|
|
6130
6196
|
boundaries.set(boundary, {
|
|
@@ -6132,7 +6198,8 @@ const __boundaryReceiverModule = (() => {
|
|
|
6132
6198
|
applied: 0,
|
|
6133
6199
|
ignored: 0,
|
|
6134
6200
|
errored: 0,
|
|
6135
|
-
lastStatus: undefined
|
|
6201
|
+
lastStatus: undefined,
|
|
6202
|
+
pending: undefined
|
|
6136
6203
|
});
|
|
6137
6204
|
}
|
|
6138
6205
|
return boundaries.get(boundary);
|