mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-25 16:02:11 +00:00
6d1e12d5e9
* feat(nativets): expose standard web-platform globals for bun parity Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(nativets): wire bun-present Event subclasses and add construction smoke test Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(nativets): seed performance.timeOrigin per isolate, drop broken reportError Addresses CI Codex review on #10112: - performance.timeOrigin was undefined (setTimeOrigin never called); seed it per isolate via __wmInitPerIsolate executed from create_nativets_runtime. - reportError needs a global EventTarget this runtime never installs; drop it. - reword the namespace-import comment to not describe drafting history. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(nativets): wire DOMException global + broad edge-case smoke sweep DOMException is present in bun and, more importantly, deno_web references it as a global: AbortController.abort() with no reason constructs a DOMException("...", "AbortError"), so the already-wired AbortController/ AbortSignal threw "DOMException is not defined" on abort. Surfaced by a new functional edge-case sweep (smoke_web_globals_edge_cases) that exercises every wired global for real (not just presence) — DOMException/abort, AbortSignal.timeout, EventTarget dispatch, stream tee/reader/writer, all 3 compression formats, structuredClone Map/Set/Date/circular/reject-function, performance mark/measure, MessagePort delivery — plus a check that the merged Web Crypto globals still work. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(nativets): restore arg-default smoke tests dropped in merge, drop history comments Addresses CI Codex/Pi review on the merge commit: - Merge conflict resolution (checkout --ours) dropped smoke_missing_optional_arg_uses_default and smoke_explicit_null_arg_is_preserved (added on main by #10111); restore them. - Reword edge-case-sweep comments to state the constraint, not how the gaps were found. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(nativets): give reportException a global dispatch target; wire stream reader/controller globals Addresses CI Codex review on #10112: - P1: a throwing EventTarget listener (and reportError) is routed through deno_web's reportException, which dispatches on a saved global reference. With none set, dispatchEvent threw a masking error that hid the original. Wire a dedicated EventTarget as that target so the ORIGINAL error is reported (async unhandled, matching bun). Does NOT make globalThis an EventTarget (bun's isn't either). Re-adds reportError, now functional. Regression test asserts the original error is surfaced, not a masking one. - P2: wire the stream reader/controller globals bun also exposes (ReadableStreamDefaultReader/BYOBReader, ReadableStreamDefault/ByteStreamController, ReadableStreamBYOBRequest, WritableStreamDefaultWriter/Controller, TransformStreamDefaultController) for instanceof parity; sweep verifies via real reader/writer/controller instances. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(nativets): make globalThis an EventTarget so globalThis.reportError() works Addresses follow-up CI Codex review on #10112: - P1: the prior fix saved a *separate* EventTarget as the global reference, so globalThis.reportError() still failed its receiver check (this === globalThis_) with 'Illegal invocation'. Make globalThis itself the saved reference by turning it into a functional EventTarget (setPrototypeOf to DedicatedWorkerGlobalScope + setEventTargetData + webidl brand + saveGlobalThisReference), per isolate in __wmInitPerIsolate. Both reportError(e) and globalThis.reportError(e) now surface the original error (async, matching bun) instead of throwing. New test smoke_report_error_both_call_forms covers both call forms. - P2: reword the regression-test comment to state the invariant, not the patch history. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(nativets): wire performance constructor globals for bun parity Addresses the P2 nit in the CI Codex review: bun exposes Performance, PerformanceEntry, PerformanceMark, and PerformanceMeasure as globals (deno_web exports all four), so wire them alongside the performance singleton. The edge-case sweep verifies instanceof against real mark/measure entries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(nativets): state global-wiring comment as a constraint, not patch history Addresses the P2 in the CI Codex review: reword the block comment to describe the current bun-parity constraint and the deliberate EventSource/ImageData exclusions, without narrating what was or wasn't wired before (per AGENTS.md). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
159 lines
7.7 KiB
JavaScript
159 lines
7.7 KiB
JavaScript
import * as abortSignal from "ext:deno_web/03_abort_signal.js";
|
|
import * as domException from "ext:deno_web/01_dom_exception.js";
|
|
import * as base64 from "ext:deno_web/05_base64.js";
|
|
import * as console from "ext:deno_console/01_console.js";
|
|
import * as encoding from "ext:deno_web/08_text_encoding.js";
|
|
import * as event from "ext:deno_web/02_event.js";
|
|
import * as fetch from "ext:deno_fetch/26_fetch.js";
|
|
import * as file from "ext:deno_web/09_file.js";
|
|
import * as fileReader from "ext:deno_web/10_filereader.js";
|
|
import * as formData from "ext:deno_fetch/21_formdata.js";
|
|
import * as headers from "ext:deno_fetch/20_headers.js";
|
|
import * as streams from "ext:deno_web/06_streams.js";
|
|
import * as timers from "ext:deno_web/02_timers.js";
|
|
import * as url from "ext:deno_url/00_url.js";
|
|
import * as net from "ext:deno_net/01_net.js";
|
|
import * as tls from "ext:deno_net/02_tls.js";
|
|
import * as urlPattern from "ext:deno_url/01_urlpattern.js";
|
|
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
|
import * as crypto from "ext:deno_crypto/00_crypto.js";
|
|
import * as response from "ext:deno_fetch/23_response.js";
|
|
import * as request from "ext:deno_fetch/23_request.js";
|
|
import "ext:deno_web/02_structured_clone.js";
|
|
import * as globalInterfaces from "ext:deno_web/04_global_interfaces.js";
|
|
// Namespace imports (not side-effect-only) so their constructors are reachable
|
|
// for the globalThis wiring below. The module bodies still execute on
|
|
// evaluation, so their side effects apply.
|
|
import * as messagePort from "ext:deno_web/13_message_port.js";
|
|
import * as compression from "ext:deno_web/14_compression.js";
|
|
import * as performance from "ext:deno_web/15_performance.js";
|
|
import "ext:deno_web/16_image_data.js";
|
|
import "ext:deno_fetch/27_eventsource.js";
|
|
|
|
globalThis.atob = base64.atob;
|
|
globalThis.btoa = base64.btoa;
|
|
globalThis.fetch = fetch.fetch;
|
|
globalThis.Request = request.Request;
|
|
globalThis.Response = response.Response;
|
|
globalThis.Blob = file.Blob;
|
|
globalThis.URL = url.URL;
|
|
globalThis.FormData = formData.FormData;
|
|
globalThis.URLSearchParams = url.URLSearchParams;
|
|
globalThis.Headers = headers.Headers;
|
|
globalThis.FileReader = fileReader.FileReader;
|
|
globalThis.console = new console.Console((msg, level) =>
|
|
globalThis.Deno.core.ops.op_log(msg)
|
|
);
|
|
globalThis.AbortController = abortSignal.AbortController;
|
|
globalThis.AbortSignal = abortSignal.AbortSignal;
|
|
globalThis.crypto = crypto.crypto;
|
|
globalThis.Crypto = crypto.Crypto;
|
|
globalThis.CryptoKey = crypto.CryptoKey;
|
|
globalThis.SubtleCrypto = crypto.SubtleCrypto;
|
|
|
|
Object.assign(globalThis, {
|
|
clearInterval: timers.clearInterval,
|
|
clearTimeout: timers.clearTimeout,
|
|
setInterval: timers.setInterval,
|
|
setTimeout: timers.setTimeout,
|
|
});
|
|
|
|
// Standard web-platform globals from the deno_web / deno_url extensions,
|
|
// exposed to match the bun runner's global surface. Every name below is present
|
|
// in bun; names bun lacks (EventSource, ImageData) are deliberately excluded.
|
|
Object.assign(globalThis, {
|
|
// DOMException. Beyond bun parity, deno_web modules reference it as a global:
|
|
// AbortController.abort() with no reason constructs `new DOMException(...)`, so
|
|
// without this the already-wired AbortController/AbortSignal throw on abort.
|
|
DOMException: domException.DOMException,
|
|
// Text encoding + encoding streams.
|
|
TextEncoder: encoding.TextEncoder,
|
|
TextDecoder: encoding.TextDecoder,
|
|
TextEncoderStream: encoding.TextEncoderStream,
|
|
TextDecoderStream: encoding.TextDecoderStream,
|
|
// File (Blob is already wired above).
|
|
File: file.File,
|
|
// Events (AbortSignal, already wired, extends EventTarget). MessageEvent is
|
|
// the companion to MessagePort/MessageChannel below. Only the event types
|
|
// bun exposes are wired (ProgressEvent / PromiseRejectionEvent are not).
|
|
// reportError works because __wmInitPerIsolate makes globalThis an EventTarget.
|
|
Event: event.Event,
|
|
EventTarget: event.EventTarget,
|
|
CustomEvent: event.CustomEvent,
|
|
MessageEvent: event.MessageEvent,
|
|
CloseEvent: event.CloseEvent,
|
|
ErrorEvent: event.ErrorEvent,
|
|
reportError: event.reportError,
|
|
// Streams + queuing strategies + the reader/controller constructors bun also
|
|
// exposes as globals (used for `x instanceof ReadableStreamDefaultReader` etc.;
|
|
// the controllers throw on direct construction, matching the spec).
|
|
ReadableStream: streams.ReadableStream,
|
|
ReadableStreamDefaultReader: streams.ReadableStreamDefaultReader,
|
|
ReadableStreamBYOBReader: streams.ReadableStreamBYOBReader,
|
|
ReadableStreamDefaultController: streams.ReadableStreamDefaultController,
|
|
ReadableByteStreamController: streams.ReadableByteStreamController,
|
|
ReadableStreamBYOBRequest: streams.ReadableStreamBYOBRequest,
|
|
WritableStream: streams.WritableStream,
|
|
WritableStreamDefaultWriter: streams.WritableStreamDefaultWriter,
|
|
WritableStreamDefaultController: streams.WritableStreamDefaultController,
|
|
TransformStream: streams.TransformStream,
|
|
TransformStreamDefaultController: streams.TransformStreamDefaultController,
|
|
ByteLengthQueuingStrategy: streams.ByteLengthQueuingStrategy,
|
|
CountQueuingStrategy: streams.CountQueuingStrategy,
|
|
// URL pattern matching.
|
|
URLPattern: urlPattern.URLPattern,
|
|
// Compression streams.
|
|
CompressionStream: compression.CompressionStream,
|
|
DecompressionStream: compression.DecompressionStream,
|
|
// Message channel / port.
|
|
MessageChannel: messagePort.MessageChannel,
|
|
MessagePort: messagePort.MessagePort,
|
|
// High-resolution timing: the `performance` singleton and its constructor
|
|
// globals (bun exposes all of these; PerformanceObserver is not in deno_web).
|
|
performance: performance.performance,
|
|
Performance: performance.Performance,
|
|
PerformanceEntry: performance.PerformanceEntry,
|
|
PerformanceMark: performance.PerformanceMark,
|
|
PerformanceMeasure: performance.PerformanceMeasure,
|
|
// Spec structuredClone (validates args + honors the options bag), from the
|
|
// message-port module rather than the single-arg internal helper in
|
|
// 02_structured_clone.js.
|
|
structuredClone: messagePort.structuredClone,
|
|
});
|
|
|
|
// Per-isolate init, invoked from Rust after the snapshot is restored (this
|
|
// module body runs at snapshot-build time, not per isolate).
|
|
globalThis.__wmInitPerIsolate = () => {
|
|
// setTimeOrigin() seeds performance.timeOrigin from the isolate's wall clock;
|
|
// without it timeOrigin is undefined and `timeOrigin + performance.now()` is NaN.
|
|
performance.setTimeOrigin();
|
|
|
|
// Make globalThis a functional EventTarget, as Deno's bootstrap does. deno_web
|
|
// routes uncaught EventTarget-listener errors and reportError through
|
|
// reportException, which dispatches an error event on the saved global
|
|
// reference; reportError also requires its receiver to equal that reference.
|
|
// Both need the reference to be globalThis and globalThis to be an EventTarget,
|
|
// otherwise dispatch throws a masking error and globalThis.reportError() throws
|
|
// "Illegal invocation". Set up per isolate so the reference is the live global.
|
|
// The prototype + brand are what webidl.assertBranded checks in the methods.
|
|
Object.setPrototypeOf(
|
|
globalThis,
|
|
globalInterfaces.DedicatedWorkerGlobalScope.prototype,
|
|
);
|
|
event.setEventTargetData(globalThis);
|
|
globalThis[webidl.brand] = webidl.brand;
|
|
event.saveGlobalThisReference(globalThis);
|
|
};
|
|
|
|
// Expose bootstrapOtel globally so it can be called from Rust after runtime creation.
|
|
// We use dynamic import so deno_telemetry isn't loaded during snapshot creation.
|
|
// Config: [tracingEnabled, metricsEnabled, consoleConfig, deterministic]
|
|
// consoleConfig: 0=ignore, 1=capture, 2=replace
|
|
globalThis.__bootstrapOtel = () => {
|
|
import("ext:deno_telemetry/telemetry.ts").then(({ bootstrap, enterSpan }) => {
|
|
bootstrap([1, 0, 1, 0]);
|
|
// Expose enterSpan for setting parent trace context
|
|
globalThis.__enterSpan = enterSpan;
|
|
});
|
|
};
|