Skip to content

Commit

Permalink
WebSocketsPlugin: polyfill structureClone in Safari < 15
Browse files Browse the repository at this point in the history
  • Loading branch information
larabr committed Oct 23, 2024
1 parent aadcbea commit a876456
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/slimy-moles-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@web/dev-server-core': patch
---

WebSocketsPlugin: polyfill `structuredClone` to support older browsers
10 changes: 9 additions & 1 deletion packages/dev-server-core/src/web-sockets/webSocketsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ export function webSocketsPlugin(): Plugin {
// this code is inlined because TS compiles to CJS but we need this to be ESM
return `
/**
* StructuredJSON copied as-is from https://github.com/ungap/structured-clone/blob/v1.2.0/structured-json.js
*/
var StructuredJSON=function(e){"use strict";const r="object"==typeof self?self:globalThis,t=e=>((e,t)=>{const s=(r,t)=>(e.set(t,r),r),n=c=>{if(e.has(c))return e.get(c);const[o,a]=t[c];switch(o){case 0:case-1:return s(a,c);case 1:{const e=s([],c);for(const r of a)e.push(n(r));return e}case 2:{const e=s({},c);for(const[r,t]of a)e[n(r)]=n(t);return e}case 3:return s(new Date(a),c);case 4:{const{source:e,flags:r}=a;return s(new RegExp(e,r),c)}case 5:{const e=s(new Map,c);for(const[r,t]of a)e.set(n(r),n(t));return e}case 6:{const e=s(new Set,c);for(const r of a)e.add(n(r));return e}case 7:{const{name:e,message:t}=a;return s(new r[e](t),c)}case 8:return s(BigInt(a),c);case"BigInt":return s(Object(BigInt(a)),c)}return s(new r[o](a),c)};return n})(new Map,e)(0),s="",{toString:n}={},{keys:c}=Object,o=e=>{const r=typeof e;if("object"!==r||!e)return[0,r];const t=n.call(e).slice(8,-1);switch(t){case"Array":return[1,s];case"Object":return[2,s];case"Date":return[3,s];case"RegExp":return[4,s];case"Map":return[5,s];case"Set":return[6,s]}return t.includes("Array")?[1,t]:t.includes("Error")?[7,t]:[2,t]},a=([e,r])=>0===e&&("function"===r||"symbol"===r),u=(e,{json:r,lossy:t}={})=>{const s=[];return((e,r,t,s)=>{const n=(e,r)=>{const n=s.push(e)-1;return t.set(r,n),n},u=s=>{if(t.has(s))return t.get(s);let[i,f]=o(s);switch(i){case 0:{let r=s;switch(f){case"bigint":i=8,r=s.toString();break;case"function":case"symbol":if(e)throw new TypeError("unable to serialize "+f);r=null;break;case"undefined":return n([-1],s)}return n([i,r],s)}case 1:{if(f)return n([f,[...s]],s);const e=[],r=n([i,e],s);for(const r of s)e.push(u(r));return r}case 2:{if(f)switch(f){case"BigInt":return n([f,s.toString()],s);case"Boolean":case"Number":case"String":return n([f,s.valueOf()],s)}if(r&&"toJSON"in s)return u(s.toJSON());const t=[],l=n([i,t],s);for(const r of c(s))!e&&a(o(s[r]))||t.push([u(r),u(s[r])]);return l}case 3:return n([i,s.toISOString()],s);case 4:{const{source:e,flags:r}=s;return n([i,{source:e,flags:r}],s)}case 5:{const r=[],t=n([i,r],s);for(const[t,n]of s)(e||!a(o(t))&&!a(o(n)))&&r.push([u(t),u(n)]);return t}case 6:{const r=[],t=n([i,r],s);for(const t of s)!e&&a(o(t))||r.push(u(t));return t}}const{message:l}=s;return n([i,{name:f,message:l}],s)};return u})(!(r||t),!!r,new Map,s)(e),s},{parse:i,stringify:f}=JSON,l={json:!0,lossy:!0};return e.parse=e=>t(i(e)),e.stringify=e=>f(u(e,l)),e}({});
// Not the exact same behaviour as structuredClone, but good enough for the basic cases.
const structuredClonePolyfill = (obj) => StructuredJSON.parse(StructuredJSON.stringify(obj));
/**
* Code at this indent adapted from fast-safe-stringify by David Mark Clements
* @license MIT
Expand All @@ -40,7 +48,7 @@ export function webSocketsPlugin(): Plugin {
}
export function stable (obj, replacer, spacer) {
var target = structuredClone(obj)
var target = ('structuredClone' in globalThis) ? structuredClone(obj) : structuredClonePolyfill(obj)
var tmp = deterministicDecirc(target, '', [], undefined) || target
var res
if (replacerStack.length === 0) {
Expand Down

0 comments on commit a876456

Please sign in to comment.