@solidjs/web 2.0.0-beta.32 → 2.0.0-beta.33
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 +51 -15
- package/dist/dev.js +47 -16
- package/dist/server.cjs +710 -71
- package/dist/server.js +707 -74
- package/dist/web.cjs +51 -15
- package/dist/web.js +47 -16
- package/frames/dist/client.cjs +181 -64
- package/frames/dist/client.dev.cjs +185 -64
- package/frames/dist/client.dev.js +183 -62
- package/frames/dist/client.js +179 -62
- package/frames/dist/server.cjs +969 -133
- package/frames/dist/server.js +971 -135
- package/package.json +17 -6
- package/serialization/decode/package.json +20 -0
- package/serialization/dist/decode.cjs +110 -0
- package/serialization/dist/decode.js +104 -0
- package/serialization/dist/serialization.cjs +98 -43
- package/serialization/dist/serialization.js +99 -44
- package/serialization/types/index.d.ts +18 -160
- package/serialization/types/serializer-decode.d.ts +182 -0
- package/serialization/types-cjs/index.d.cts +18 -160
- package/serialization/types-cjs/serializer-decode.d.cts +182 -0
- package/server-functions/dist/client.cjs +101 -105
- package/server-functions/dist/client.js +101 -105
- package/server-functions/dist/server.cjs +131 -107
- package/server-functions/dist/server.dev.cjs +131 -107
- package/server-functions/dist/server.dev.js +132 -108
- package/server-functions/dist/server.js +132 -108
- package/types/client.d.ts +23 -1
- package/types/cookies.d.ts +93 -0
- package/types/core.d.ts +1 -1
- package/types/frames/frame-client.d.ts +26 -0
- package/types/frames/frame-transport.d.ts +1 -1
- package/types/frames/serializer.d.ts +18 -160
- package/types/serializer-decode.d.ts +182 -0
- package/types/serializer.d.ts +18 -160
- package/types/server-functions/client.d.ts +1 -1
- package/types/server-functions/server.d.ts +1 -1
- package/types/server-functions/shared.d.ts +57 -1
- package/types/server.d.ts +21 -1
- package/types-cjs/client.d.cts +23 -1
- package/types-cjs/cookies.d.cts +93 -0
- package/types-cjs/core.d.cts +1 -1
- package/types-cjs/frames/frame-client.d.cts +26 -0
- package/types-cjs/frames/frame-transport.d.cts +1 -1
- package/types-cjs/frames/serializer.d.cts +18 -160
- package/types-cjs/serializer-decode.d.cts +182 -0
- package/types-cjs/serializer.d.cts +18 -160
- package/types-cjs/server-functions/client.d.cts +1 -1
- package/types-cjs/server-functions/server.d.cts +1 -1
- package/types-cjs/server-functions/shared.d.cts +57 -1
- package/types-cjs/server.d.cts +21 -1
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var seroval = require('seroval');
|
|
4
|
-
var web = require('seroval-plugins/web');
|
|
5
3
|
var solidJs = require('solid-js');
|
|
6
4
|
|
|
7
5
|
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
@@ -14,51 +12,70 @@ function isSafeError(value) {
|
|
|
14
12
|
}
|
|
15
13
|
const REVALIDATE_HEADER = "X-Revalidate";
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
web.FormDataPlugin, web.HeadersPlugin, web.ReadableStreamPlugin, web.RequestPlugin, web.ResponsePlugin, web.URLSearchParamsPlugin, web.URLPlugin]);
|
|
22
|
-
function resolveSerializerPlugins(customPlugins) {
|
|
23
|
-
return customPlugins ? [...customPlugins, ...DEFAULT_WEB_PLUGINS] : [...DEFAULT_WEB_PLUGINS];
|
|
15
|
+
const SERVER_FUNCTION_METADATA = Symbol.for("solid.ServerFunctionMetadata");
|
|
16
|
+
function getServerFunctionMetadata(fn) {
|
|
17
|
+
if (typeof fn !== "function") return undefined;
|
|
18
|
+
return fn[SERVER_FUNCTION_METADATA] || undefined;
|
|
24
19
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
function resolveCodecOptions({
|
|
28
|
-
plugins,
|
|
29
|
-
disabledFeatures,
|
|
30
|
-
depthLimit
|
|
31
|
-
} = {}) {
|
|
32
|
-
return {
|
|
33
|
-
plugins: resolveSerializerPlugins(plugins),
|
|
34
|
-
disabledFeatures: disabledFeatures === undefined ? JSON_CODEC_DISABLED_FEATURES : disabledFeatures,
|
|
35
|
-
depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
|
|
36
|
-
};
|
|
20
|
+
function isServerFunction(fn) {
|
|
21
|
+
return typeof fn === "function" && !!fn[SERVER_FUNCTION_METADATA];
|
|
37
22
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return seroval.toCrossJSONStream(value, {
|
|
46
|
-
onParse,
|
|
47
|
-
onDone,
|
|
48
|
-
onError,
|
|
49
|
-
...resolved,
|
|
50
|
-
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures()
|
|
51
|
-
});
|
|
23
|
+
function withMeta(fn, meta) {
|
|
24
|
+
const metadata = getServerFunctionMetadata(fn);
|
|
25
|
+
if (!metadata) {
|
|
26
|
+
throw new Error("withMeta expects a server function reference");
|
|
27
|
+
}
|
|
28
|
+
Object.assign(metadata, meta);
|
|
29
|
+
return fn;
|
|
52
30
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
31
|
+
const SERVER_FUNCTION_RPC = Symbol.for("solid.ServerFunctionRPC");
|
|
32
|
+
function provideServerFunctionRPC(rpc) {
|
|
33
|
+
globalThis[SERVER_FUNCTION_RPC] || (globalThis[SERVER_FUNCTION_RPC] = rpc);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function parseCookieHeader(header) {
|
|
37
|
+
const cookies = {};
|
|
38
|
+
if (!header) return cookies;
|
|
39
|
+
for (const part of header.split(";")) {
|
|
40
|
+
const eq = part.indexOf("=");
|
|
41
|
+
if (eq < 0) continue;
|
|
42
|
+
const name = decodeSafe(part.slice(0, eq).trim());
|
|
43
|
+
let value = part.slice(eq + 1).trim();
|
|
44
|
+
if (value.length > 1 && value[0] === '"' && value[value.length - 1] === '"') {
|
|
45
|
+
value = value.slice(1, -1);
|
|
46
|
+
}
|
|
47
|
+
cookies[name] = decodeSafe(value);
|
|
48
|
+
}
|
|
49
|
+
return cookies;
|
|
50
|
+
}
|
|
51
|
+
function decodeSafe(text) {
|
|
52
|
+
try {
|
|
53
|
+
return decodeURIComponent(text);
|
|
54
|
+
} catch {
|
|
55
|
+
return text;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function serializeCookie(name, value, options = {}) {
|
|
59
|
+
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
60
|
+
cookie += `; Path=${options.path === undefined ? "/" : options.path}`;
|
|
61
|
+
if (options.domain) cookie += `; Domain=${options.domain}`;
|
|
62
|
+
if (options.maxAge !== undefined) cookie += `; Max-Age=${Math.trunc(options.maxAge)}`;
|
|
63
|
+
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
64
|
+
if (options.httpOnly) cookie += "; HttpOnly";
|
|
65
|
+
if (options.secure) cookie += "; Secure";
|
|
66
|
+
if (options.sameSite) {
|
|
67
|
+
const sameSite = options.sameSite.toLowerCase();
|
|
68
|
+
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
69
|
+
}
|
|
70
|
+
return cookie;
|
|
71
|
+
}
|
|
72
|
+
const FLASH_COOKIE = "flash";
|
|
73
|
+
const FLASH_MATCHER = new RegExp(`(?:^|;\\s*)${FLASH_COOKIE}=([^;]+)`);
|
|
74
|
+
function hasFlashCookie(cookieHeader) {
|
|
75
|
+
return !!cookieHeader && FLASH_MATCHER.test(cookieHeader);
|
|
76
|
+
}
|
|
77
|
+
function clearFlashCookie() {
|
|
78
|
+
return `${FLASH_COOKIE}=; Max-Age=0; Path=/`;
|
|
62
79
|
}
|
|
63
80
|
|
|
64
81
|
const codecConfig = {
|
|
@@ -74,22 +91,6 @@ function subscribeFlightData(consumer) {
|
|
|
74
91
|
return () => {
|
|
75
92
|
};
|
|
76
93
|
}
|
|
77
|
-
const SERVER_FUNCTION_METADATA = Symbol.for("solid.ServerFunctionMetadata");
|
|
78
|
-
function getServerFunctionMetadata(fn) {
|
|
79
|
-
if (typeof fn !== "function") return undefined;
|
|
80
|
-
return fn[SERVER_FUNCTION_METADATA] || undefined;
|
|
81
|
-
}
|
|
82
|
-
function isServerFunction(fn) {
|
|
83
|
-
return typeof fn === "function" && !!fn[SERVER_FUNCTION_METADATA];
|
|
84
|
-
}
|
|
85
|
-
function withMeta(fn, meta) {
|
|
86
|
-
const metadata = getServerFunctionMetadata(fn);
|
|
87
|
-
if (!metadata) {
|
|
88
|
-
throw new Error("withMeta expects a server function reference");
|
|
89
|
-
}
|
|
90
|
-
Object.assign(metadata, meta);
|
|
91
|
-
return fn;
|
|
92
|
-
}
|
|
93
94
|
const FUNCTION_HEADER = "X-Server-Function-Id";
|
|
94
95
|
const ERROR_HEADER = "X-Server-Function-Error";
|
|
95
96
|
const ERROR_HEADER_MARKER = "=?1?";
|
|
@@ -120,14 +121,6 @@ const INSTANCE_HEADER = "X-Server-Function-Instance";
|
|
|
120
121
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
121
122
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
122
123
|
const FILE_FORM_KEY = "__server_function_file__";
|
|
123
|
-
const FLASH_COOKIE = "flash";
|
|
124
|
-
const FLASH_MATCHER = new RegExp(`(?:^|;\\s*)${FLASH_COOKIE}=([^;]+)`);
|
|
125
|
-
function hasFlashCookie(cookieHeader) {
|
|
126
|
-
return !!cookieHeader && FLASH_MATCHER.test(cookieHeader);
|
|
127
|
-
}
|
|
128
|
-
function clearFlashCookie() {
|
|
129
|
-
return `${FLASH_COOKIE}=; Max-Age=0; Path=/`;
|
|
130
|
-
}
|
|
131
124
|
const BodyFormat = {
|
|
132
125
|
Serialized: "0",
|
|
133
126
|
String: "1",
|
|
@@ -139,6 +132,38 @@ const BodyFormat = {
|
|
|
139
132
|
Uint8Array: "7",
|
|
140
133
|
Json: "8"
|
|
141
134
|
};
|
|
135
|
+
const JSON_SAFE_DEPTH_LIMIT = 10000;
|
|
136
|
+
const EXIT = {};
|
|
137
|
+
function isJSONSafe(value) {
|
|
138
|
+
const stack = [value];
|
|
139
|
+
const ancestors = new Set();
|
|
140
|
+
while (stack.length) {
|
|
141
|
+
const v = stack.pop();
|
|
142
|
+
if (v === EXIT) {
|
|
143
|
+
ancestors.delete(stack.pop());
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (v === null) continue;
|
|
147
|
+
const t = typeof v;
|
|
148
|
+
if (t === "string" || t === "boolean") continue;
|
|
149
|
+
if (t === "number") {
|
|
150
|
+
if (!Number.isFinite(v)) return false;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (t !== "object") return false;
|
|
154
|
+
if (ancestors.has(v) || ancestors.size >= JSON_SAFE_DEPTH_LIMIT) return false;
|
|
155
|
+
ancestors.add(v);
|
|
156
|
+
stack.push(v, EXIT);
|
|
157
|
+
if (Array.isArray(v)) {
|
|
158
|
+
for (let i = 0; i < v.length; i++) stack.push(v[i]);
|
|
159
|
+
} else {
|
|
160
|
+
const proto = Object.getPrototypeOf(v);
|
|
161
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
162
|
+
for (const k in v) stack.push(v[k]);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
142
167
|
function getHeadersAndBody(body) {
|
|
143
168
|
switch (true) {
|
|
144
169
|
case typeof body === "string":
|
|
@@ -298,7 +323,10 @@ class ChunkReader {
|
|
|
298
323
|
}
|
|
299
324
|
function serializeStream(value, codecOptions) {
|
|
300
325
|
return new ReadableStream({
|
|
301
|
-
start(controller) {
|
|
326
|
+
async start(controller) {
|
|
327
|
+
const {
|
|
328
|
+
serializeJSON
|
|
329
|
+
} = await import('@solidjs/web/serialization');
|
|
302
330
|
serializeJSON(value, {
|
|
303
331
|
...codecOptions,
|
|
304
332
|
onParse(node) {
|
|
@@ -321,6 +349,9 @@ async function deserializeStream(source, codecOptions) {
|
|
|
321
349
|
const reader = new ChunkReader(source.body);
|
|
322
350
|
const result = await reader.next();
|
|
323
351
|
if (!result.done) {
|
|
352
|
+
const {
|
|
353
|
+
createJSONDeserializer
|
|
354
|
+
} = await import('@solidjs/web/serialization/decode');
|
|
324
355
|
const deserializeChunk = createJSONDeserializer(codecOptions);
|
|
325
356
|
function interpretChunk(chunk) {
|
|
326
357
|
return deserializeChunk(JSON.parse(chunk));
|
|
@@ -350,43 +381,6 @@ async function decodeResponsePayload(response, codecOptions) {
|
|
|
350
381
|
};
|
|
351
382
|
}
|
|
352
383
|
|
|
353
|
-
function parseCookieHeader(header) {
|
|
354
|
-
const cookies = {};
|
|
355
|
-
if (!header) return cookies;
|
|
356
|
-
for (const part of header.split(";")) {
|
|
357
|
-
const eq = part.indexOf("=");
|
|
358
|
-
if (eq < 0) continue;
|
|
359
|
-
const name = decodeSafe(part.slice(0, eq).trim());
|
|
360
|
-
let value = part.slice(eq + 1).trim();
|
|
361
|
-
if (value.length > 1 && value[0] === '"' && value[value.length - 1] === '"') {
|
|
362
|
-
value = value.slice(1, -1);
|
|
363
|
-
}
|
|
364
|
-
cookies[name] = decodeSafe(value);
|
|
365
|
-
}
|
|
366
|
-
return cookies;
|
|
367
|
-
}
|
|
368
|
-
function decodeSafe(text) {
|
|
369
|
-
try {
|
|
370
|
-
return decodeURIComponent(text);
|
|
371
|
-
} catch {
|
|
372
|
-
return text;
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
function serializeCookie(name, value, options = {}) {
|
|
376
|
-
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
377
|
-
cookie += `; Path=${options.path === undefined ? "/" : options.path}`;
|
|
378
|
-
if (options.domain) cookie += `; Domain=${options.domain}`;
|
|
379
|
-
if (options.maxAge !== undefined) cookie += `; Max-Age=${Math.trunc(options.maxAge)}`;
|
|
380
|
-
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
381
|
-
if (options.httpOnly) cookie += "; HttpOnly";
|
|
382
|
-
if (options.secure) cookie += "; Secure";
|
|
383
|
-
if (options.sameSite) {
|
|
384
|
-
const sameSite = options.sameSite.toLowerCase();
|
|
385
|
-
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
386
|
-
}
|
|
387
|
-
return cookie;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
384
|
const RequestContext = Symbol.for("solid.RequestContext");
|
|
391
385
|
function getRequestEvent() {
|
|
392
386
|
return globalThis[RequestContext] ? globalThis[RequestContext].getStore() || solidJs.sharedConfig.context && solidJs.sharedConfig.context.event || console.warn("RequestEvent is missing. This is most likely due to accessing `getRequestEvent` non-managed async scope in a partially polyfilled environment. Try moving it above all `await` calls.") : undefined;
|
|
@@ -550,7 +544,17 @@ function provideEvent(event, fn) {
|
|
|
550
544
|
const REGISTRATIONS = new Map();
|
|
551
545
|
const METHODS = new Map();
|
|
552
546
|
const INVOCATIONS = new WeakMap();
|
|
547
|
+
let rpcProvided = false;
|
|
548
|
+
function provideRPC() {
|
|
549
|
+
if (rpcProvided) return;
|
|
550
|
+
rpcProvided = true;
|
|
551
|
+
provideServerFunctionRPC({
|
|
552
|
+
GET,
|
|
553
|
+
decodeResponse
|
|
554
|
+
});
|
|
555
|
+
}
|
|
553
556
|
function registerServerFunction(id, callback) {
|
|
557
|
+
provideRPC();
|
|
554
558
|
REGISTRATIONS.set(id, callback);
|
|
555
559
|
return callback;
|
|
556
560
|
}
|
|
@@ -575,6 +579,7 @@ function createServerReference({
|
|
|
575
579
|
name
|
|
576
580
|
}) {
|
|
577
581
|
if (typeof fn !== "function") throw new Error("Export from a 'use server' module must be a function");
|
|
582
|
+
provideRPC();
|
|
578
583
|
const metadata = name === undefined ? {} : {
|
|
579
584
|
name
|
|
580
585
|
};
|
|
@@ -686,7 +691,9 @@ async function foldFlightData(hook, event, headers, outcome, context = {}) {
|
|
|
686
691
|
return transformed;
|
|
687
692
|
}
|
|
688
693
|
}
|
|
689
|
-
return {
|
|
694
|
+
return outcome.value === undefined ? {
|
|
695
|
+
data
|
|
696
|
+
} : {
|
|
690
697
|
value: outcome.value,
|
|
691
698
|
data
|
|
692
699
|
};
|
|
@@ -818,6 +825,23 @@ function encodeResult(value, headers, status, codec) {
|
|
|
818
825
|
headers
|
|
819
826
|
});
|
|
820
827
|
}
|
|
828
|
+
if (value === undefined) {
|
|
829
|
+
return new Response(null, {
|
|
830
|
+
status,
|
|
831
|
+
headers
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
try {
|
|
835
|
+
if (isJSONSafe(value)) {
|
|
836
|
+
headers.set(BODY_FORMAT_HEADER, BodyFormat.Json);
|
|
837
|
+
headers.set("Content-Type", "application/json");
|
|
838
|
+
return new Response(JSON.stringify(value), {
|
|
839
|
+
status,
|
|
840
|
+
headers
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
} catch {
|
|
844
|
+
}
|
|
821
845
|
const response = serializedResponse(value, headers, codec);
|
|
822
846
|
return status === 200 ? response : new Response(response.body, {
|
|
823
847
|
status,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { fromCrossJSON, Feature, toCrossJSONStream } from 'seroval';
|
|
2
|
-
import { AbortSignalPlugin, CustomEventPlugin, DOMExceptionPlugin, EventPlugin, FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin } from 'seroval-plugins/web';
|
|
3
1
|
import { sharedConfig } from 'solid-js';
|
|
4
2
|
|
|
5
3
|
const ENVELOPE = Symbol.for("solid.ResponseEnvelope");
|
|
@@ -12,51 +10,70 @@ function isSafeError(value) {
|
|
|
12
10
|
}
|
|
13
11
|
const REVALIDATE_HEADER = "X-Revalidate";
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
FormDataPlugin, HeadersPlugin, ReadableStreamPlugin, RequestPlugin, ResponsePlugin, URLSearchParamsPlugin, URLPlugin]);
|
|
20
|
-
function resolveSerializerPlugins(customPlugins) {
|
|
21
|
-
return customPlugins ? [...customPlugins, ...DEFAULT_WEB_PLUGINS] : [...DEFAULT_WEB_PLUGINS];
|
|
22
|
-
}
|
|
23
|
-
const JSON_CODEC_DISABLED_FEATURES = Feature.RegExp;
|
|
24
|
-
const JSON_CODEC_DEPTH_LIMIT = 64;
|
|
25
|
-
function resolveCodecOptions({
|
|
26
|
-
plugins,
|
|
27
|
-
disabledFeatures,
|
|
28
|
-
depthLimit
|
|
29
|
-
} = {}) {
|
|
30
|
-
return {
|
|
31
|
-
plugins: resolveSerializerPlugins(plugins),
|
|
32
|
-
disabledFeatures: disabledFeatures === undefined ? JSON_CODEC_DISABLED_FEATURES : disabledFeatures,
|
|
33
|
-
depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
|
|
34
|
-
};
|
|
13
|
+
const SERVER_FUNCTION_METADATA = Symbol.for("solid.ServerFunctionMetadata");
|
|
14
|
+
function getServerFunctionMetadata(fn) {
|
|
15
|
+
if (typeof fn !== "function") return undefined;
|
|
16
|
+
return fn[SERVER_FUNCTION_METADATA] || undefined;
|
|
35
17
|
}
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
onDone,
|
|
39
|
-
onError,
|
|
40
|
-
...codecOptions
|
|
41
|
-
}) {
|
|
42
|
-
const resolved = resolveCodecOptions(codecOptions);
|
|
43
|
-
return toCrossJSONStream(value, {
|
|
44
|
-
onParse,
|
|
45
|
-
onDone,
|
|
46
|
-
onError,
|
|
47
|
-
...resolved,
|
|
48
|
-
disabledFeatures: resolved.disabledFeatures | serializeOnlyDisabledFeatures()
|
|
49
|
-
});
|
|
18
|
+
function isServerFunction(fn) {
|
|
19
|
+
return typeof fn === "function" && !!fn[SERVER_FUNCTION_METADATA];
|
|
50
20
|
}
|
|
51
|
-
function
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
21
|
+
function withMeta(fn, meta) {
|
|
22
|
+
const metadata = getServerFunctionMetadata(fn);
|
|
23
|
+
if (!metadata) {
|
|
24
|
+
throw new Error("withMeta expects a server function reference");
|
|
25
|
+
}
|
|
26
|
+
Object.assign(metadata, meta);
|
|
27
|
+
return fn;
|
|
28
|
+
}
|
|
29
|
+
const SERVER_FUNCTION_RPC = Symbol.for("solid.ServerFunctionRPC");
|
|
30
|
+
function provideServerFunctionRPC(rpc) {
|
|
31
|
+
globalThis[SERVER_FUNCTION_RPC] || (globalThis[SERVER_FUNCTION_RPC] = rpc);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function parseCookieHeader(header) {
|
|
35
|
+
const cookies = {};
|
|
36
|
+
if (!header) return cookies;
|
|
37
|
+
for (const part of header.split(";")) {
|
|
38
|
+
const eq = part.indexOf("=");
|
|
39
|
+
if (eq < 0) continue;
|
|
40
|
+
const name = decodeSafe(part.slice(0, eq).trim());
|
|
41
|
+
let value = part.slice(eq + 1).trim();
|
|
42
|
+
if (value.length > 1 && value[0] === '"' && value[value.length - 1] === '"') {
|
|
43
|
+
value = value.slice(1, -1);
|
|
44
|
+
}
|
|
45
|
+
cookies[name] = decodeSafe(value);
|
|
46
|
+
}
|
|
47
|
+
return cookies;
|
|
48
|
+
}
|
|
49
|
+
function decodeSafe(text) {
|
|
50
|
+
try {
|
|
51
|
+
return decodeURIComponent(text);
|
|
52
|
+
} catch {
|
|
53
|
+
return text;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function serializeCookie(name, value, options = {}) {
|
|
57
|
+
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
58
|
+
cookie += `; Path=${options.path === undefined ? "/" : options.path}`;
|
|
59
|
+
if (options.domain) cookie += `; Domain=${options.domain}`;
|
|
60
|
+
if (options.maxAge !== undefined) cookie += `; Max-Age=${Math.trunc(options.maxAge)}`;
|
|
61
|
+
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
62
|
+
if (options.httpOnly) cookie += "; HttpOnly";
|
|
63
|
+
if (options.secure) cookie += "; Secure";
|
|
64
|
+
if (options.sameSite) {
|
|
65
|
+
const sameSite = options.sameSite.toLowerCase();
|
|
66
|
+
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
67
|
+
}
|
|
68
|
+
return cookie;
|
|
69
|
+
}
|
|
70
|
+
const FLASH_COOKIE = "flash";
|
|
71
|
+
const FLASH_MATCHER = new RegExp(`(?:^|;\\s*)${FLASH_COOKIE}=([^;]+)`);
|
|
72
|
+
function hasFlashCookie(cookieHeader) {
|
|
73
|
+
return !!cookieHeader && FLASH_MATCHER.test(cookieHeader);
|
|
74
|
+
}
|
|
75
|
+
function clearFlashCookie() {
|
|
76
|
+
return `${FLASH_COOKIE}=; Max-Age=0; Path=/`;
|
|
60
77
|
}
|
|
61
78
|
|
|
62
79
|
const codecConfig = {
|
|
@@ -72,22 +89,6 @@ function subscribeFlightData(consumer) {
|
|
|
72
89
|
return () => {
|
|
73
90
|
};
|
|
74
91
|
}
|
|
75
|
-
const SERVER_FUNCTION_METADATA = Symbol.for("solid.ServerFunctionMetadata");
|
|
76
|
-
function getServerFunctionMetadata(fn) {
|
|
77
|
-
if (typeof fn !== "function") return undefined;
|
|
78
|
-
return fn[SERVER_FUNCTION_METADATA] || undefined;
|
|
79
|
-
}
|
|
80
|
-
function isServerFunction(fn) {
|
|
81
|
-
return typeof fn === "function" && !!fn[SERVER_FUNCTION_METADATA];
|
|
82
|
-
}
|
|
83
|
-
function withMeta(fn, meta) {
|
|
84
|
-
const metadata = getServerFunctionMetadata(fn);
|
|
85
|
-
if (!metadata) {
|
|
86
|
-
throw new Error("withMeta expects a server function reference");
|
|
87
|
-
}
|
|
88
|
-
Object.assign(metadata, meta);
|
|
89
|
-
return fn;
|
|
90
|
-
}
|
|
91
92
|
const FUNCTION_HEADER = "X-Server-Function-Id";
|
|
92
93
|
const ERROR_HEADER = "X-Server-Function-Error";
|
|
93
94
|
const ERROR_HEADER_MARKER = "=?1?";
|
|
@@ -118,14 +119,6 @@ const INSTANCE_HEADER = "X-Server-Function-Instance";
|
|
|
118
119
|
const BODY_FORMAT_HEADER = "X-Server-Function-Format";
|
|
119
120
|
const SINGLE_FLIGHT_HEADER = "X-Single-Flight";
|
|
120
121
|
const FILE_FORM_KEY = "__server_function_file__";
|
|
121
|
-
const FLASH_COOKIE = "flash";
|
|
122
|
-
const FLASH_MATCHER = new RegExp(`(?:^|;\\s*)${FLASH_COOKIE}=([^;]+)`);
|
|
123
|
-
function hasFlashCookie(cookieHeader) {
|
|
124
|
-
return !!cookieHeader && FLASH_MATCHER.test(cookieHeader);
|
|
125
|
-
}
|
|
126
|
-
function clearFlashCookie() {
|
|
127
|
-
return `${FLASH_COOKIE}=; Max-Age=0; Path=/`;
|
|
128
|
-
}
|
|
129
122
|
const BodyFormat = {
|
|
130
123
|
Serialized: "0",
|
|
131
124
|
String: "1",
|
|
@@ -137,6 +130,38 @@ const BodyFormat = {
|
|
|
137
130
|
Uint8Array: "7",
|
|
138
131
|
Json: "8"
|
|
139
132
|
};
|
|
133
|
+
const JSON_SAFE_DEPTH_LIMIT = 10000;
|
|
134
|
+
const EXIT = {};
|
|
135
|
+
function isJSONSafe(value) {
|
|
136
|
+
const stack = [value];
|
|
137
|
+
const ancestors = new Set();
|
|
138
|
+
while (stack.length) {
|
|
139
|
+
const v = stack.pop();
|
|
140
|
+
if (v === EXIT) {
|
|
141
|
+
ancestors.delete(stack.pop());
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (v === null) continue;
|
|
145
|
+
const t = typeof v;
|
|
146
|
+
if (t === "string" || t === "boolean") continue;
|
|
147
|
+
if (t === "number") {
|
|
148
|
+
if (!Number.isFinite(v)) return false;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (t !== "object") return false;
|
|
152
|
+
if (ancestors.has(v) || ancestors.size >= JSON_SAFE_DEPTH_LIMIT) return false;
|
|
153
|
+
ancestors.add(v);
|
|
154
|
+
stack.push(v, EXIT);
|
|
155
|
+
if (Array.isArray(v)) {
|
|
156
|
+
for (let i = 0; i < v.length; i++) stack.push(v[i]);
|
|
157
|
+
} else {
|
|
158
|
+
const proto = Object.getPrototypeOf(v);
|
|
159
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
160
|
+
for (const k in v) stack.push(v[k]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
140
165
|
function getHeadersAndBody(body) {
|
|
141
166
|
switch (true) {
|
|
142
167
|
case typeof body === "string":
|
|
@@ -296,7 +321,10 @@ class ChunkReader {
|
|
|
296
321
|
}
|
|
297
322
|
function serializeStream(value, codecOptions) {
|
|
298
323
|
return new ReadableStream({
|
|
299
|
-
start(controller) {
|
|
324
|
+
async start(controller) {
|
|
325
|
+
const {
|
|
326
|
+
serializeJSON
|
|
327
|
+
} = await import('@solidjs/web/serialization');
|
|
300
328
|
serializeJSON(value, {
|
|
301
329
|
...codecOptions,
|
|
302
330
|
onParse(node) {
|
|
@@ -319,6 +347,9 @@ async function deserializeStream(source, codecOptions) {
|
|
|
319
347
|
const reader = new ChunkReader(source.body);
|
|
320
348
|
const result = await reader.next();
|
|
321
349
|
if (!result.done) {
|
|
350
|
+
const {
|
|
351
|
+
createJSONDeserializer
|
|
352
|
+
} = await import('@solidjs/web/serialization/decode');
|
|
322
353
|
const deserializeChunk = createJSONDeserializer(codecOptions);
|
|
323
354
|
function interpretChunk(chunk) {
|
|
324
355
|
return deserializeChunk(JSON.parse(chunk));
|
|
@@ -348,43 +379,6 @@ async function decodeResponsePayload(response, codecOptions) {
|
|
|
348
379
|
};
|
|
349
380
|
}
|
|
350
381
|
|
|
351
|
-
function parseCookieHeader(header) {
|
|
352
|
-
const cookies = {};
|
|
353
|
-
if (!header) return cookies;
|
|
354
|
-
for (const part of header.split(";")) {
|
|
355
|
-
const eq = part.indexOf("=");
|
|
356
|
-
if (eq < 0) continue;
|
|
357
|
-
const name = decodeSafe(part.slice(0, eq).trim());
|
|
358
|
-
let value = part.slice(eq + 1).trim();
|
|
359
|
-
if (value.length > 1 && value[0] === '"' && value[value.length - 1] === '"') {
|
|
360
|
-
value = value.slice(1, -1);
|
|
361
|
-
}
|
|
362
|
-
cookies[name] = decodeSafe(value);
|
|
363
|
-
}
|
|
364
|
-
return cookies;
|
|
365
|
-
}
|
|
366
|
-
function decodeSafe(text) {
|
|
367
|
-
try {
|
|
368
|
-
return decodeURIComponent(text);
|
|
369
|
-
} catch {
|
|
370
|
-
return text;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
function serializeCookie(name, value, options = {}) {
|
|
374
|
-
let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
375
|
-
cookie += `; Path=${options.path === undefined ? "/" : options.path}`;
|
|
376
|
-
if (options.domain) cookie += `; Domain=${options.domain}`;
|
|
377
|
-
if (options.maxAge !== undefined) cookie += `; Max-Age=${Math.trunc(options.maxAge)}`;
|
|
378
|
-
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
379
|
-
if (options.httpOnly) cookie += "; HttpOnly";
|
|
380
|
-
if (options.secure) cookie += "; Secure";
|
|
381
|
-
if (options.sameSite) {
|
|
382
|
-
const sameSite = options.sameSite.toLowerCase();
|
|
383
|
-
cookie += `; SameSite=${sameSite === "none" ? "None" : sameSite === "strict" ? "Strict" : "Lax"}`;
|
|
384
|
-
}
|
|
385
|
-
return cookie;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
382
|
const RequestContext = Symbol.for("solid.RequestContext");
|
|
389
383
|
function getRequestEvent() {
|
|
390
384
|
return globalThis[RequestContext] ? globalThis[RequestContext].getStore() || sharedConfig.context && sharedConfig.context.event || console.warn("RequestEvent is missing. This is most likely due to accessing `getRequestEvent` non-managed async scope in a partially polyfilled environment. Try moving it above all `await` calls.") : undefined;
|
|
@@ -548,7 +542,17 @@ function provideEvent(event, fn) {
|
|
|
548
542
|
const REGISTRATIONS = new Map();
|
|
549
543
|
const METHODS = new Map();
|
|
550
544
|
const INVOCATIONS = new WeakMap();
|
|
545
|
+
let rpcProvided = false;
|
|
546
|
+
function provideRPC() {
|
|
547
|
+
if (rpcProvided) return;
|
|
548
|
+
rpcProvided = true;
|
|
549
|
+
provideServerFunctionRPC({
|
|
550
|
+
GET,
|
|
551
|
+
decodeResponse
|
|
552
|
+
});
|
|
553
|
+
}
|
|
551
554
|
function registerServerFunction(id, callback) {
|
|
555
|
+
provideRPC();
|
|
552
556
|
REGISTRATIONS.set(id, callback);
|
|
553
557
|
return callback;
|
|
554
558
|
}
|
|
@@ -573,6 +577,7 @@ function createServerReference({
|
|
|
573
577
|
name
|
|
574
578
|
}) {
|
|
575
579
|
if (typeof fn !== "function") throw new Error("Export from a 'use server' module must be a function");
|
|
580
|
+
provideRPC();
|
|
576
581
|
const metadata = name === undefined ? {} : {
|
|
577
582
|
name
|
|
578
583
|
};
|
|
@@ -684,7 +689,9 @@ async function foldFlightData(hook, event, headers, outcome, context = {}) {
|
|
|
684
689
|
return transformed;
|
|
685
690
|
}
|
|
686
691
|
}
|
|
687
|
-
return {
|
|
692
|
+
return outcome.value === undefined ? {
|
|
693
|
+
data
|
|
694
|
+
} : {
|
|
688
695
|
value: outcome.value,
|
|
689
696
|
data
|
|
690
697
|
};
|
|
@@ -816,6 +823,23 @@ function encodeResult(value, headers, status, codec) {
|
|
|
816
823
|
headers
|
|
817
824
|
});
|
|
818
825
|
}
|
|
826
|
+
if (value === undefined) {
|
|
827
|
+
return new Response(null, {
|
|
828
|
+
status,
|
|
829
|
+
headers
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
try {
|
|
833
|
+
if (isJSONSafe(value)) {
|
|
834
|
+
headers.set(BODY_FORMAT_HEADER, BodyFormat.Json);
|
|
835
|
+
headers.set("Content-Type", "application/json");
|
|
836
|
+
return new Response(JSON.stringify(value), {
|
|
837
|
+
status,
|
|
838
|
+
headers
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
} catch {
|
|
842
|
+
}
|
|
819
843
|
const response = serializedResponse(value, headers, codec);
|
|
820
844
|
return status === 200 ? response : new Response(response.body, {
|
|
821
845
|
status,
|