@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.
Files changed (52) hide show
  1. package/dist/dev.cjs +51 -15
  2. package/dist/dev.js +47 -16
  3. package/dist/server.cjs +710 -71
  4. package/dist/server.js +707 -74
  5. package/dist/web.cjs +51 -15
  6. package/dist/web.js +47 -16
  7. package/frames/dist/client.cjs +181 -64
  8. package/frames/dist/client.dev.cjs +185 -64
  9. package/frames/dist/client.dev.js +183 -62
  10. package/frames/dist/client.js +179 -62
  11. package/frames/dist/server.cjs +969 -133
  12. package/frames/dist/server.js +971 -135
  13. package/package.json +17 -6
  14. package/serialization/decode/package.json +20 -0
  15. package/serialization/dist/decode.cjs +110 -0
  16. package/serialization/dist/decode.js +104 -0
  17. package/serialization/dist/serialization.cjs +98 -43
  18. package/serialization/dist/serialization.js +99 -44
  19. package/serialization/types/index.d.ts +18 -160
  20. package/serialization/types/serializer-decode.d.ts +182 -0
  21. package/serialization/types-cjs/index.d.cts +18 -160
  22. package/serialization/types-cjs/serializer-decode.d.cts +182 -0
  23. package/server-functions/dist/client.cjs +101 -105
  24. package/server-functions/dist/client.js +101 -105
  25. package/server-functions/dist/server.cjs +131 -107
  26. package/server-functions/dist/server.dev.cjs +131 -107
  27. package/server-functions/dist/server.dev.js +132 -108
  28. package/server-functions/dist/server.js +132 -108
  29. package/types/client.d.ts +23 -1
  30. package/types/cookies.d.ts +93 -0
  31. package/types/core.d.ts +1 -1
  32. package/types/frames/frame-client.d.ts +26 -0
  33. package/types/frames/frame-transport.d.ts +1 -1
  34. package/types/frames/serializer.d.ts +18 -160
  35. package/types/serializer-decode.d.ts +182 -0
  36. package/types/serializer.d.ts +18 -160
  37. package/types/server-functions/client.d.ts +1 -1
  38. package/types/server-functions/server.d.ts +1 -1
  39. package/types/server-functions/shared.d.ts +57 -1
  40. package/types/server.d.ts +21 -1
  41. package/types-cjs/client.d.cts +23 -1
  42. package/types-cjs/cookies.d.cts +93 -0
  43. package/types-cjs/core.d.cts +1 -1
  44. package/types-cjs/frames/frame-client.d.cts +26 -0
  45. package/types-cjs/frames/frame-transport.d.cts +1 -1
  46. package/types-cjs/frames/serializer.d.cts +18 -160
  47. package/types-cjs/serializer-decode.d.cts +182 -0
  48. package/types-cjs/serializer.d.cts +18 -160
  49. package/types-cjs/server-functions/client.d.cts +1 -1
  50. package/types-cjs/server-functions/server.d.cts +1 -1
  51. package/types-cjs/server-functions/shared.d.cts +57 -1
  52. 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
- seroval.Feature.AggregateError | seroval.Feature.BigIntTypedArray;
18
- const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : seroval.Feature.ErrorPrototypeStack;
19
- const DEFAULT_WEB_PLUGINS = Object.freeze([web.AbortSignalPlugin,
20
- web.CustomEventPlugin, web.DOMExceptionPlugin, web.EventPlugin,
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
- const JSON_CODEC_DISABLED_FEATURES = seroval.Feature.RegExp;
26
- const JSON_CODEC_DEPTH_LIMIT = 64;
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 serializeJSON(value, {
39
- onParse,
40
- onDone,
41
- onError,
42
- ...codecOptions
43
- }) {
44
- const resolved = resolveCodecOptions(codecOptions);
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
- function createJSONDeserializer(options) {
54
- const refs = new Map();
55
- const resolved = resolveCodecOptions(options);
56
- return function deserializeJSONChunk(node) {
57
- return seroval.fromCrossJSON(node, {
58
- refs,
59
- ...resolved
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
- Feature.AggregateError | Feature.BigIntTypedArray;
16
- const serializeOnlyDisabledFeatures = () => process.env.NODE_ENV === "development" ? 0 : Feature.ErrorPrototypeStack;
17
- const DEFAULT_WEB_PLUGINS = Object.freeze([AbortSignalPlugin,
18
- CustomEventPlugin, DOMExceptionPlugin, EventPlugin,
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 serializeJSON(value, {
37
- onParse,
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 createJSONDeserializer(options) {
52
- const refs = new Map();
53
- const resolved = resolveCodecOptions(options);
54
- return function deserializeJSONChunk(node) {
55
- return fromCrossJSON(node, {
56
- refs,
57
- ...resolved
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,