wawesome 0.18.1 → 0.20.0
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/{guest-parity-Df4rlLDW.mjs → guest-parity-W61MH7Fb.mjs} +131 -8
- package/dist/guest-parity.d.mts +2 -0
- package/dist/guest-parity.mjs +1 -1
- package/dist/guest-surface-D5X-IMAN.mjs +208 -0
- package/dist/index.mjs +741 -346
- package/dist/vite.mjs +1 -1
- package/dist/vitest-setup.mjs +1 -1
- package/package.json +1 -1
- package/dist/guest-surface-CXON0L5V.mjs +0 -107
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as unsupportedGlobals, i as shimmedGlobals, n as methodRemedy, r as polyfilledGlobals, t as declaredMethods } from "./guest-surface-
|
|
1
|
+
import { a as unsupportedGlobals, i as shimmedGlobals, n as methodRemedy, r as polyfilledGlobals, t as declaredMethods } from "./guest-surface-D5X-IMAN.mjs";
|
|
2
2
|
//#region ../../server/guest-surface/message-channel.js
|
|
3
3
|
const ENTANGLED = Symbol("entangled");
|
|
4
4
|
const QUEUE = Symbol("queue");
|
|
@@ -6,6 +6,39 @@ const STARTED = Symbol("started");
|
|
|
6
6
|
const CLOSED = Symbol("closed");
|
|
7
7
|
const LISTENERS = Symbol("listeners");
|
|
8
8
|
const ONMESSAGE = Symbol("onmessage");
|
|
9
|
+
var MessageEvent = class extends Event {
|
|
10
|
+
#data;
|
|
11
|
+
#origin;
|
|
12
|
+
#lastEventId;
|
|
13
|
+
#source;
|
|
14
|
+
#ports;
|
|
15
|
+
constructor(type, init = {}) {
|
|
16
|
+
super(type, init);
|
|
17
|
+
this.#data = init.data ?? null;
|
|
18
|
+
this.#origin = init.origin ?? "";
|
|
19
|
+
this.#lastEventId = init.lastEventId ?? "";
|
|
20
|
+
this.#source = init.source ?? null;
|
|
21
|
+
this.#ports = init.ports ?? [];
|
|
22
|
+
}
|
|
23
|
+
get data() {
|
|
24
|
+
return this.#data;
|
|
25
|
+
}
|
|
26
|
+
get origin() {
|
|
27
|
+
return this.#origin;
|
|
28
|
+
}
|
|
29
|
+
get lastEventId() {
|
|
30
|
+
return this.#lastEventId;
|
|
31
|
+
}
|
|
32
|
+
get source() {
|
|
33
|
+
return this.#source;
|
|
34
|
+
}
|
|
35
|
+
get ports() {
|
|
36
|
+
return this.#ports;
|
|
37
|
+
}
|
|
38
|
+
get [Symbol.toStringTag]() {
|
|
39
|
+
return "MessageEvent";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
9
42
|
var MessagePort = class {
|
|
10
43
|
constructor() {
|
|
11
44
|
this[ENTANGLED] = null;
|
|
@@ -59,15 +92,18 @@ function drain(port) {
|
|
|
59
92
|
const data = port[QUEUE].shift();
|
|
60
93
|
setTimeout(() => {
|
|
61
94
|
if (port[CLOSED]) return;
|
|
62
|
-
deliver(port,
|
|
63
|
-
type: "message",
|
|
64
|
-
data,
|
|
65
|
-
target: port,
|
|
66
|
-
ports: []
|
|
67
|
-
});
|
|
95
|
+
deliver(port, messageEvent(port, data));
|
|
68
96
|
drain(port);
|
|
69
97
|
}, 0);
|
|
70
98
|
}
|
|
99
|
+
function messageEvent(port, data) {
|
|
100
|
+
const event = new MessageEvent("message", { data });
|
|
101
|
+
Object.defineProperty(event, "target", {
|
|
102
|
+
value: port,
|
|
103
|
+
enumerable: true
|
|
104
|
+
});
|
|
105
|
+
return event;
|
|
106
|
+
}
|
|
71
107
|
function deliver(port, event) {
|
|
72
108
|
if (typeof port.onmessage === "function") port.onmessage(event);
|
|
73
109
|
for (const listener of port[LISTENERS].slice()) if (typeof listener === "function") listener.call(port, event);
|
|
@@ -82,6 +118,84 @@ var MessageChannel = class {
|
|
|
82
118
|
}
|
|
83
119
|
};
|
|
84
120
|
//#endregion
|
|
121
|
+
//#region ../../server/guest-surface/text-streams.js
|
|
122
|
+
const READABLE = Symbol("readable");
|
|
123
|
+
const WRITABLE = Symbol("writable");
|
|
124
|
+
const DECODER = Symbol("decoder");
|
|
125
|
+
var TextEncoderStream = class {
|
|
126
|
+
constructor() {
|
|
127
|
+
const encoder = new TextEncoder();
|
|
128
|
+
let held = "";
|
|
129
|
+
const pipe = new TransformStream({
|
|
130
|
+
transform(chunk, controller) {
|
|
131
|
+
const text = held + String(chunk);
|
|
132
|
+
held = endsInHighSurrogate(text) ? text.slice(-1) : "";
|
|
133
|
+
const bytes = encoder.encode(held === "" ? text : text.slice(0, -1));
|
|
134
|
+
if (bytes.length > 0) controller.enqueue(bytes);
|
|
135
|
+
},
|
|
136
|
+
flush(controller) {
|
|
137
|
+
if (held === "") return;
|
|
138
|
+
controller.enqueue(encoder.encode(held));
|
|
139
|
+
held = "";
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
this[READABLE] = pipe.readable;
|
|
143
|
+
this[WRITABLE] = pipe.writable;
|
|
144
|
+
}
|
|
145
|
+
get encoding() {
|
|
146
|
+
return "utf-8";
|
|
147
|
+
}
|
|
148
|
+
get readable() {
|
|
149
|
+
return this[READABLE];
|
|
150
|
+
}
|
|
151
|
+
get writable() {
|
|
152
|
+
return this[WRITABLE];
|
|
153
|
+
}
|
|
154
|
+
get [Symbol.toStringTag]() {
|
|
155
|
+
return "TextEncoderStream";
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
function endsInHighSurrogate(text) {
|
|
159
|
+
const last = text.charCodeAt(text.length - 1);
|
|
160
|
+
return last >= 55296 && last <= 56319;
|
|
161
|
+
}
|
|
162
|
+
var TextDecoderStream = class {
|
|
163
|
+
constructor(label = "utf-8", options = {}) {
|
|
164
|
+
const decoder = new TextDecoder(label, options);
|
|
165
|
+
const pipe = new TransformStream({
|
|
166
|
+
transform(chunk, controller) {
|
|
167
|
+
const text = decoder.decode(chunk, { stream: true });
|
|
168
|
+
if (text !== "") controller.enqueue(text);
|
|
169
|
+
},
|
|
170
|
+
flush(controller) {
|
|
171
|
+
const text = decoder.decode();
|
|
172
|
+
if (text !== "") controller.enqueue(text);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
this[DECODER] = decoder;
|
|
176
|
+
this[READABLE] = pipe.readable;
|
|
177
|
+
this[WRITABLE] = pipe.writable;
|
|
178
|
+
}
|
|
179
|
+
get encoding() {
|
|
180
|
+
return this[DECODER].encoding;
|
|
181
|
+
}
|
|
182
|
+
get fatal() {
|
|
183
|
+
return this[DECODER].fatal;
|
|
184
|
+
}
|
|
185
|
+
get ignoreBOM() {
|
|
186
|
+
return this[DECODER].ignoreBOM;
|
|
187
|
+
}
|
|
188
|
+
get readable() {
|
|
189
|
+
return this[READABLE];
|
|
190
|
+
}
|
|
191
|
+
get writable() {
|
|
192
|
+
return this[WRITABLE];
|
|
193
|
+
}
|
|
194
|
+
get [Symbol.toStringTag]() {
|
|
195
|
+
return "TextDecoderStream";
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
//#endregion
|
|
85
199
|
//#region ../../server/guest-surface/locale-methods.js
|
|
86
200
|
function installUnsupportedLocaleMethods(scope, methods, remedy) {
|
|
87
201
|
const replaced = [];
|
|
@@ -118,7 +232,10 @@ function resolve(scope, target) {
|
|
|
118
232
|
//#region src/guest-parity.ts
|
|
119
233
|
const SHIMS = {
|
|
120
234
|
MessageChannel,
|
|
121
|
-
|
|
235
|
+
MessageEvent,
|
|
236
|
+
MessagePort,
|
|
237
|
+
TextDecoderStream,
|
|
238
|
+
TextEncoderStream
|
|
122
239
|
};
|
|
123
240
|
function applyGuestParity(options = {}) {
|
|
124
241
|
const scope = globalThis;
|
|
@@ -126,11 +243,16 @@ function applyGuestParity(options = {}) {
|
|
|
126
243
|
const undo = [];
|
|
127
244
|
const removed = [];
|
|
128
245
|
const exempted = [];
|
|
246
|
+
const neededByHost = [];
|
|
129
247
|
for (const entry of unsupportedGlobals()) {
|
|
130
248
|
if (polyfilled.has(entry.name)) {
|
|
131
249
|
exempted.push(entry.name);
|
|
132
250
|
continue;
|
|
133
251
|
}
|
|
252
|
+
if (entry.neededByHost) {
|
|
253
|
+
neededByHost.push(entry.name);
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
134
256
|
const descriptor = Object.getOwnPropertyDescriptor(scope, entry.name);
|
|
135
257
|
if (!descriptor) continue;
|
|
136
258
|
undo.push(() => Object.defineProperty(scope, entry.name, descriptor));
|
|
@@ -158,6 +280,7 @@ function applyGuestParity(options = {}) {
|
|
|
158
280
|
shimmed,
|
|
159
281
|
replacedMethods: replaced.map(({ target, name }) => `${target}.${name}`),
|
|
160
282
|
exempted,
|
|
283
|
+
neededByHost,
|
|
161
284
|
restore() {
|
|
162
285
|
for (const step of undo.reverse()) step();
|
|
163
286
|
undo.length = 0;
|
package/dist/guest-parity.d.mts
CHANGED
|
@@ -9,6 +9,8 @@ interface GuestParity {
|
|
|
9
9
|
replacedMethods: string[];
|
|
10
10
|
/** Left in place because the project bundles a polyfill for them. */
|
|
11
11
|
exempted: string[];
|
|
12
|
+
/** Left in place because this process needs them. The guest still has none. */
|
|
13
|
+
neededByHost: string[];
|
|
12
14
|
restore(): void;
|
|
13
15
|
}
|
|
14
16
|
declare function applyGuestParity(options?: GuestParityOptions): GuestParity;
|
package/dist/guest-parity.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as applyGuestParity } from "./guest-parity-
|
|
1
|
+
import { t as applyGuestParity } from "./guest-parity-W61MH7Fb.mjs";
|
|
2
2
|
export { applyGuestParity };
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region ../../server/guest-surface/surface.json
|
|
4
|
+
var globals = [
|
|
5
|
+
{
|
|
6
|
+
"name": "MessageChannel",
|
|
7
|
+
"status": "shim",
|
|
8
|
+
"shim": "message-channel",
|
|
9
|
+
"why": "The engine has none. react-dom/server.browser constructs one at module scope, so a bundle that reaches for it does not evaluate at all."
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": "MessagePort",
|
|
13
|
+
"status": "shim",
|
|
14
|
+
"shim": "message-channel",
|
|
15
|
+
"why": "The other half of the pair: a port handed to code that checks what it received has to be a real constructor."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "MessageEvent",
|
|
19
|
+
"status": "shim",
|
|
20
|
+
"shim": "message-channel",
|
|
21
|
+
"why": "What the pair above carries. Without it, code that checks `event instanceof MessageEvent` fails against our own shim."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "TextEncoderStream",
|
|
25
|
+
"status": "shim",
|
|
26
|
+
"shim": "text-streams",
|
|
27
|
+
"why": "The engine has TransformStream and TextEncoder and not this wrapper over them. Every other stream class is there, so the gap is easy to walk into while piping a body."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "TextDecoderStream",
|
|
31
|
+
"status": "shim",
|
|
32
|
+
"shim": "text-streams",
|
|
33
|
+
"why": "The other direction, and the one a streamed request body is read through."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "Intl",
|
|
37
|
+
"status": "unsupported",
|
|
38
|
+
"remedy": "bundle an Intl polyfill, for example @formatjs/intl-numberformat",
|
|
39
|
+
"providedBy": [
|
|
40
|
+
"intl",
|
|
41
|
+
"full-icu",
|
|
42
|
+
"@formatjs/intl",
|
|
43
|
+
"@formatjs/intl-*",
|
|
44
|
+
"intl-pluralrules",
|
|
45
|
+
"intl-locales-supported",
|
|
46
|
+
"intl-segmenter-polyfill"
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "URLPattern",
|
|
51
|
+
"status": "unsupported",
|
|
52
|
+
"remedy": "bundle a URLPattern polyfill, for example urlpattern-polyfill",
|
|
53
|
+
"providedBy": ["urlpattern-polyfill"]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "WebSocket",
|
|
57
|
+
"status": "unsupported",
|
|
58
|
+
"remedy": "the sandbox has no sockets, so nothing can supply this one; open the connection from the browser instead, or reach a realtime service over HTTPS"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "EventSource",
|
|
62
|
+
"status": "unsupported",
|
|
63
|
+
"remedy": "a run is bounded by the invocation clock, so nothing here can hold a subscription open for a client; subscribe from the browser instead, or poll with fetch"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "BroadcastChannel",
|
|
67
|
+
"status": "unsupported",
|
|
68
|
+
"remedy": "each invocation runs on its own and shares no memory with any other, so there is nobody here to broadcast to; pass the message over fetch to a service that holds it"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "caches",
|
|
72
|
+
"status": "unsupported",
|
|
73
|
+
"remedy": "the platform has no Cache API; keep the value in a service you reach over fetch"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "FileReader",
|
|
77
|
+
"status": "unsupported",
|
|
78
|
+
"remedy": "read the Blob directly: await blob.text(), await blob.arrayBuffer(), or blob.stream()"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "WebAssembly",
|
|
82
|
+
"status": "unsupported",
|
|
83
|
+
"neededByHost": true,
|
|
84
|
+
"why": "Node compiles its own HTTP parser from WebAssembly the first time anything calls fetch, so a suite that had this taken away would fail inside undici rather than in the code under test.",
|
|
85
|
+
"remedy": "the guest is itself WebAssembly and cannot load more of it; do the work in JavaScript, or call a service that does it"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"name": "XMLHttpRequest",
|
|
89
|
+
"status": "unsupported",
|
|
90
|
+
"remedy": "use fetch, which the guest has"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "navigator",
|
|
94
|
+
"status": "unsupported",
|
|
95
|
+
"remedy": "nothing here is a browser, so nothing can supply it; ask with typeof navigator and take the other path"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "localStorage",
|
|
99
|
+
"status": "unsupported",
|
|
100
|
+
"remedy": "nothing written in one invocation survives into the next; keep the value in a store you reach over fetch, or hand it back to the caller"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "sessionStorage",
|
|
104
|
+
"status": "unsupported",
|
|
105
|
+
"remedy": "nothing written in one invocation survives into the next; keep the value in a store you reach over fetch, or hand it back to the caller"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "indexedDB",
|
|
109
|
+
"status": "unsupported",
|
|
110
|
+
"remedy": "the sandbox has no database; reach one over fetch"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "setImmediate",
|
|
114
|
+
"status": "unsupported",
|
|
115
|
+
"remedy": "call setTimeout(fn, 0), or queueMicrotask(fn) where the callback must run before the host is yielded to"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"name": "reportError",
|
|
119
|
+
"status": "unsupported",
|
|
120
|
+
"remedy": "throw, or write the error yourself with console.error"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "Atomics",
|
|
124
|
+
"status": "unsupported",
|
|
125
|
+
"remedy": "the guest runs one thread and shares memory with nothing, so there is nothing here to synchronise against; take the single-threaded path"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "SharedArrayBuffer",
|
|
129
|
+
"status": "unsupported",
|
|
130
|
+
"remedy": "the guest runs one thread and shares memory with nothing; use an ArrayBuffer"
|
|
131
|
+
}
|
|
132
|
+
];
|
|
133
|
+
var methods = [
|
|
134
|
+
{
|
|
135
|
+
"target": "Number.prototype",
|
|
136
|
+
"name": "toLocaleString"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"target": "Date.prototype",
|
|
140
|
+
"name": "toLocaleString"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"target": "Date.prototype",
|
|
144
|
+
"name": "toLocaleDateString"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"target": "Date.prototype",
|
|
148
|
+
"name": "toLocaleTimeString"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"target": "String.prototype",
|
|
152
|
+
"name": "toLocaleLowerCase"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"target": "String.prototype",
|
|
156
|
+
"name": "toLocaleUpperCase"
|
|
157
|
+
}
|
|
158
|
+
];
|
|
159
|
+
var methodRemedy$1 = "the engine carries no ICU, so it ignores the locale and returns an unlocalised string; format the value yourself, or bundle a formatting library and call it directly";
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/guest-surface.ts
|
|
162
|
+
function declaredGlobals() {
|
|
163
|
+
return globals;
|
|
164
|
+
}
|
|
165
|
+
function declaredMethods() {
|
|
166
|
+
return methods;
|
|
167
|
+
}
|
|
168
|
+
function methodRemedy() {
|
|
169
|
+
return methodRemedy$1;
|
|
170
|
+
}
|
|
171
|
+
function unsupportedGlobals() {
|
|
172
|
+
return declaredGlobals().filter((entry) => entry.status === "unsupported");
|
|
173
|
+
}
|
|
174
|
+
function shimmedGlobals() {
|
|
175
|
+
return declaredGlobals().filter((entry) => entry.status === "shim");
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Globals a project already carries a polyfill for, read from the manifest the
|
|
179
|
+
* polyfill is declared in so nothing here can drift from what is bundled.
|
|
180
|
+
*/
|
|
181
|
+
function polyfilledGlobals(projectDir) {
|
|
182
|
+
const declared = declaredPackages(projectDir);
|
|
183
|
+
return new Set(declaredGlobals().filter((entry) => (entry.providedBy ?? []).some((pattern) => declared.some((name) => matches(pattern, name)))).map((entry) => entry.name));
|
|
184
|
+
}
|
|
185
|
+
function matches(pattern, name) {
|
|
186
|
+
if (!pattern.endsWith("*")) return pattern === name;
|
|
187
|
+
return name.startsWith(pattern.slice(0, -1));
|
|
188
|
+
}
|
|
189
|
+
function declaredPackages(projectDir) {
|
|
190
|
+
const manifest = path.join(projectDir, "package.json");
|
|
191
|
+
if (!fs.existsSync(manifest)) return [];
|
|
192
|
+
let parsed;
|
|
193
|
+
try {
|
|
194
|
+
parsed = JSON.parse(fs.readFileSync(manifest, "utf-8"));
|
|
195
|
+
} catch {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
return [
|
|
199
|
+
"dependencies",
|
|
200
|
+
"devDependencies",
|
|
201
|
+
"optionalDependencies"
|
|
202
|
+
].flatMap((field) => {
|
|
203
|
+
const deps = parsed[field];
|
|
204
|
+
return typeof deps === "object" && deps !== null ? Object.keys(deps) : [];
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
//#endregion
|
|
208
|
+
export { unsupportedGlobals as a, shimmedGlobals as i, methodRemedy as n, polyfilledGlobals as r, declaredMethods as t };
|