@solidjs/web 2.0.0-beta.21 → 2.0.0-beta.22
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/dist/dev.cjs +27 -1
- package/dist/dev.js +24 -2
- package/dist/server.cjs +19 -1
- package/dist/server.js +16 -2
- package/dist/web.cjs +27 -1
- package/dist/web.js +24 -2
- package/package.json +3 -3
- package/server-functions/dist/client.cjs +33 -5
- package/server-functions/dist/client.js +31 -6
- package/server-functions/dist/server.cjs +35 -8
- package/server-functions/dist/server.js +33 -9
- package/types/client.d.ts +18 -0
- package/types/jsx.d.ts +17 -2
- package/types/response.d.ts +27 -1
- package/types/server-functions/client.d.ts +16 -5
- package/types/server-functions/server.d.ts +9 -5
- package/types/server-functions/shared.d.ts +29 -0
- package/types/server.d.ts +8 -0
- package/types-cjs/client.d.cts +18 -0
- package/types-cjs/jsx.d.cts +17 -2
- package/types-cjs/response.d.cts +27 -1
- package/types-cjs/server-functions/client.d.cts +16 -5
- package/types-cjs/server-functions/server.d.cts +9 -5
- package/types-cjs/server-functions/shared.d.cts +29 -0
- package/types-cjs/server.d.cts +8 -0
package/dist/dev.cjs
CHANGED
|
@@ -282,9 +282,24 @@ function setProperty(node, name, value) {
|
|
|
282
282
|
if (isHydrating(node)) return;
|
|
283
283
|
node[name] = value;
|
|
284
284
|
}
|
|
285
|
+
let claimHandlers = null;
|
|
286
|
+
function registerElementClaim(handler) {
|
|
287
|
+
(claimHandlers || (claimHandlers = [])).push(handler);
|
|
288
|
+
return () => {
|
|
289
|
+
const index = claimHandlers.indexOf(handler);
|
|
290
|
+
index > -1 && claimHandlers.splice(index, 1);
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function claimElement(node) {
|
|
294
|
+
if (claimHandlers !== null) {
|
|
295
|
+
for (let i = 0; i < claimHandlers.length; i++) claimHandlers[i](node);
|
|
296
|
+
}
|
|
297
|
+
return node;
|
|
298
|
+
}
|
|
285
299
|
function setAttribute(node, name, value) {
|
|
286
300
|
if (isHydrating(node)) return;
|
|
287
301
|
if (value == null || value === false) node.removeAttribute(name);else node.setAttribute(name, value === true ? "" : value);
|
|
302
|
+
if (claimHandlers !== null && (name === "href" || name === "action")) claimElement(node);
|
|
288
303
|
}
|
|
289
304
|
function setAttributeNS(node, namespace, name, value) {
|
|
290
305
|
if (isHydrating(node)) return;
|
|
@@ -1130,6 +1145,10 @@ ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
|
1130
1145
|
function isResponseEnvelope(value) {
|
|
1131
1146
|
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1132
1147
|
}
|
|
1148
|
+
const HREF = Symbol.for("solid.Href");
|
|
1149
|
+
function isHref(value) {
|
|
1150
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
1151
|
+
}
|
|
1133
1152
|
function initWithRevalidate(init) {
|
|
1134
1153
|
const {
|
|
1135
1154
|
revalidate,
|
|
@@ -1143,6 +1162,9 @@ function initWithRevalidate(init) {
|
|
|
1143
1162
|
};
|
|
1144
1163
|
}
|
|
1145
1164
|
function redirect(url, init = 302) {
|
|
1165
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
1166
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
1167
|
+
}
|
|
1146
1168
|
const {
|
|
1147
1169
|
responseInit,
|
|
1148
1170
|
headers
|
|
@@ -1152,7 +1174,7 @@ function redirect(url, init = 302) {
|
|
|
1152
1174
|
if (responseInit.status === undefined) {
|
|
1153
1175
|
responseInit.status = 302;
|
|
1154
1176
|
}
|
|
1155
|
-
headers.set("Location", url);
|
|
1177
|
+
headers.set("Location", String(url));
|
|
1156
1178
|
return new Response(null, {
|
|
1157
1179
|
...responseInit,
|
|
1158
1180
|
headers
|
|
@@ -1341,6 +1363,7 @@ exports.DOMElements = DOMElements;
|
|
|
1341
1363
|
exports.DOMWithState = DOMWithState;
|
|
1342
1364
|
exports.DelegatedEvents = DelegatedEvents;
|
|
1343
1365
|
exports.Dynamic = Dynamic;
|
|
1366
|
+
exports.HREF = HREF;
|
|
1344
1367
|
exports.HydrationScript = voidFn;
|
|
1345
1368
|
exports.MathMLElements = MathMLElements;
|
|
1346
1369
|
exports.Namespaces = Namespaces;
|
|
@@ -1354,6 +1377,7 @@ exports.acquireAsset = acquireAsset;
|
|
|
1354
1377
|
exports.addEvent = addEvent;
|
|
1355
1378
|
exports.applyRef = applyRef;
|
|
1356
1379
|
exports.assign = assign;
|
|
1380
|
+
exports.claimElement = claimElement;
|
|
1357
1381
|
exports.className = className;
|
|
1358
1382
|
exports.delegateEvents = delegateEvents;
|
|
1359
1383
|
exports.dynamic = dynamic;
|
|
@@ -1374,6 +1398,7 @@ exports.hydrate = hydrate;
|
|
|
1374
1398
|
exports.insert = insert;
|
|
1375
1399
|
exports.installHydrationRuntime = installHydrationRuntime;
|
|
1376
1400
|
exports.isDev = isDev;
|
|
1401
|
+
exports.isHref = isHref;
|
|
1377
1402
|
exports.isResponseEnvelope = isResponseEnvelope;
|
|
1378
1403
|
exports.isServer = isServer;
|
|
1379
1404
|
exports.memo = memo;
|
|
@@ -1382,6 +1407,7 @@ exports.redirect = redirect;
|
|
|
1382
1407
|
exports.ref = ref;
|
|
1383
1408
|
exports.registerDelegatedContainer = registerDelegatedContainer;
|
|
1384
1409
|
exports.registerDelegatedRoot = registerDelegatedRoot;
|
|
1410
|
+
exports.registerElementClaim = registerElementClaim;
|
|
1385
1411
|
exports.reload = reload;
|
|
1386
1412
|
exports.render = render;
|
|
1387
1413
|
exports.renderToStream = renderToStream;
|
package/dist/dev.js
CHANGED
|
@@ -281,9 +281,24 @@ function setProperty(node, name, value) {
|
|
|
281
281
|
if (isHydrating(node)) return;
|
|
282
282
|
node[name] = value;
|
|
283
283
|
}
|
|
284
|
+
let claimHandlers = null;
|
|
285
|
+
function registerElementClaim(handler) {
|
|
286
|
+
(claimHandlers || (claimHandlers = [])).push(handler);
|
|
287
|
+
return () => {
|
|
288
|
+
const index = claimHandlers.indexOf(handler);
|
|
289
|
+
index > -1 && claimHandlers.splice(index, 1);
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function claimElement(node) {
|
|
293
|
+
if (claimHandlers !== null) {
|
|
294
|
+
for (let i = 0; i < claimHandlers.length; i++) claimHandlers[i](node);
|
|
295
|
+
}
|
|
296
|
+
return node;
|
|
297
|
+
}
|
|
284
298
|
function setAttribute(node, name, value) {
|
|
285
299
|
if (isHydrating(node)) return;
|
|
286
300
|
if (value == null || value === false) node.removeAttribute(name);else node.setAttribute(name, value === true ? "" : value);
|
|
301
|
+
if (claimHandlers !== null && (name === "href" || name === "action")) claimElement(node);
|
|
287
302
|
}
|
|
288
303
|
function setAttributeNS(node, namespace, name, value) {
|
|
289
304
|
if (isHydrating(node)) return;
|
|
@@ -1129,6 +1144,10 @@ ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
|
1129
1144
|
function isResponseEnvelope(value) {
|
|
1130
1145
|
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1131
1146
|
}
|
|
1147
|
+
const HREF = Symbol.for("solid.Href");
|
|
1148
|
+
function isHref(value) {
|
|
1149
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
1150
|
+
}
|
|
1132
1151
|
function initWithRevalidate(init) {
|
|
1133
1152
|
const {
|
|
1134
1153
|
revalidate,
|
|
@@ -1142,6 +1161,9 @@ function initWithRevalidate(init) {
|
|
|
1142
1161
|
};
|
|
1143
1162
|
}
|
|
1144
1163
|
function redirect(url, init = 302) {
|
|
1164
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
1165
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
1166
|
+
}
|
|
1145
1167
|
const {
|
|
1146
1168
|
responseInit,
|
|
1147
1169
|
headers
|
|
@@ -1151,7 +1173,7 @@ function redirect(url, init = 302) {
|
|
|
1151
1173
|
if (responseInit.status === undefined) {
|
|
1152
1174
|
responseInit.status = 302;
|
|
1153
1175
|
}
|
|
1154
|
-
headers.set("Location", url);
|
|
1176
|
+
headers.set("Location", String(url));
|
|
1155
1177
|
return new Response(null, {
|
|
1156
1178
|
...responseInit,
|
|
1157
1179
|
headers
|
|
@@ -1282,4 +1304,4 @@ function createElement(tagName, is = undefined) {
|
|
|
1282
1304
|
});
|
|
1283
1305
|
}
|
|
1284
1306
|
|
|
1285
|
-
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, installHydrationRuntime, isDev, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
|
|
1307
|
+
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
|
package/dist/server.cjs
CHANGED
|
@@ -1272,6 +1272,13 @@ function getRequestEvent() {
|
|
|
1272
1272
|
function renderToStringAsync(code, options = {}) {
|
|
1273
1273
|
return new Promise(resolve => renderToStream(code, options).then(resolve));
|
|
1274
1274
|
}
|
|
1275
|
+
function registerElementClaim() {
|
|
1276
|
+
return noopCleanup;
|
|
1277
|
+
}
|
|
1278
|
+
function noopCleanup() {}
|
|
1279
|
+
function claimElement(node) {
|
|
1280
|
+
return node;
|
|
1281
|
+
}
|
|
1275
1282
|
function notSup() {
|
|
1276
1283
|
throw new Error("Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>.");
|
|
1277
1284
|
}
|
|
@@ -1287,6 +1294,10 @@ ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
|
1287
1294
|
function isResponseEnvelope(value) {
|
|
1288
1295
|
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1289
1296
|
}
|
|
1297
|
+
const HREF = Symbol.for("solid.Href");
|
|
1298
|
+
function isHref(value) {
|
|
1299
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
1300
|
+
}
|
|
1290
1301
|
function initWithRevalidate(init) {
|
|
1291
1302
|
const {
|
|
1292
1303
|
revalidate,
|
|
@@ -1300,6 +1311,9 @@ function initWithRevalidate(init) {
|
|
|
1300
1311
|
};
|
|
1301
1312
|
}
|
|
1302
1313
|
function redirect(url, init = 302) {
|
|
1314
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
1315
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
1316
|
+
}
|
|
1303
1317
|
const {
|
|
1304
1318
|
responseInit,
|
|
1305
1319
|
headers
|
|
@@ -1309,7 +1323,7 @@ function redirect(url, init = 302) {
|
|
|
1309
1323
|
if (responseInit.status === undefined) {
|
|
1310
1324
|
responseInit.status = 302;
|
|
1311
1325
|
}
|
|
1312
|
-
headers.set("Location", url);
|
|
1326
|
+
headers.set("Location", String(url));
|
|
1313
1327
|
return new Response(null, {
|
|
1314
1328
|
...responseInit,
|
|
1315
1329
|
headers
|
|
@@ -1454,6 +1468,7 @@ exports.DOMElements = DOMElements;
|
|
|
1454
1468
|
exports.DOMWithState = DOMWithState;
|
|
1455
1469
|
exports.DelegatedEvents = DelegatedEvents;
|
|
1456
1470
|
exports.Dynamic = Dynamic;
|
|
1471
|
+
exports.HREF = HREF;
|
|
1457
1472
|
exports.HydrationScript = HydrationScript;
|
|
1458
1473
|
exports.MathMLElements = MathMLElements;
|
|
1459
1474
|
exports.Namespaces = Namespaces;
|
|
@@ -1467,6 +1482,7 @@ exports.acquireAsset = notSup;
|
|
|
1467
1482
|
exports.addEvent = notSup;
|
|
1468
1483
|
exports.applyRef = applyRef;
|
|
1469
1484
|
exports.assign = notSup;
|
|
1485
|
+
exports.claimElement = claimElement;
|
|
1470
1486
|
exports.className = notSup;
|
|
1471
1487
|
exports.delegateEvents = notSup;
|
|
1472
1488
|
exports.dynamic = dynamic;
|
|
@@ -1484,6 +1500,7 @@ exports.getRequestEvent = getRequestEvent;
|
|
|
1484
1500
|
exports.hydrate = notSup;
|
|
1485
1501
|
exports.insert = notSup;
|
|
1486
1502
|
exports.isDev = isDev;
|
|
1503
|
+
exports.isHref = isHref;
|
|
1487
1504
|
exports.isResponseEnvelope = isResponseEnvelope;
|
|
1488
1505
|
exports.isServer = isServer;
|
|
1489
1506
|
exports.memo = memo;
|
|
@@ -1491,6 +1508,7 @@ exports.redirect = redirect;
|
|
|
1491
1508
|
exports.ref = notSup;
|
|
1492
1509
|
exports.registerDelegatedContainer = notSup;
|
|
1493
1510
|
exports.registerDelegatedRoot = notSup;
|
|
1511
|
+
exports.registerElementClaim = registerElementClaim;
|
|
1494
1512
|
exports.reload = reload;
|
|
1495
1513
|
exports.render = notSup;
|
|
1496
1514
|
exports.renderToStream = renderToStream;
|
package/dist/server.js
CHANGED
|
@@ -1271,6 +1271,13 @@ function getRequestEvent() {
|
|
|
1271
1271
|
function renderToStringAsync(code, options = {}) {
|
|
1272
1272
|
return new Promise(resolve => renderToStream(code, options).then(resolve));
|
|
1273
1273
|
}
|
|
1274
|
+
function registerElementClaim() {
|
|
1275
|
+
return noopCleanup;
|
|
1276
|
+
}
|
|
1277
|
+
function noopCleanup() {}
|
|
1278
|
+
function claimElement(node) {
|
|
1279
|
+
return node;
|
|
1280
|
+
}
|
|
1274
1281
|
function notSup() {
|
|
1275
1282
|
throw new Error("Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>.");
|
|
1276
1283
|
}
|
|
@@ -1286,6 +1293,10 @@ ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
|
1286
1293
|
function isResponseEnvelope(value) {
|
|
1287
1294
|
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1288
1295
|
}
|
|
1296
|
+
const HREF = Symbol.for("solid.Href");
|
|
1297
|
+
function isHref(value) {
|
|
1298
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
1299
|
+
}
|
|
1289
1300
|
function initWithRevalidate(init) {
|
|
1290
1301
|
const {
|
|
1291
1302
|
revalidate,
|
|
@@ -1299,6 +1310,9 @@ function initWithRevalidate(init) {
|
|
|
1299
1310
|
};
|
|
1300
1311
|
}
|
|
1301
1312
|
function redirect(url, init = 302) {
|
|
1313
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
1314
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
1315
|
+
}
|
|
1302
1316
|
const {
|
|
1303
1317
|
responseInit,
|
|
1304
1318
|
headers
|
|
@@ -1308,7 +1322,7 @@ function redirect(url, init = 302) {
|
|
|
1308
1322
|
if (responseInit.status === undefined) {
|
|
1309
1323
|
responseInit.status = 302;
|
|
1310
1324
|
}
|
|
1311
|
-
headers.set("Location", url);
|
|
1325
|
+
headers.set("Location", String(url));
|
|
1312
1326
|
return new Response(null, {
|
|
1313
1327
|
...responseInit,
|
|
1314
1328
|
headers
|
|
@@ -1387,4 +1401,4 @@ function Portal(props) {
|
|
|
1387
1401
|
return undefined;
|
|
1388
1402
|
}
|
|
1389
1403
|
|
|
1390
|
-
export { Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, notSup as className, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, getAssets, notSup as getDelegatedRoot, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, notSup as hydrate, notSup as insert, isDev, isResponseEnvelope, isServer, memo, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, reload, notSup as render, renderToStream, renderToString, renderToStringAsync, respond, notSup as runHydrationEvents, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useAssets };
|
|
1404
|
+
export { Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, notSup as acquireAsset, notSup as addEvent, applyRef, notSup as assign, claimElement, notSup as className, notSup as delegateEvents, dynamic, notSup as dynamicProperty, effect, escape, generateHydrationScript, getAssets, notSup as getDelegatedRoot, getHydrationKey, notSup as getNextElement, notSup as getNextMarker, notSup as getNextMatch, getRequestEvent, notSup as hydrate, notSup as insert, isDev, isHref, isResponseEnvelope, isServer, memo, redirect, notSup as ref, notSup as registerDelegatedContainer, notSup as registerDelegatedRoot, registerElementClaim, reload, notSup as render, renderToStream, renderToString, renderToStringAsync, respond, notSup as runHydrationEvents, notSup as setAttribute, notSup as setAttributeNS, notSup as setProperty, notSup as setStyleProperty, notSup as spread, ssr, ssrAttribute, ssrClassName, ssrElement, ssrGroup, ssrHydrationKey, ssrStyle, ssrStyleProperty, notSup as style, notSup as template, notSup as unregisterDelegatedContainer, notSup as unregisterDelegatedRoot, useAssets };
|
package/dist/web.cjs
CHANGED
|
@@ -277,9 +277,24 @@ function setProperty(node, name, value) {
|
|
|
277
277
|
if (isHydrating(node)) return;
|
|
278
278
|
node[name] = value;
|
|
279
279
|
}
|
|
280
|
+
let claimHandlers = null;
|
|
281
|
+
function registerElementClaim(handler) {
|
|
282
|
+
(claimHandlers || (claimHandlers = [])).push(handler);
|
|
283
|
+
return () => {
|
|
284
|
+
const index = claimHandlers.indexOf(handler);
|
|
285
|
+
index > -1 && claimHandlers.splice(index, 1);
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function claimElement(node) {
|
|
289
|
+
if (claimHandlers !== null) {
|
|
290
|
+
for (let i = 0; i < claimHandlers.length; i++) claimHandlers[i](node);
|
|
291
|
+
}
|
|
292
|
+
return node;
|
|
293
|
+
}
|
|
280
294
|
function setAttribute(node, name, value) {
|
|
281
295
|
if (isHydrating(node)) return;
|
|
282
296
|
if (value == null || value === false) node.removeAttribute(name);else node.setAttribute(name, value === true ? "" : value);
|
|
297
|
+
if (claimHandlers !== null && (name === "href" || name === "action")) claimElement(node);
|
|
283
298
|
}
|
|
284
299
|
function setAttributeNS(node, namespace, name, value) {
|
|
285
300
|
if (isHydrating(node)) return;
|
|
@@ -1073,6 +1088,10 @@ ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
|
1073
1088
|
function isResponseEnvelope(value) {
|
|
1074
1089
|
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1075
1090
|
}
|
|
1091
|
+
const HREF = Symbol.for("solid.Href");
|
|
1092
|
+
function isHref(value) {
|
|
1093
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
1094
|
+
}
|
|
1076
1095
|
function initWithRevalidate(init) {
|
|
1077
1096
|
const {
|
|
1078
1097
|
revalidate,
|
|
@@ -1086,6 +1105,9 @@ function initWithRevalidate(init) {
|
|
|
1086
1105
|
};
|
|
1087
1106
|
}
|
|
1088
1107
|
function redirect(url, init = 302) {
|
|
1108
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
1109
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
1110
|
+
}
|
|
1089
1111
|
const {
|
|
1090
1112
|
responseInit,
|
|
1091
1113
|
headers
|
|
@@ -1095,7 +1117,7 @@ function redirect(url, init = 302) {
|
|
|
1095
1117
|
if (responseInit.status === undefined) {
|
|
1096
1118
|
responseInit.status = 302;
|
|
1097
1119
|
}
|
|
1098
|
-
headers.set("Location", url);
|
|
1120
|
+
headers.set("Location", String(url));
|
|
1099
1121
|
return new Response(null, {
|
|
1100
1122
|
...responseInit,
|
|
1101
1123
|
headers
|
|
@@ -1279,6 +1301,7 @@ exports.DOMElements = DOMElements;
|
|
|
1279
1301
|
exports.DOMWithState = DOMWithState;
|
|
1280
1302
|
exports.DelegatedEvents = DelegatedEvents;
|
|
1281
1303
|
exports.Dynamic = Dynamic;
|
|
1304
|
+
exports.HREF = HREF;
|
|
1282
1305
|
exports.HydrationScript = voidFn;
|
|
1283
1306
|
exports.MathMLElements = MathMLElements;
|
|
1284
1307
|
exports.Namespaces = Namespaces;
|
|
@@ -1292,6 +1315,7 @@ exports.acquireAsset = acquireAsset;
|
|
|
1292
1315
|
exports.addEvent = addEvent;
|
|
1293
1316
|
exports.applyRef = applyRef;
|
|
1294
1317
|
exports.assign = assign;
|
|
1318
|
+
exports.claimElement = claimElement;
|
|
1295
1319
|
exports.className = className;
|
|
1296
1320
|
exports.delegateEvents = delegateEvents;
|
|
1297
1321
|
exports.dynamic = dynamic;
|
|
@@ -1312,6 +1336,7 @@ exports.hydrate = hydrate;
|
|
|
1312
1336
|
exports.insert = insert;
|
|
1313
1337
|
exports.installHydrationRuntime = installHydrationRuntime;
|
|
1314
1338
|
exports.isDev = isDev;
|
|
1339
|
+
exports.isHref = isHref;
|
|
1315
1340
|
exports.isResponseEnvelope = isResponseEnvelope;
|
|
1316
1341
|
exports.isServer = isServer;
|
|
1317
1342
|
exports.memo = memo;
|
|
@@ -1320,6 +1345,7 @@ exports.redirect = redirect;
|
|
|
1320
1345
|
exports.ref = ref;
|
|
1321
1346
|
exports.registerDelegatedContainer = registerDelegatedContainer;
|
|
1322
1347
|
exports.registerDelegatedRoot = registerDelegatedRoot;
|
|
1348
|
+
exports.registerElementClaim = registerElementClaim;
|
|
1323
1349
|
exports.reload = reload;
|
|
1324
1350
|
exports.render = render;
|
|
1325
1351
|
exports.renderToStream = renderToStream;
|
package/dist/web.js
CHANGED
|
@@ -276,9 +276,24 @@ function setProperty(node, name, value) {
|
|
|
276
276
|
if (isHydrating(node)) return;
|
|
277
277
|
node[name] = value;
|
|
278
278
|
}
|
|
279
|
+
let claimHandlers = null;
|
|
280
|
+
function registerElementClaim(handler) {
|
|
281
|
+
(claimHandlers || (claimHandlers = [])).push(handler);
|
|
282
|
+
return () => {
|
|
283
|
+
const index = claimHandlers.indexOf(handler);
|
|
284
|
+
index > -1 && claimHandlers.splice(index, 1);
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function claimElement(node) {
|
|
288
|
+
if (claimHandlers !== null) {
|
|
289
|
+
for (let i = 0; i < claimHandlers.length; i++) claimHandlers[i](node);
|
|
290
|
+
}
|
|
291
|
+
return node;
|
|
292
|
+
}
|
|
279
293
|
function setAttribute(node, name, value) {
|
|
280
294
|
if (isHydrating(node)) return;
|
|
281
295
|
if (value == null || value === false) node.removeAttribute(name);else node.setAttribute(name, value === true ? "" : value);
|
|
296
|
+
if (claimHandlers !== null && (name === "href" || name === "action")) claimElement(node);
|
|
282
297
|
}
|
|
283
298
|
function setAttributeNS(node, namespace, name, value) {
|
|
284
299
|
if (isHydrating(node)) return;
|
|
@@ -1072,6 +1087,10 @@ ResponseEnvelope.prototype[ENVELOPE] = true;
|
|
|
1072
1087
|
function isResponseEnvelope(value) {
|
|
1073
1088
|
return !!(value && typeof value === "object" && value[ENVELOPE]);
|
|
1074
1089
|
}
|
|
1090
|
+
const HREF = Symbol.for("solid.Href");
|
|
1091
|
+
function isHref(value) {
|
|
1092
|
+
return !!(value && (typeof value === "object" || typeof value === "function") && value[HREF]);
|
|
1093
|
+
}
|
|
1075
1094
|
function initWithRevalidate(init) {
|
|
1076
1095
|
const {
|
|
1077
1096
|
revalidate,
|
|
@@ -1085,6 +1104,9 @@ function initWithRevalidate(init) {
|
|
|
1085
1104
|
};
|
|
1086
1105
|
}
|
|
1087
1106
|
function redirect(url, init = 302) {
|
|
1107
|
+
if (typeof url !== "string" && !isHref(url)) {
|
|
1108
|
+
throw new TypeError("redirect() expects a string URL or an Href-branded value (Symbol.for('solid.Href')).");
|
|
1109
|
+
}
|
|
1088
1110
|
const {
|
|
1089
1111
|
responseInit,
|
|
1090
1112
|
headers
|
|
@@ -1094,7 +1116,7 @@ function redirect(url, init = 302) {
|
|
|
1094
1116
|
if (responseInit.status === undefined) {
|
|
1095
1117
|
responseInit.status = 302;
|
|
1096
1118
|
}
|
|
1097
|
-
headers.set("Location", url);
|
|
1119
|
+
headers.set("Location", String(url));
|
|
1098
1120
|
return new Response(null, {
|
|
1099
1121
|
...responseInit,
|
|
1100
1122
|
headers
|
|
@@ -1220,4 +1242,4 @@ function createElement(tagName, is = undefined) {
|
|
|
1220
1242
|
});
|
|
1221
1243
|
}
|
|
1222
1244
|
|
|
1223
|
-
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, installHydrationRuntime, isDev, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
|
|
1245
|
+
export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/web",
|
|
3
3
|
"description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.22",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://solidjs.com",
|
|
@@ -224,10 +224,10 @@
|
|
|
224
224
|
"seroval-plugins": "~1.5.4"
|
|
225
225
|
},
|
|
226
226
|
"peerDependencies": {
|
|
227
|
-
"solid-js": "^2.0.0-beta.
|
|
227
|
+
"solid-js": "^2.0.0-beta.22"
|
|
228
228
|
},
|
|
229
229
|
"devDependencies": {
|
|
230
|
-
"solid-js": "2.0.0-beta.
|
|
230
|
+
"solid-js": "2.0.0-beta.22"
|
|
231
231
|
},
|
|
232
232
|
"scripts": {
|
|
233
233
|
"build": "npm-run-all -nl build:clean types:copy-jsx build:js",
|
|
@@ -85,6 +85,31 @@ function withMeta(fn, meta) {
|
|
|
85
85
|
return fn;
|
|
86
86
|
}
|
|
87
87
|
const FUNCTION_HEADER = "X-Server-Function-Id";
|
|
88
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
89
|
+
const ERROR_HEADER_MARKER = "=?1?";
|
|
90
|
+
const NEEDS_ENCODING = /[^\x20-\x7e\xa0-\xff]/;
|
|
91
|
+
function encodeErrorHeaderValue(value) {
|
|
92
|
+
let stripped = String(value).replace(/[\r\n]+/g, "");
|
|
93
|
+
if (!NEEDS_ENCODING.test(stripped) && !stripped.startsWith(ERROR_HEADER_MARKER) && stripped === stripped.trim()) {
|
|
94
|
+
return stripped;
|
|
95
|
+
}
|
|
96
|
+
if (typeof stripped.toWellFormed === "function") {
|
|
97
|
+
stripped = stripped.toWellFormed();
|
|
98
|
+
} else {
|
|
99
|
+
stripped = stripped.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
|
|
100
|
+
}
|
|
101
|
+
return ERROR_HEADER_MARKER + encodeURIComponent(stripped);
|
|
102
|
+
}
|
|
103
|
+
function decodeErrorHeaderValue(value) {
|
|
104
|
+
if (typeof value !== "string" || !value.startsWith(ERROR_HEADER_MARKER)) {
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
return decodeURIComponent(value.slice(ERROR_HEADER_MARKER.length));
|
|
109
|
+
} catch {
|
|
110
|
+
return value;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
88
113
|
const INSTANCE_HEADER = "X-Server-Function-Instance";
|
|
89
114
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
90
115
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
@@ -372,7 +397,7 @@ async function fetchServerFunction(base, id, options, args, meta) {
|
|
|
372
397
|
await consumer(payload.data, {
|
|
373
398
|
response
|
|
374
399
|
});
|
|
375
|
-
if (response.headers.has(
|
|
400
|
+
if (response.headers.has(ERROR_HEADER) && !response.headers.has("Location") && !response.headers.has("X-Revalidate")) {
|
|
376
401
|
throw payload.value;
|
|
377
402
|
}
|
|
378
403
|
return payload.value;
|
|
@@ -382,22 +407,22 @@ async function fetchServerFunction(base, id, options, args, meta) {
|
|
|
382
407
|
return response;
|
|
383
408
|
}
|
|
384
409
|
const result = await decodeResponse(response.clone());
|
|
385
|
-
if (response.headers.has(
|
|
410
|
+
if (response.headers.has(ERROR_HEADER)) {
|
|
386
411
|
throw result;
|
|
387
412
|
}
|
|
388
413
|
return result;
|
|
389
414
|
}
|
|
390
|
-
function createServerReference(id, name) {
|
|
415
|
+
function createServerReference(id, name, base) {
|
|
391
416
|
const metadata = name === undefined ? {} : {
|
|
392
417
|
name
|
|
393
418
|
};
|
|
394
|
-
const fn = (...args) => fetchServerFunction(config.endpoint, id, {}, args, metadata);
|
|
419
|
+
const fn = (...args) => fetchServerFunction(base || config.endpoint, id, {}, args, metadata);
|
|
395
420
|
fn[SERVER_FUNCTION_METADATA] = metadata;
|
|
396
421
|
return new Proxy(fn, {
|
|
397
422
|
get(target, prop) {
|
|
398
423
|
if (prop === "id") return id;
|
|
399
424
|
if (prop === "url") {
|
|
400
|
-
return `${config.endpoint}?id=${encodeURIComponent(id)}`;
|
|
425
|
+
return base || `${config.endpoint}?id=${encodeURIComponent(id)}`;
|
|
401
426
|
}
|
|
402
427
|
return target[prop];
|
|
403
428
|
}
|
|
@@ -434,13 +459,16 @@ function registerServerReference() {
|
|
|
434
459
|
throw new Error("registerServerReference must not be called in the client build");
|
|
435
460
|
}
|
|
436
461
|
|
|
462
|
+
exports.ERROR_HEADER = ERROR_HEADER;
|
|
437
463
|
exports.FUNCTION_HEADER = FUNCTION_HEADER;
|
|
438
464
|
exports.GET = GET;
|
|
439
465
|
exports.INSTANCE_HEADER = INSTANCE_HEADER;
|
|
440
466
|
exports.SINGLE_FLIGHT_HEADER = SINGLE_FLIGHT_HEADER;
|
|
441
467
|
exports.configureServerFunctionsClient = configureServerFunctionsClient;
|
|
442
468
|
exports.createServerReference = createServerReference;
|
|
469
|
+
exports.decodeErrorHeaderValue = decodeErrorHeaderValue;
|
|
443
470
|
exports.decodeResponse = decodeResponse;
|
|
471
|
+
exports.encodeErrorHeaderValue = encodeErrorHeaderValue;
|
|
444
472
|
exports.getServerFunctionMetadata = getServerFunctionMetadata;
|
|
445
473
|
exports.isServerFunction = isServerFunction;
|
|
446
474
|
exports.registerServerReference = registerServerReference;
|
|
@@ -83,6 +83,31 @@ function withMeta(fn, meta) {
|
|
|
83
83
|
return fn;
|
|
84
84
|
}
|
|
85
85
|
const FUNCTION_HEADER = "X-Server-Function-Id";
|
|
86
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
87
|
+
const ERROR_HEADER_MARKER = "=?1?";
|
|
88
|
+
const NEEDS_ENCODING = /[^\x20-\x7e\xa0-\xff]/;
|
|
89
|
+
function encodeErrorHeaderValue(value) {
|
|
90
|
+
let stripped = String(value).replace(/[\r\n]+/g, "");
|
|
91
|
+
if (!NEEDS_ENCODING.test(stripped) && !stripped.startsWith(ERROR_HEADER_MARKER) && stripped === stripped.trim()) {
|
|
92
|
+
return stripped;
|
|
93
|
+
}
|
|
94
|
+
if (typeof stripped.toWellFormed === "function") {
|
|
95
|
+
stripped = stripped.toWellFormed();
|
|
96
|
+
} else {
|
|
97
|
+
stripped = stripped.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
|
|
98
|
+
}
|
|
99
|
+
return ERROR_HEADER_MARKER + encodeURIComponent(stripped);
|
|
100
|
+
}
|
|
101
|
+
function decodeErrorHeaderValue(value) {
|
|
102
|
+
if (typeof value !== "string" || !value.startsWith(ERROR_HEADER_MARKER)) {
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
return decodeURIComponent(value.slice(ERROR_HEADER_MARKER.length));
|
|
107
|
+
} catch {
|
|
108
|
+
return value;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
86
111
|
const INSTANCE_HEADER = "X-Server-Function-Instance";
|
|
87
112
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
88
113
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
@@ -370,7 +395,7 @@ async function fetchServerFunction(base, id, options, args, meta) {
|
|
|
370
395
|
await consumer(payload.data, {
|
|
371
396
|
response
|
|
372
397
|
});
|
|
373
|
-
if (response.headers.has(
|
|
398
|
+
if (response.headers.has(ERROR_HEADER) && !response.headers.has("Location") && !response.headers.has("X-Revalidate")) {
|
|
374
399
|
throw payload.value;
|
|
375
400
|
}
|
|
376
401
|
return payload.value;
|
|
@@ -380,22 +405,22 @@ async function fetchServerFunction(base, id, options, args, meta) {
|
|
|
380
405
|
return response;
|
|
381
406
|
}
|
|
382
407
|
const result = await decodeResponse(response.clone());
|
|
383
|
-
if (response.headers.has(
|
|
408
|
+
if (response.headers.has(ERROR_HEADER)) {
|
|
384
409
|
throw result;
|
|
385
410
|
}
|
|
386
411
|
return result;
|
|
387
412
|
}
|
|
388
|
-
function createServerReference(id, name) {
|
|
413
|
+
function createServerReference(id, name, base) {
|
|
389
414
|
const metadata = name === undefined ? {} : {
|
|
390
415
|
name
|
|
391
416
|
};
|
|
392
|
-
const fn = (...args) => fetchServerFunction(config.endpoint, id, {}, args, metadata);
|
|
417
|
+
const fn = (...args) => fetchServerFunction(base || config.endpoint, id, {}, args, metadata);
|
|
393
418
|
fn[SERVER_FUNCTION_METADATA] = metadata;
|
|
394
419
|
return new Proxy(fn, {
|
|
395
420
|
get(target, prop) {
|
|
396
421
|
if (prop === "id") return id;
|
|
397
422
|
if (prop === "url") {
|
|
398
|
-
return `${config.endpoint}?id=${encodeURIComponent(id)}`;
|
|
423
|
+
return base || `${config.endpoint}?id=${encodeURIComponent(id)}`;
|
|
399
424
|
}
|
|
400
425
|
return target[prop];
|
|
401
426
|
}
|
|
@@ -432,4 +457,4 @@ function registerServerReference() {
|
|
|
432
457
|
throw new Error("registerServerReference must not be called in the client build");
|
|
433
458
|
}
|
|
434
459
|
|
|
435
|
-
export { FUNCTION_HEADER, GET, INSTANCE_HEADER, SINGLE_FLIGHT_HEADER, configureServerFunctionsClient, createServerReference, decodeResponse, getServerFunctionMetadata, isServerFunction, registerServerReference, subscribeFlightData, withMeta };
|
|
460
|
+
export { ERROR_HEADER, FUNCTION_HEADER, GET, INSTANCE_HEADER, SINGLE_FLIGHT_HEADER, configureServerFunctionsClient, createServerReference, decodeErrorHeaderValue, decodeResponse, encodeErrorHeaderValue, getServerFunctionMetadata, isServerFunction, registerServerReference, subscribeFlightData, withMeta };
|
|
@@ -88,6 +88,31 @@ function withMeta(fn, meta) {
|
|
|
88
88
|
return fn;
|
|
89
89
|
}
|
|
90
90
|
const FUNCTION_HEADER = "X-Server-Function-Id";
|
|
91
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
92
|
+
const ERROR_HEADER_MARKER = "=?1?";
|
|
93
|
+
const NEEDS_ENCODING = /[^\x20-\x7e\xa0-\xff]/;
|
|
94
|
+
function encodeErrorHeaderValue(value) {
|
|
95
|
+
let stripped = String(value).replace(/[\r\n]+/g, "");
|
|
96
|
+
if (!NEEDS_ENCODING.test(stripped) && !stripped.startsWith(ERROR_HEADER_MARKER) && stripped === stripped.trim()) {
|
|
97
|
+
return stripped;
|
|
98
|
+
}
|
|
99
|
+
if (typeof stripped.toWellFormed === "function") {
|
|
100
|
+
stripped = stripped.toWellFormed();
|
|
101
|
+
} else {
|
|
102
|
+
stripped = stripped.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
|
|
103
|
+
}
|
|
104
|
+
return ERROR_HEADER_MARKER + encodeURIComponent(stripped);
|
|
105
|
+
}
|
|
106
|
+
function decodeErrorHeaderValue(value) {
|
|
107
|
+
if (typeof value !== "string" || !value.startsWith(ERROR_HEADER_MARKER)) {
|
|
108
|
+
return value;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
return decodeURIComponent(value.slice(ERROR_HEADER_MARKER.length));
|
|
112
|
+
} catch {
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
91
116
|
const INSTANCE_HEADER = "X-Server-Function-Instance";
|
|
92
117
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
93
118
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
@@ -400,7 +425,8 @@ function resolveFunctionId(request, url) {
|
|
|
400
425
|
}
|
|
401
426
|
async function parseArguments(request, url, instance, codec) {
|
|
402
427
|
const parsed = [];
|
|
403
|
-
|
|
428
|
+
const bodyFormat = request.method === "POST" ? request.headers.get(BODY_FORMAT_HEADER) : null;
|
|
429
|
+
if (!instance || request.method === "GET" || bodyFormat !== BodyFormat.Serialized) {
|
|
404
430
|
const args = url.searchParams.get("args");
|
|
405
431
|
if (args) {
|
|
406
432
|
const result = args.startsWith(";0x") ? await deserializeString(args, codec) : JSON.parse(args);
|
|
@@ -410,9 +436,8 @@ async function parseArguments(request, url, instance, codec) {
|
|
|
410
436
|
}
|
|
411
437
|
}
|
|
412
438
|
if (request.method === "POST" && request.body !== null) {
|
|
413
|
-
const format = request.headers.get(BODY_FORMAT_HEADER);
|
|
414
439
|
const decoded = await extractBody(request.clone(), codec);
|
|
415
|
-
if (
|
|
440
|
+
if (bodyFormat === BodyFormat.Serialized) {
|
|
416
441
|
return decoded;
|
|
417
442
|
}
|
|
418
443
|
parsed.push(decoded);
|
|
@@ -470,12 +495,11 @@ async function handleServerFunctionRequest(request, options = {}) {
|
|
|
470
495
|
status: 404
|
|
471
496
|
});
|
|
472
497
|
}
|
|
473
|
-
|
|
474
|
-
if (request.method === "GET" !== (allowedMethod === "GET")) {
|
|
498
|
+
if (request.method === "GET" && METHODS.get(functionId) !== "GET") {
|
|
475
499
|
return new Response(process.env.NODE_ENV === "development" ? `Method not allowed for server function: ${functionId}` : null, {
|
|
476
500
|
status: 405,
|
|
477
501
|
headers: {
|
|
478
|
-
Allow:
|
|
502
|
+
Allow: "POST"
|
|
479
503
|
}
|
|
480
504
|
});
|
|
481
505
|
}
|
|
@@ -594,7 +618,7 @@ async function handleServerFunctionRequest(request, options = {}) {
|
|
|
594
618
|
thrown: true
|
|
595
619
|
});
|
|
596
620
|
}
|
|
597
|
-
headers.set(
|
|
621
|
+
headers.set(ERROR_HEADER, "true");
|
|
598
622
|
if (!instance) {
|
|
599
623
|
if (options.handleNoJS) return options.handleNoJS(x, request, parsed, true);
|
|
600
624
|
if (x instanceof Response) return x;
|
|
@@ -609,18 +633,21 @@ async function handleServerFunctionRequest(request, options = {}) {
|
|
|
609
633
|
});
|
|
610
634
|
}
|
|
611
635
|
const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true";
|
|
612
|
-
headers.set(
|
|
636
|
+
headers.set(ERROR_HEADER, encodeErrorHeaderValue(error));
|
|
613
637
|
return encodeResult(x, headers, 200, codec);
|
|
614
638
|
}
|
|
615
639
|
}
|
|
616
640
|
|
|
641
|
+
exports.ERROR_HEADER = ERROR_HEADER;
|
|
617
642
|
exports.FUNCTION_HEADER = FUNCTION_HEADER;
|
|
618
643
|
exports.GET = GET;
|
|
619
644
|
exports.INSTANCE_HEADER = INSTANCE_HEADER;
|
|
620
645
|
exports.SINGLE_FLIGHT_HEADER = SINGLE_FLIGHT_HEADER;
|
|
621
646
|
exports.configureServerFunctionsServer = configureServerFunctionsServer;
|
|
622
647
|
exports.createServerReference = createServerReference;
|
|
648
|
+
exports.decodeErrorHeaderValue = decodeErrorHeaderValue;
|
|
623
649
|
exports.decodeResponse = decodeResponse;
|
|
650
|
+
exports.encodeErrorHeaderValue = encodeErrorHeaderValue;
|
|
624
651
|
exports.getServerFunction = getServerFunction;
|
|
625
652
|
exports.getServerFunctionMeta = getServerFunctionMeta;
|
|
626
653
|
exports.getServerFunctionMetadata = getServerFunctionMetadata;
|
|
@@ -86,6 +86,31 @@ function withMeta(fn, meta) {
|
|
|
86
86
|
return fn;
|
|
87
87
|
}
|
|
88
88
|
const FUNCTION_HEADER = "X-Server-Function-Id";
|
|
89
|
+
const ERROR_HEADER = "X-Server-Function-Error";
|
|
90
|
+
const ERROR_HEADER_MARKER = "=?1?";
|
|
91
|
+
const NEEDS_ENCODING = /[^\x20-\x7e\xa0-\xff]/;
|
|
92
|
+
function encodeErrorHeaderValue(value) {
|
|
93
|
+
let stripped = String(value).replace(/[\r\n]+/g, "");
|
|
94
|
+
if (!NEEDS_ENCODING.test(stripped) && !stripped.startsWith(ERROR_HEADER_MARKER) && stripped === stripped.trim()) {
|
|
95
|
+
return stripped;
|
|
96
|
+
}
|
|
97
|
+
if (typeof stripped.toWellFormed === "function") {
|
|
98
|
+
stripped = stripped.toWellFormed();
|
|
99
|
+
} else {
|
|
100
|
+
stripped = stripped.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
|
|
101
|
+
}
|
|
102
|
+
return ERROR_HEADER_MARKER + encodeURIComponent(stripped);
|
|
103
|
+
}
|
|
104
|
+
function decodeErrorHeaderValue(value) {
|
|
105
|
+
if (typeof value !== "string" || !value.startsWith(ERROR_HEADER_MARKER)) {
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
return decodeURIComponent(value.slice(ERROR_HEADER_MARKER.length));
|
|
110
|
+
} catch {
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
89
114
|
const INSTANCE_HEADER = "X-Server-Function-Instance";
|
|
90
115
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
91
116
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
@@ -398,7 +423,8 @@ function resolveFunctionId(request, url) {
|
|
|
398
423
|
}
|
|
399
424
|
async function parseArguments(request, url, instance, codec) {
|
|
400
425
|
const parsed = [];
|
|
401
|
-
|
|
426
|
+
const bodyFormat = request.method === "POST" ? request.headers.get(BODY_FORMAT_HEADER) : null;
|
|
427
|
+
if (!instance || request.method === "GET" || bodyFormat !== BodyFormat.Serialized) {
|
|
402
428
|
const args = url.searchParams.get("args");
|
|
403
429
|
if (args) {
|
|
404
430
|
const result = args.startsWith(";0x") ? await deserializeString(args, codec) : JSON.parse(args);
|
|
@@ -408,9 +434,8 @@ async function parseArguments(request, url, instance, codec) {
|
|
|
408
434
|
}
|
|
409
435
|
}
|
|
410
436
|
if (request.method === "POST" && request.body !== null) {
|
|
411
|
-
const format = request.headers.get(BODY_FORMAT_HEADER);
|
|
412
437
|
const decoded = await extractBody(request.clone(), codec);
|
|
413
|
-
if (
|
|
438
|
+
if (bodyFormat === BodyFormat.Serialized) {
|
|
414
439
|
return decoded;
|
|
415
440
|
}
|
|
416
441
|
parsed.push(decoded);
|
|
@@ -468,12 +493,11 @@ async function handleServerFunctionRequest(request, options = {}) {
|
|
|
468
493
|
status: 404
|
|
469
494
|
});
|
|
470
495
|
}
|
|
471
|
-
|
|
472
|
-
if (request.method === "GET" !== (allowedMethod === "GET")) {
|
|
496
|
+
if (request.method === "GET" && METHODS.get(functionId) !== "GET") {
|
|
473
497
|
return new Response(process.env.NODE_ENV === "development" ? `Method not allowed for server function: ${functionId}` : null, {
|
|
474
498
|
status: 405,
|
|
475
499
|
headers: {
|
|
476
|
-
Allow:
|
|
500
|
+
Allow: "POST"
|
|
477
501
|
}
|
|
478
502
|
});
|
|
479
503
|
}
|
|
@@ -592,7 +616,7 @@ async function handleServerFunctionRequest(request, options = {}) {
|
|
|
592
616
|
thrown: true
|
|
593
617
|
});
|
|
594
618
|
}
|
|
595
|
-
headers.set(
|
|
619
|
+
headers.set(ERROR_HEADER, "true");
|
|
596
620
|
if (!instance) {
|
|
597
621
|
if (options.handleNoJS) return options.handleNoJS(x, request, parsed, true);
|
|
598
622
|
if (x instanceof Response) return x;
|
|
@@ -607,9 +631,9 @@ async function handleServerFunctionRequest(request, options = {}) {
|
|
|
607
631
|
});
|
|
608
632
|
}
|
|
609
633
|
const error = x instanceof Error ? x.message : typeof x === "string" ? x : "true";
|
|
610
|
-
headers.set(
|
|
634
|
+
headers.set(ERROR_HEADER, encodeErrorHeaderValue(error));
|
|
611
635
|
return encodeResult(x, headers, 200, codec);
|
|
612
636
|
}
|
|
613
637
|
}
|
|
614
638
|
|
|
615
|
-
export { FUNCTION_HEADER, GET, INSTANCE_HEADER, SINGLE_FLIGHT_HEADER, configureServerFunctionsServer, createServerReference, decodeResponse, getServerFunction, getServerFunctionMeta, getServerFunctionMetadata, handleServerFunctionRequest, isServerFunction, registerServerFunction, registerServerReference, subscribeFlightData, withMeta };
|
|
639
|
+
export { ERROR_HEADER, FUNCTION_HEADER, GET, INSTANCE_HEADER, SINGLE_FLIGHT_HEADER, configureServerFunctionsServer, createServerReference, decodeErrorHeaderValue, decodeResponse, encodeErrorHeaderValue, getServerFunction, getServerFunctionMeta, getServerFunctionMetadata, handleServerFunctionRequest, isServerFunction, registerServerFunction, registerServerReference, subscribeFlightData, withMeta };
|
package/types/client.d.ts
CHANGED
|
@@ -66,6 +66,24 @@ export function assign(
|
|
|
66
66
|
): void;
|
|
67
67
|
export function setAttribute(node: Element, name: string, value: string): void;
|
|
68
68
|
export function setAttributeNS(node: Element, namespace: string, name: string, value: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Register a consumer for compiler-emitted element claims. Compiled DOM
|
|
71
|
+
* output claims navigation-relevant elements (`a[href]`, `form[action]`) at
|
|
72
|
+
* creation, and compiler-owned writes to `href`/`action` re-invoke the same
|
|
73
|
+
* handlers — so handlers must be idempotent and must check the element's
|
|
74
|
+
* relevance themselves (rechecks can fire for any element whose
|
|
75
|
+
* `href`/`action` is written, e.g. `<link href>`). Handlers run under the
|
|
76
|
+
* reactive owner current at element creation; scope per-element state and
|
|
77
|
+
* cleanup through your own reactive system. Dormant until registered —
|
|
78
|
+
* without a handler the emitted claims are null checks. Returns an
|
|
79
|
+
* unregister function.
|
|
80
|
+
*/
|
|
81
|
+
export function registerElementClaim(handler: (element: Element) => void): () => void;
|
|
82
|
+
/**
|
|
83
|
+
* Claim `node` for registered consumers (see `registerElementClaim`).
|
|
84
|
+
* Emitted by the compiler at element creation; idempotent by contract.
|
|
85
|
+
*/
|
|
86
|
+
export function claimElement<T extends Element>(node: T): T;
|
|
69
87
|
export function className(node: Element, value: JSX.ClassValue, prev?: JSX.ClassValue): void;
|
|
70
88
|
export function setProperty(node: Element, name: string, value: any): void;
|
|
71
89
|
export function setStyleProperty(node: Element, name: string, value: any): void;
|
package/types/jsx.d.ts
CHANGED
|
@@ -1120,7 +1120,7 @@ export namespace JSX {
|
|
|
1120
1120
|
|
|
1121
1121
|
interface AnchorHTMLAttributes<T> extends HTMLAttributes<T> {
|
|
1122
1122
|
download?: string | EnumeratedAcceptsEmpty | RemoveAttribute;
|
|
1123
|
-
href?: string | RemoveAttribute;
|
|
1123
|
+
href?: string | SerializableAttributeValue | RemoveAttribute;
|
|
1124
1124
|
hreflang?: string | RemoveAttribute;
|
|
1125
1125
|
ping?: string | RemoveAttribute;
|
|
1126
1126
|
referrerpolicy?: HTMLReferrerPolicy | RemoveAttribute;
|
|
@@ -1128,6 +1128,21 @@ export namespace JSX {
|
|
|
1128
1128
|
target?: "_self" | "_blank" | "_parent" | "_top" | (string & {}) | RemoveAttribute;
|
|
1129
1129
|
type?: string | RemoveAttribute;
|
|
1130
1130
|
|
|
1131
|
+
// Client-side navigation contract. These attributes are inert markup on
|
|
1132
|
+
// their own — a routing integration that delegates anchor clicks (e.g.
|
|
1133
|
+
// @solidjs/router) reads them off the element at event time. Typed here
|
|
1134
|
+
// so plain `<a>` elements participate without per-router augmentation.
|
|
1135
|
+
/** Marks the anchor as a client-navigation link when the integration requires explicit opt-in. */
|
|
1136
|
+
link?: BooleanAttribute | RemoveAttribute;
|
|
1137
|
+
/** Serialized (JSON) history state pushed alongside the navigation. */
|
|
1138
|
+
state?: string | RemoveAttribute;
|
|
1139
|
+
/** Suppress scroll restoration/reset after the navigation. */
|
|
1140
|
+
noScroll?: BooleanAttribute | RemoveAttribute;
|
|
1141
|
+
/** Replace the current history entry instead of pushing a new one. */
|
|
1142
|
+
replace?: BooleanAttribute | RemoveAttribute;
|
|
1143
|
+
/** Route preload intent; `"false"` disables the integration's default eager preload. */
|
|
1144
|
+
preload?: boolean | "false" | RemoveAttribute;
|
|
1145
|
+
|
|
1131
1146
|
/** @experimental */
|
|
1132
1147
|
attributionsrc?: string | RemoveAttribute;
|
|
1133
1148
|
|
|
@@ -1147,7 +1162,7 @@ export namespace JSX {
|
|
|
1147
1162
|
alt?: string | RemoveAttribute;
|
|
1148
1163
|
coords?: string | RemoveAttribute;
|
|
1149
1164
|
download?: string | EnumeratedAcceptsEmpty | RemoveAttribute;
|
|
1150
|
-
href?: string | RemoveAttribute;
|
|
1165
|
+
href?: string | SerializableAttributeValue | RemoveAttribute;
|
|
1151
1166
|
ping?: string | RemoveAttribute;
|
|
1152
1167
|
referrerpolicy?: HTMLReferrerPolicy | RemoveAttribute;
|
|
1153
1168
|
rel?: string | RemoveAttribute;
|
package/types/response.d.ts
CHANGED
|
@@ -23,6 +23,32 @@ export class ResponseEnvelope<T = unknown> {
|
|
|
23
23
|
*/
|
|
24
24
|
export function isResponseEnvelope(value: unknown): value is ResponseEnvelope;
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Registered-symbol brand (`Symbol.for("solid.Href")`) marking URL-bearing
|
|
28
|
+
* values. Declared `unique symbol` type-side; the runtime value is the
|
|
29
|
+
* registered symbol, so separately bundled copies agree on identity.
|
|
30
|
+
*/
|
|
31
|
+
export declare const HREF: unique symbol;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A URL-bearing value: coerces to its URL via `toString()` and carries the
|
|
35
|
+
* `HREF` registered-symbol brand. Integrations mint these (e.g. a router's
|
|
36
|
+
* typed path objects answer the brand from their proxy) and URL-accepting
|
|
37
|
+
* APIs like `redirect()` accept them alongside plain strings. The brand is
|
|
38
|
+
* what makes the type meaningful — every object has `toString()`.
|
|
39
|
+
*/
|
|
40
|
+
export interface Href {
|
|
41
|
+
[HREF]: true;
|
|
42
|
+
toString(): string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether `value` is an `Href`-branded URL-bearing value. Registered-symbol
|
|
47
|
+
* check, so it stays correct across duplicated module instances — same
|
|
48
|
+
* rationale as `isResponseEnvelope`.
|
|
49
|
+
*/
|
|
50
|
+
export function isHref(value: unknown): value is Href;
|
|
51
|
+
|
|
26
52
|
/** `ResponseInit` accepted by the response helpers, plus `revalidate`. */
|
|
27
53
|
export interface ResponseHelperInit extends ResponseInit {
|
|
28
54
|
/**
|
|
@@ -51,7 +77,7 @@ export interface ResponseHelperInit extends ResponseInit {
|
|
|
51
77
|
* }
|
|
52
78
|
* ```
|
|
53
79
|
*/
|
|
54
|
-
export function redirect(url: string, init?: number | ResponseHelperInit): Response;
|
|
80
|
+
export function redirect(url: string | Href, init?: number | ResponseHelperInit): Response;
|
|
55
81
|
|
|
56
82
|
/**
|
|
57
83
|
* Empty response requesting revalidation of the named cache keys — all of
|
|
@@ -2,10 +2,13 @@ import { JSONCodecOptions } from "../serializer.js";
|
|
|
2
2
|
import { ServerFunction, ServerFunctionMetadata } from "./shared.js";
|
|
3
3
|
|
|
4
4
|
export {
|
|
5
|
+
ERROR_HEADER,
|
|
5
6
|
FUNCTION_HEADER,
|
|
6
7
|
INSTANCE_HEADER,
|
|
7
8
|
SINGLE_FLIGHT_HEADER,
|
|
9
|
+
decodeErrorHeaderValue,
|
|
8
10
|
decodeResponse,
|
|
11
|
+
encodeErrorHeaderValue,
|
|
9
12
|
getServerFunctionMetadata,
|
|
10
13
|
isServerFunction,
|
|
11
14
|
subscribeFlightData,
|
|
@@ -97,10 +100,11 @@ export function configureServerFunctionsClient(config?: ServerFunctionsClientCon
|
|
|
97
100
|
*
|
|
98
101
|
* The declaration rides the metadata channel
|
|
99
102
|
* (`getServerFunctionMetadata(fn)?.method === "GET"`) for routers and
|
|
100
|
-
* integrations to detect, and the server
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
103
|
+
* integrations to detect, and the server honors it: GET-declared functions
|
|
104
|
+
* accept GET requests in addition to the default POST transport (declaring
|
|
105
|
+
* GET grants, it does not revoke); functions that never declared GET answer
|
|
106
|
+
* GET requests with 405. Server-side the wrapper is identity-flavored — SSR
|
|
107
|
+
* calls stay in-process.
|
|
104
108
|
*
|
|
105
109
|
* Wrap the reference at its declaration; the compiler round-trips the call
|
|
106
110
|
* in both builds:
|
|
@@ -123,9 +127,16 @@ export function GET<A extends readonly any[], R>(
|
|
|
123
127
|
* source name as the trailing argument (dev-only metadata seeded on the
|
|
124
128
|
* metadata channel; never emitted in production). Not meant for
|
|
125
129
|
* hand-written code.
|
|
130
|
+
*
|
|
131
|
+
* The optional `base` targets calls at that url verbatim instead of the
|
|
132
|
+
* configured endpoint — for integrations reconstructing a callable from a
|
|
133
|
+
* server-rendered action url (e.g. a router intercepting a form submit whose
|
|
134
|
+
* `action="/_server?id=...&args=..."` came off the wire): bound arguments
|
|
135
|
+
* stay in the query string, where the server reads them for natural-encoding
|
|
136
|
+
* bodies (FormData, urlencoded).
|
|
126
137
|
* @internal
|
|
127
138
|
*/
|
|
128
|
-
export function createServerReference(id: string, name?: string): ServerFunction;
|
|
139
|
+
export function createServerReference(id: string, name?: string, base?: string): ServerFunction;
|
|
129
140
|
|
|
130
141
|
/**
|
|
131
142
|
* Compiler ABI — only ever referenced by server-mode compiler output;
|
|
@@ -3,10 +3,13 @@ import { JSONCodecOptions } from "../serializer.js";
|
|
|
3
3
|
import { RequestEvent } from "../server.js";
|
|
4
4
|
|
|
5
5
|
export {
|
|
6
|
+
ERROR_HEADER,
|
|
6
7
|
FUNCTION_HEADER,
|
|
7
8
|
INSTANCE_HEADER,
|
|
8
9
|
SINGLE_FLIGHT_HEADER,
|
|
10
|
+
decodeErrorHeaderValue,
|
|
9
11
|
decodeResponse,
|
|
12
|
+
encodeErrorHeaderValue,
|
|
10
13
|
getServerFunctionMetadata,
|
|
11
14
|
isServerFunction,
|
|
12
15
|
subscribeFlightData,
|
|
@@ -194,8 +197,9 @@ export function createServerReference<T extends any[], R>(
|
|
|
194
197
|
* declaration on the reference's metadata channel
|
|
195
198
|
* (`getServerFunctionMetadata(fn)?.method === "GET"`) and records the
|
|
196
199
|
* declared method for the function's id so `handleServerFunctionRequest`
|
|
197
|
-
*
|
|
198
|
-
*
|
|
200
|
+
* honors it: GET-declared functions accept GET requests in addition to the
|
|
201
|
+
* default POST transport (declaring GET grants, it does not revoke);
|
|
202
|
+
* functions that never declared GET answer GET requests with 405.
|
|
199
203
|
*
|
|
200
204
|
* Wrap the reference at its declaration; the compiler round-trips the call
|
|
201
205
|
* in both builds:
|
|
@@ -282,9 +286,9 @@ export interface HandleServerFunctionOptions {
|
|
|
282
286
|
|
|
283
287
|
/**
|
|
284
288
|
* Web-standard HTTP handler for server function calls: resolves the
|
|
285
|
-
* function id from the request,
|
|
286
|
-
* request
|
|
287
|
-
*
|
|
289
|
+
* function id from the request, gates GET dispatch on the declaration (405
|
|
290
|
+
* for a GET request to a function that never declared `GET`; POST is always
|
|
291
|
+
* accepted), decodes arguments, runs the function under a request-event scope,
|
|
288
292
|
* and encodes the result (forwarding redirect/revalidation metadata
|
|
289
293
|
* through headers). Mount it on the endpoint the client transport targets
|
|
290
294
|
* (default `/_server`); platform adapters (h3, express, ...) convert their
|
|
@@ -38,6 +38,35 @@ export const FUNCTION_HEADER: string;
|
|
|
38
38
|
*/
|
|
39
39
|
export const INSTANCE_HEADER: string;
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Response header marking a thrown server-function error
|
|
43
|
+
* (`"X-Server-Function-Error"`). The client transport rejects with the
|
|
44
|
+
* decoded body when it is present (unless redirect/revalidation metadata
|
|
45
|
+
* marks the response as control flow). The value carries the error's
|
|
46
|
+
* message — `"true"` for thrown control-flow responses and non-Error
|
|
47
|
+
* values — encoded with `encodeErrorHeaderValue`, so integrations reading
|
|
48
|
+
* it must pass it through `decodeErrorHeaderValue`.
|
|
49
|
+
*/
|
|
50
|
+
export const ERROR_HEADER: string;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Encodes an error message for the `ERROR_HEADER` value. HTTP header values
|
|
54
|
+
* are latin1 ByteStrings — `Headers.set` throws on code points above U+00FF
|
|
55
|
+
* — so plain printable-latin1 messages ride verbatim (ASCII stays
|
|
56
|
+
* byte-identical on the wire) and everything else (CJK, emoji, controls)
|
|
57
|
+
* travels percent-encoded behind a marker. `decodeErrorHeaderValue`
|
|
58
|
+
* round-trips the message exactly, astral-plane characters included (lone
|
|
59
|
+
* surrogates are replaced with U+FFFD — they cannot survive UTF-8 anyway).
|
|
60
|
+
*/
|
|
61
|
+
export function encodeErrorHeaderValue(value: string): string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Decodes an `ERROR_HEADER` value produced by `encodeErrorHeaderValue`:
|
|
65
|
+
* marked values are percent-decoded, everything else (including values from
|
|
66
|
+
* peers that never encode) passes through untouched.
|
|
67
|
+
*/
|
|
68
|
+
export function decodeErrorHeaderValue(value: string): string;
|
|
69
|
+
|
|
41
70
|
/**
|
|
42
71
|
* Header driving the single-flight protocol on both legs
|
|
43
72
|
* (`"X-Single-Flight"`). On the request it opts the call into data
|
package/types/server.d.ts
CHANGED
|
@@ -205,6 +205,14 @@ export function setAttribute(node: Element, name: string, value: string): void;
|
|
|
205
205
|
/** @deprecated not supported on the server side */
|
|
206
206
|
export function setAttributeNS(node: Element, namespace: string, name: string, value: string): void;
|
|
207
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Server no-op: element claims are a client-only concern, but consumers may
|
|
210
|
+
* register isomorphically. Returns a no-op unregister function.
|
|
211
|
+
*/
|
|
212
|
+
export function registerElementClaim(handler: (element: Element) => void): () => void;
|
|
213
|
+
/** Server no-op: returns `node` unchanged. Claims never fire during SSR. */
|
|
214
|
+
export function claimElement<T extends Element>(node: T): T;
|
|
215
|
+
|
|
208
216
|
/** @deprecated not supported on the server side */
|
|
209
217
|
export function addEvent(node: Element, name: string, handler: () => void, delegate: boolean): void;
|
|
210
218
|
|
package/types-cjs/client.d.cts
CHANGED
|
@@ -66,6 +66,24 @@ export function assign(
|
|
|
66
66
|
): void;
|
|
67
67
|
export function setAttribute(node: Element, name: string, value: string): void;
|
|
68
68
|
export function setAttributeNS(node: Element, namespace: string, name: string, value: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Register a consumer for compiler-emitted element claims. Compiled DOM
|
|
71
|
+
* output claims navigation-relevant elements (`a[href]`, `form[action]`) at
|
|
72
|
+
* creation, and compiler-owned writes to `href`/`action` re-invoke the same
|
|
73
|
+
* handlers — so handlers must be idempotent and must check the element's
|
|
74
|
+
* relevance themselves (rechecks can fire for any element whose
|
|
75
|
+
* `href`/`action` is written, e.g. `<link href>`). Handlers run under the
|
|
76
|
+
* reactive owner current at element creation; scope per-element state and
|
|
77
|
+
* cleanup through your own reactive system. Dormant until registered —
|
|
78
|
+
* without a handler the emitted claims are null checks. Returns an
|
|
79
|
+
* unregister function.
|
|
80
|
+
*/
|
|
81
|
+
export function registerElementClaim(handler: (element: Element) => void): () => void;
|
|
82
|
+
/**
|
|
83
|
+
* Claim `node` for registered consumers (see `registerElementClaim`).
|
|
84
|
+
* Emitted by the compiler at element creation; idempotent by contract.
|
|
85
|
+
*/
|
|
86
|
+
export function claimElement<T extends Element>(node: T): T;
|
|
69
87
|
export function className(node: Element, value: JSX.ClassValue, prev?: JSX.ClassValue): void;
|
|
70
88
|
export function setProperty(node: Element, name: string, value: any): void;
|
|
71
89
|
export function setStyleProperty(node: Element, name: string, value: any): void;
|
package/types-cjs/jsx.d.cts
CHANGED
|
@@ -1120,7 +1120,7 @@ export namespace JSX {
|
|
|
1120
1120
|
|
|
1121
1121
|
interface AnchorHTMLAttributes<T> extends HTMLAttributes<T> {
|
|
1122
1122
|
download?: string | EnumeratedAcceptsEmpty | RemoveAttribute;
|
|
1123
|
-
href?: string | RemoveAttribute;
|
|
1123
|
+
href?: string | SerializableAttributeValue | RemoveAttribute;
|
|
1124
1124
|
hreflang?: string | RemoveAttribute;
|
|
1125
1125
|
ping?: string | RemoveAttribute;
|
|
1126
1126
|
referrerpolicy?: HTMLReferrerPolicy | RemoveAttribute;
|
|
@@ -1128,6 +1128,21 @@ export namespace JSX {
|
|
|
1128
1128
|
target?: "_self" | "_blank" | "_parent" | "_top" | (string & {}) | RemoveAttribute;
|
|
1129
1129
|
type?: string | RemoveAttribute;
|
|
1130
1130
|
|
|
1131
|
+
// Client-side navigation contract. These attributes are inert markup on
|
|
1132
|
+
// their own — a routing integration that delegates anchor clicks (e.g.
|
|
1133
|
+
// @solidjs/router) reads them off the element at event time. Typed here
|
|
1134
|
+
// so plain `<a>` elements participate without per-router augmentation.
|
|
1135
|
+
/** Marks the anchor as a client-navigation link when the integration requires explicit opt-in. */
|
|
1136
|
+
link?: BooleanAttribute | RemoveAttribute;
|
|
1137
|
+
/** Serialized (JSON) history state pushed alongside the navigation. */
|
|
1138
|
+
state?: string | RemoveAttribute;
|
|
1139
|
+
/** Suppress scroll restoration/reset after the navigation. */
|
|
1140
|
+
noScroll?: BooleanAttribute | RemoveAttribute;
|
|
1141
|
+
/** Replace the current history entry instead of pushing a new one. */
|
|
1142
|
+
replace?: BooleanAttribute | RemoveAttribute;
|
|
1143
|
+
/** Route preload intent; `"false"` disables the integration's default eager preload. */
|
|
1144
|
+
preload?: boolean | "false" | RemoveAttribute;
|
|
1145
|
+
|
|
1131
1146
|
/** @experimental */
|
|
1132
1147
|
attributionsrc?: string | RemoveAttribute;
|
|
1133
1148
|
|
|
@@ -1147,7 +1162,7 @@ export namespace JSX {
|
|
|
1147
1162
|
alt?: string | RemoveAttribute;
|
|
1148
1163
|
coords?: string | RemoveAttribute;
|
|
1149
1164
|
download?: string | EnumeratedAcceptsEmpty | RemoveAttribute;
|
|
1150
|
-
href?: string | RemoveAttribute;
|
|
1165
|
+
href?: string | SerializableAttributeValue | RemoveAttribute;
|
|
1151
1166
|
ping?: string | RemoveAttribute;
|
|
1152
1167
|
referrerpolicy?: HTMLReferrerPolicy | RemoveAttribute;
|
|
1153
1168
|
rel?: string | RemoveAttribute;
|
package/types-cjs/response.d.cts
CHANGED
|
@@ -23,6 +23,32 @@ export class ResponseEnvelope<T = unknown> {
|
|
|
23
23
|
*/
|
|
24
24
|
export function isResponseEnvelope(value: unknown): value is ResponseEnvelope;
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Registered-symbol brand (`Symbol.for("solid.Href")`) marking URL-bearing
|
|
28
|
+
* values. Declared `unique symbol` type-side; the runtime value is the
|
|
29
|
+
* registered symbol, so separately bundled copies agree on identity.
|
|
30
|
+
*/
|
|
31
|
+
export declare const HREF: unique symbol;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A URL-bearing value: coerces to its URL via `toString()` and carries the
|
|
35
|
+
* `HREF` registered-symbol brand. Integrations mint these (e.g. a router's
|
|
36
|
+
* typed path objects answer the brand from their proxy) and URL-accepting
|
|
37
|
+
* APIs like `redirect()` accept them alongside plain strings. The brand is
|
|
38
|
+
* what makes the type meaningful — every object has `toString()`.
|
|
39
|
+
*/
|
|
40
|
+
export interface Href {
|
|
41
|
+
[HREF]: true;
|
|
42
|
+
toString(): string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether `value` is an `Href`-branded URL-bearing value. Registered-symbol
|
|
47
|
+
* check, so it stays correct across duplicated module instances — same
|
|
48
|
+
* rationale as `isResponseEnvelope`.
|
|
49
|
+
*/
|
|
50
|
+
export function isHref(value: unknown): value is Href;
|
|
51
|
+
|
|
26
52
|
/** `ResponseInit` accepted by the response helpers, plus `revalidate`. */
|
|
27
53
|
export interface ResponseHelperInit extends ResponseInit {
|
|
28
54
|
/**
|
|
@@ -51,7 +77,7 @@ export interface ResponseHelperInit extends ResponseInit {
|
|
|
51
77
|
* }
|
|
52
78
|
* ```
|
|
53
79
|
*/
|
|
54
|
-
export function redirect(url: string, init?: number | ResponseHelperInit): Response;
|
|
80
|
+
export function redirect(url: string | Href, init?: number | ResponseHelperInit): Response;
|
|
55
81
|
|
|
56
82
|
/**
|
|
57
83
|
* Empty response requesting revalidation of the named cache keys — all of
|
|
@@ -2,10 +2,13 @@ import { JSONCodecOptions } from "../serializer.cjs";
|
|
|
2
2
|
import { ServerFunction, ServerFunctionMetadata } from "./shared.cjs";
|
|
3
3
|
|
|
4
4
|
export {
|
|
5
|
+
ERROR_HEADER,
|
|
5
6
|
FUNCTION_HEADER,
|
|
6
7
|
INSTANCE_HEADER,
|
|
7
8
|
SINGLE_FLIGHT_HEADER,
|
|
9
|
+
decodeErrorHeaderValue,
|
|
8
10
|
decodeResponse,
|
|
11
|
+
encodeErrorHeaderValue,
|
|
9
12
|
getServerFunctionMetadata,
|
|
10
13
|
isServerFunction,
|
|
11
14
|
subscribeFlightData,
|
|
@@ -97,10 +100,11 @@ export function configureServerFunctionsClient(config?: ServerFunctionsClientCon
|
|
|
97
100
|
*
|
|
98
101
|
* The declaration rides the metadata channel
|
|
99
102
|
* (`getServerFunctionMetadata(fn)?.method === "GET"`) for routers and
|
|
100
|
-
* integrations to detect, and the server
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
103
|
+
* integrations to detect, and the server honors it: GET-declared functions
|
|
104
|
+
* accept GET requests in addition to the default POST transport (declaring
|
|
105
|
+
* GET grants, it does not revoke); functions that never declared GET answer
|
|
106
|
+
* GET requests with 405. Server-side the wrapper is identity-flavored — SSR
|
|
107
|
+
* calls stay in-process.
|
|
104
108
|
*
|
|
105
109
|
* Wrap the reference at its declaration; the compiler round-trips the call
|
|
106
110
|
* in both builds:
|
|
@@ -123,9 +127,16 @@ export function GET<A extends readonly any[], R>(
|
|
|
123
127
|
* source name as the trailing argument (dev-only metadata seeded on the
|
|
124
128
|
* metadata channel; never emitted in production). Not meant for
|
|
125
129
|
* hand-written code.
|
|
130
|
+
*
|
|
131
|
+
* The optional `base` targets calls at that url verbatim instead of the
|
|
132
|
+
* configured endpoint — for integrations reconstructing a callable from a
|
|
133
|
+
* server-rendered action url (e.g. a router intercepting a form submit whose
|
|
134
|
+
* `action="/_server?id=...&args=..."` came off the wire): bound arguments
|
|
135
|
+
* stay in the query string, where the server reads them for natural-encoding
|
|
136
|
+
* bodies (FormData, urlencoded).
|
|
126
137
|
* @internal
|
|
127
138
|
*/
|
|
128
|
-
export function createServerReference(id: string, name?: string): ServerFunction;
|
|
139
|
+
export function createServerReference(id: string, name?: string, base?: string): ServerFunction;
|
|
129
140
|
|
|
130
141
|
/**
|
|
131
142
|
* Compiler ABI — only ever referenced by server-mode compiler output;
|
|
@@ -3,10 +3,13 @@ import { JSONCodecOptions } from "../serializer.cjs";
|
|
|
3
3
|
import { RequestEvent } from "../server.cjs";
|
|
4
4
|
|
|
5
5
|
export {
|
|
6
|
+
ERROR_HEADER,
|
|
6
7
|
FUNCTION_HEADER,
|
|
7
8
|
INSTANCE_HEADER,
|
|
8
9
|
SINGLE_FLIGHT_HEADER,
|
|
10
|
+
decodeErrorHeaderValue,
|
|
9
11
|
decodeResponse,
|
|
12
|
+
encodeErrorHeaderValue,
|
|
10
13
|
getServerFunctionMetadata,
|
|
11
14
|
isServerFunction,
|
|
12
15
|
subscribeFlightData,
|
|
@@ -194,8 +197,9 @@ export function createServerReference<T extends any[], R>(
|
|
|
194
197
|
* declaration on the reference's metadata channel
|
|
195
198
|
* (`getServerFunctionMetadata(fn)?.method === "GET"`) and records the
|
|
196
199
|
* declared method for the function's id so `handleServerFunctionRequest`
|
|
197
|
-
*
|
|
198
|
-
*
|
|
200
|
+
* honors it: GET-declared functions accept GET requests in addition to the
|
|
201
|
+
* default POST transport (declaring GET grants, it does not revoke);
|
|
202
|
+
* functions that never declared GET answer GET requests with 405.
|
|
199
203
|
*
|
|
200
204
|
* Wrap the reference at its declaration; the compiler round-trips the call
|
|
201
205
|
* in both builds:
|
|
@@ -282,9 +286,9 @@ export interface HandleServerFunctionOptions {
|
|
|
282
286
|
|
|
283
287
|
/**
|
|
284
288
|
* Web-standard HTTP handler for server function calls: resolves the
|
|
285
|
-
* function id from the request,
|
|
286
|
-
* request
|
|
287
|
-
*
|
|
289
|
+
* function id from the request, gates GET dispatch on the declaration (405
|
|
290
|
+
* for a GET request to a function that never declared `GET`; POST is always
|
|
291
|
+
* accepted), decodes arguments, runs the function under a request-event scope,
|
|
288
292
|
* and encodes the result (forwarding redirect/revalidation metadata
|
|
289
293
|
* through headers). Mount it on the endpoint the client transport targets
|
|
290
294
|
* (default `/_server`); platform adapters (h3, express, ...) convert their
|
|
@@ -38,6 +38,35 @@ export const FUNCTION_HEADER: string;
|
|
|
38
38
|
*/
|
|
39
39
|
export const INSTANCE_HEADER: string;
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Response header marking a thrown server-function error
|
|
43
|
+
* (`"X-Server-Function-Error"`). The client transport rejects with the
|
|
44
|
+
* decoded body when it is present (unless redirect/revalidation metadata
|
|
45
|
+
* marks the response as control flow). The value carries the error's
|
|
46
|
+
* message — `"true"` for thrown control-flow responses and non-Error
|
|
47
|
+
* values — encoded with `encodeErrorHeaderValue`, so integrations reading
|
|
48
|
+
* it must pass it through `decodeErrorHeaderValue`.
|
|
49
|
+
*/
|
|
50
|
+
export const ERROR_HEADER: string;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Encodes an error message for the `ERROR_HEADER` value. HTTP header values
|
|
54
|
+
* are latin1 ByteStrings — `Headers.set` throws on code points above U+00FF
|
|
55
|
+
* — so plain printable-latin1 messages ride verbatim (ASCII stays
|
|
56
|
+
* byte-identical on the wire) and everything else (CJK, emoji, controls)
|
|
57
|
+
* travels percent-encoded behind a marker. `decodeErrorHeaderValue`
|
|
58
|
+
* round-trips the message exactly, astral-plane characters included (lone
|
|
59
|
+
* surrogates are replaced with U+FFFD — they cannot survive UTF-8 anyway).
|
|
60
|
+
*/
|
|
61
|
+
export function encodeErrorHeaderValue(value: string): string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Decodes an `ERROR_HEADER` value produced by `encodeErrorHeaderValue`:
|
|
65
|
+
* marked values are percent-decoded, everything else (including values from
|
|
66
|
+
* peers that never encode) passes through untouched.
|
|
67
|
+
*/
|
|
68
|
+
export function decodeErrorHeaderValue(value: string): string;
|
|
69
|
+
|
|
41
70
|
/**
|
|
42
71
|
* Header driving the single-flight protocol on both legs
|
|
43
72
|
* (`"X-Single-Flight"`). On the request it opts the call into data
|
package/types-cjs/server.d.cts
CHANGED
|
@@ -205,6 +205,14 @@ export function setAttribute(node: Element, name: string, value: string): void;
|
|
|
205
205
|
/** @deprecated not supported on the server side */
|
|
206
206
|
export function setAttributeNS(node: Element, namespace: string, name: string, value: string): void;
|
|
207
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Server no-op: element claims are a client-only concern, but consumers may
|
|
210
|
+
* register isomorphically. Returns a no-op unregister function.
|
|
211
|
+
*/
|
|
212
|
+
export function registerElementClaim(handler: (element: Element) => void): () => void;
|
|
213
|
+
/** Server no-op: returns `node` unchanged. Claims never fire during SSR. */
|
|
214
|
+
export function claimElement<T extends Element>(node: T): T;
|
|
215
|
+
|
|
208
216
|
/** @deprecated not supported on the server side */
|
|
209
217
|
export function addEvent(node: Element, name: string, handler: () => void, delegate: boolean): void;
|
|
210
218
|
|