@solidjs/web 2.0.0-rc.5 → 2.0.0-rc.6

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.
@@ -99,6 +99,8 @@ const ContainerTracePlugin = {
99
99
  }
100
100
  };
101
101
 
102
+ const COMPOSED_BODY_FRAMING = /*#__PURE__*/new Set(["content-length", "content-encoding", "transfer-encoding"]);
103
+
102
104
  setContainerTraceStreamMint(iterable => {
103
105
  const stream = createStream();
104
106
  (async () => {
@@ -2789,8 +2791,55 @@ function resolveSSRSync(node) {
2789
2791
  if (!res.h.length) return res.t[0];
2790
2792
  throw new Error("This value cannot be rendered synchronously. Are you missing a boundary?");
2791
2793
  }
2792
- /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, REDIRECT_HEADER, "Location"].map(header => header.toLowerCase()));
2794
+ /*#__PURE__*/new Set([ERROR_HEADER, BODY_FORMAT_HEADER, SINGLE_FLIGHT_HEADER, REVALIDATE_HEADER, REDIRECT_HEADER, "Location",
2795
+ ...COMPOSED_BODY_FRAMING].map(header => header.toLowerCase()));
2793
2796
 
2797
+ function scopeDeferredResult(value, scope) {
2798
+ if (value === null || typeof value !== "object" && typeof value !== "function") return value;
2799
+ const promised = scope(() => nativePromise(value));
2800
+ if (promised) {
2801
+ return promised.then(result => scope(() => scopeDeferredResult(result, scope)));
2802
+ }
2803
+ if (typeof ReadableStream !== "undefined" && value instanceof ReadableStream) {
2804
+ let reader;
2805
+ return new ReadableStream({
2806
+ async pull(controller) {
2807
+ try {
2808
+ const step = await scope(() => {
2809
+ if (!reader) reader = value.getReader();
2810
+ return reader.read();
2811
+ });
2812
+ if (step.done) controller.close();else controller.enqueue(step.value);
2813
+ } catch (error) {
2814
+ controller.error(error);
2815
+ }
2816
+ },
2817
+ cancel(reason) {
2818
+ return scope(() => reader ? reader.cancel(reason) : value.cancel(reason));
2819
+ }
2820
+ }, {
2821
+ highWaterMark: 0
2822
+ });
2823
+ }
2824
+ const scopedIterator = symbol => ({
2825
+ [symbol]() {
2826
+ const iterator = scope(() => value[symbol]());
2827
+ return new Proxy(iterator, {
2828
+ get(target, property) {
2829
+ const member = Reflect.get(target, property, target);
2830
+ return typeof member === "function" && (property === "next" || property === "return" || property === "throw") ? (...args) => scope(() => member.apply(target, args)) : member;
2831
+ }
2832
+ });
2833
+ }
2834
+ });
2835
+ if (typeof value[Symbol.asyncIterator] === "function") {
2836
+ return scopedIterator(Symbol.asyncIterator);
2837
+ }
2838
+ if (typeof value[Symbol.iterator] === "function" && !Array.isArray(value) && !(value instanceof Map) && !(value instanceof Set) && !ArrayBuffer.isView(value)) {
2839
+ return scopedIterator(Symbol.iterator);
2840
+ }
2841
+ return value;
2842
+ }
2794
2843
  const INVOCATIONS = new WeakMap();
2795
2844
  function getEventServerFunctionInvocation(event) {
2796
2845
  return event && INVOCATIONS.get(event);
@@ -2855,14 +2904,11 @@ function guardFailures(value, state) {
2855
2904
  top.next.add(guarded);
2856
2905
  if (guarded !== original) top.changed = true;
2857
2906
  } else if (guarded !== original || top.accessorRead === i) {
2858
- Object.defineProperty(top.next, items[i], top.accessorRead === i ? {
2859
- enumerable: true,
2860
- configurable: true,
2907
+ Object.defineProperty(top.next, items[i], {
2908
+ value: guarded,
2861
2909
  writable: true,
2862
- value: guarded
2863
- } : {
2864
- ...top.descriptors[items[i]],
2865
- value: guarded
2910
+ configurable: true,
2911
+ enumerable: top.descriptors[items[i]].enumerable
2866
2912
  });
2867
2913
  top.changed = true;
2868
2914
  }
@@ -2897,6 +2943,9 @@ class Frame {
2897
2943
  this.pendingKey = undefined;
2898
2944
  }
2899
2945
  }
2946
+ function guardOperation(state, run) {
2947
+ return state.scope ? state.scope(run) : run();
2948
+ }
2900
2949
  function enterGuard(value, state) {
2901
2950
  if (value === null || typeof value !== "object") return value;
2902
2951
  if (state.seen.has(value)) {
@@ -2911,7 +2960,7 @@ function enterGuard(value, state) {
2911
2960
  if (finished) return;
2912
2961
  finished = true;
2913
2962
  try {
2914
- const cancelled = reader ? reader.cancel() : value.cancel();
2963
+ const cancelled = guardOperation(state, () => reader ? reader.cancel() : value.cancel());
2915
2964
  if (cancelled && typeof cancelled.then === "function") cancelled.then(undefined, () => {});
2916
2965
  } catch {}
2917
2966
  };
@@ -2923,19 +2972,19 @@ function enterGuard(value, state) {
2923
2972
  controller.close();
2924
2973
  return;
2925
2974
  }
2926
- if (!reader) reader = value.getReader();
2975
+ if (!reader) reader = guardOperation(state, () => value.getReader());
2927
2976
  const {
2928
2977
  done,
2929
2978
  value: chunk
2930
- } = await reader.read();
2931
- done ? controller.close() : controller.enqueue(guardFailures(chunk, state));
2979
+ } = await guardOperation(state, () => reader.read());
2980
+ done ? controller.close() : controller.enqueue(guardOperation(state, () => guardFailures(chunk, state)));
2932
2981
  } catch (error) {
2933
- controller.error(sanitizeServerError(error));
2982
+ controller.error(guardOperation(state, () => sanitizeServerError(error)));
2934
2983
  }
2935
2984
  },
2936
2985
  cancel(reason) {
2937
2986
  finished = true;
2938
- return reader ? reader.cancel(reason) : value.cancel(reason);
2987
+ return guardOperation(state, () => reader ? reader.cancel(reason) : value.cancel(reason));
2939
2988
  }
2940
2989
  });
2941
2990
  if (gate) gate.onOpen(close);
@@ -2943,9 +2992,10 @@ function enterGuard(value, state) {
2943
2992
  return guardedStream;
2944
2993
  }
2945
2994
  if (typeof value.then === "function") {
2946
- const guardedPromise = Promise.resolve(value).then(resolved => guardFailures(resolved, state), error => {
2947
- throw sanitizeServerError(error);
2995
+ const guardedPromise = Promise.resolve(value).then(resolved => guardOperation(state, () => guardFailures(resolved, state)), error => {
2996
+ throw guardOperation(state, () => sanitizeServerError(error));
2948
2997
  });
2998
+ guardedPromise.catch(() => {});
2949
2999
  state.seen.set(value, guardedPromise);
2950
3000
  return guardedPromise;
2951
3001
  }
@@ -2954,13 +3004,13 @@ function enterGuard(value, state) {
2954
3004
  const gate = state.gate;
2955
3005
  const guardedIterable = {
2956
3006
  [Symbol.asyncIterator]() {
2957
- const iterator = source[Symbol.asyncIterator]();
3007
+ const iterator = guardOperation(state, () => source[Symbol.asyncIterator]());
2958
3008
  let finished = false;
2959
3009
  const close = () => {
2960
3010
  if (finished) return;
2961
3011
  finished = true;
2962
3012
  try {
2963
- const returned = iterator.return && iterator.return();
3013
+ const returned = iterator.return && guardOperation(state, () => iterator.return());
2964
3014
  if (returned && typeof returned.then === "function") returned.then(undefined, () => {});
2965
3015
  } catch {}
2966
3016
  };
@@ -2968,17 +3018,17 @@ function enterGuard(value, state) {
2968
3018
  const step = () => finished ? Promise.resolve({
2969
3019
  done: true,
2970
3020
  value: undefined
2971
- }) : iterator.next().then(step => {
3021
+ }) : guardOperation(state, () => iterator.next()).then(step => {
2972
3022
  if (step.done) {
2973
3023
  finished = true;
2974
3024
  return step;
2975
3025
  }
2976
3026
  return {
2977
3027
  done: false,
2978
- value: guardFailures(step.value, state)
3028
+ value: guardOperation(state, () => guardFailures(step.value, state))
2979
3029
  };
2980
3030
  }, error => {
2981
- throw sanitizeServerError(error);
3031
+ throw guardOperation(state, () => sanitizeServerError(error));
2982
3032
  });
2983
3033
  return {
2984
3034
  next: () => finished || !gate || gate.wantsMore() ? step() : gate.awaitDemand().then(step),
@@ -2995,6 +3045,11 @@ function enterGuard(value, state) {
2995
3045
  state.seen.set(value, guardedIterable);
2996
3046
  return guardedIterable;
2997
3047
  }
3048
+ if (state.scope && typeof value[Symbol.iterator] === "function" && !Array.isArray(value) && !(value instanceof Map) && !(value instanceof Set) && !ArrayBuffer.isView(value)) {
3049
+ const scopedIterable = scopeDeferredResult(value, state.scope);
3050
+ state.seen.set(value, scopedIterable);
3051
+ return scopedIterable;
3052
+ }
2998
3053
  if (Array.isArray(value)) {
2999
3054
  const next = value.slice();
3000
3055
  state.seen.set(value, next);
@@ -3018,9 +3073,13 @@ function enterGuard(value, state) {
3018
3073
  return value;
3019
3074
  }
3020
3075
  const descriptors = Object.getOwnPropertyDescriptors(value);
3076
+ for (const key of Object.keys(descriptors)) {
3077
+ descriptors[key].configurable = true;
3078
+ if ("value" in descriptors[key]) descriptors[key].writable = true;
3079
+ }
3021
3080
  const next = Object.create(prototype, descriptors);
3022
3081
  state.seen.set(value, next);
3023
- return new Frame(OBJECT, value, next, Object.keys(descriptors), descriptors);
3082
+ return new Frame(OBJECT, value, next, Object.keys(value), descriptors);
3024
3083
  }
3025
3084
  function keepGuarded(value, next, changed, state) {
3026
3085
  if (changed || state.cyclic.has(value)) return next;
@@ -3032,6 +3091,12 @@ function sanitizeServerError(value) {
3032
3091
  if (isSafeError(value)) return value;
3033
3092
  return new Error(GENERIC_SERVER_ERROR_MESSAGE);
3034
3093
  }
3094
+ function nativePromise(value) {
3095
+ if (value instanceof Promise) return value;
3096
+ try {
3097
+ if (Object.prototype.toString.call(value) === "[object Promise]") return Promise.prototype.then.call(value, value => value);
3098
+ } catch {}
3099
+ }
3035
3100
 
3036
3101
  const FRAME_STREAM_HEADER = "X-Frame-Stream";
3037
3102
  function isFrameStreamResponse(response) {
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-rc.5",
4
+ "version": "2.0.0-rc.6",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -398,7 +398,7 @@
398
398
  "seroval-plugins": "~1.5.4"
399
399
  },
400
400
  "peerDependencies": {
401
- "solid-js": "^2.0.0-rc.5"
401
+ "solid-js": "^2.0.0-rc.6"
402
402
  },
403
403
  "devDependencies": {
404
404
  "@codspeed/vitest-plugin": "^5.4.0",
@@ -635,10 +635,19 @@ async function createRequest(base, id, instance, options, meta) {
635
635
  headers
636
636
  };
637
637
  if (config.prepareRequest) {
638
- init = (await config.prepareRequest(init, {
638
+ const prepared = await config.prepareRequest(init, {
639
639
  id,
640
640
  meta
641
- })) || init;
641
+ });
642
+ if (prepared && prepared !== init) {
643
+ if (typeof prepared !== "object") {
644
+ throw new Error("prepareRequest must return (or mutate and return) the RequestInit it received; " + `it returned a ${typeof prepared}. Spread the init: ` + "init => ({ ...init, headers: { ...init.headers, ... } })");
645
+ }
646
+ if (!new Headers(prepared.headers).has(INSTANCE_HEADER)) {
647
+ throw new Error("prepareRequest returned an init without the transport headers " + `(${INSTANCE_HEADER}), which would send the call without its payload or ` + "protocol. Spread the init it received: " + "init => ({ ...init, headers: { ...init.headers, ... } })");
648
+ }
649
+ }
650
+ init = prepared || init;
642
651
  }
643
652
  const send = config.fetch || fetch;
644
653
  if (CALL_OBSERVERS.size === 0) return send(base, init);
@@ -755,6 +764,9 @@ async function fetchServerFunction(base, id, options, args, meta, callArgs = arg
755
764
  if (response.headers.has(REDIRECT_HEADER) || response.headers.has(REVALIDATE_HEADER) || response.headers.has(SINGLE_FLIGHT_HEADER) || response.status >= 300 && response.status < 400 && response.status !== 304) {
756
765
  return response;
757
766
  }
767
+ if (response.status < 300 && !response.headers.has(BODY_FORMAT_HEADER) && !response.headers.has("X-Content-Raw")) {
768
+ throw serverFunctionFailure(response, new Error(`Server function response carries no recognized encoding (status ${response.status}` + `${response.headers.get("Content-Type") ? `, content-type ${response.headers.get("Content-Type")}` : ""}): answered by something other than the server function runtime`));
769
+ }
758
770
  const result = await decodeResponse(response.clone());
759
771
  if (failed) {
760
772
  throw serverFunctionFailure(response, result);
@@ -633,10 +633,19 @@ async function createRequest(base, id, instance, options, meta) {
633
633
  headers
634
634
  };
635
635
  if (config.prepareRequest) {
636
- init = (await config.prepareRequest(init, {
636
+ const prepared = await config.prepareRequest(init, {
637
637
  id,
638
638
  meta
639
- })) || init;
639
+ });
640
+ if (prepared && prepared !== init) {
641
+ if (typeof prepared !== "object") {
642
+ throw new Error("prepareRequest must return (or mutate and return) the RequestInit it received; " + `it returned a ${typeof prepared}. Spread the init: ` + "init => ({ ...init, headers: { ...init.headers, ... } })");
643
+ }
644
+ if (!new Headers(prepared.headers).has(INSTANCE_HEADER)) {
645
+ throw new Error("prepareRequest returned an init without the transport headers " + `(${INSTANCE_HEADER}), which would send the call without its payload or ` + "protocol. Spread the init it received: " + "init => ({ ...init, headers: { ...init.headers, ... } })");
646
+ }
647
+ }
648
+ init = prepared || init;
640
649
  }
641
650
  const send = config.fetch || fetch;
642
651
  if (CALL_OBSERVERS.size === 0) return send(base, init);
@@ -753,6 +762,9 @@ async function fetchServerFunction(base, id, options, args, meta, callArgs = arg
753
762
  if (response.headers.has(REDIRECT_HEADER) || response.headers.has(REVALIDATE_HEADER) || response.headers.has(SINGLE_FLIGHT_HEADER) || response.status >= 300 && response.status < 400 && response.status !== 304) {
754
763
  return response;
755
764
  }
765
+ if (response.status < 300 && !response.headers.has(BODY_FORMAT_HEADER) && !response.headers.has("X-Content-Raw")) {
766
+ throw serverFunctionFailure(response, new Error(`Server function response carries no recognized encoding (status ${response.status}` + `${response.headers.get("Content-Type") ? `, content-type ${response.headers.get("Content-Type")}` : ""}): answered by something other than the server function runtime`));
767
+ }
756
768
  const result = await decodeResponse(response.clone());
757
769
  if (failed) {
758
770
  throw serverFunctionFailure(response, result);