diff --git a/packages/tuono/src/build/index.ts b/packages/tuono/src/build/index.ts index 306a7fc2..3703068d 100644 --- a/packages/tuono/src/build/index.ts +++ b/packages/tuono/src/build/index.ts @@ -21,6 +21,8 @@ const VITE_SSR_PLUGINS: Array = [ * @see https://github.com/tuono-labs/tuono/issues/218 */ MessageChannel: ['tuono/ssr', 'MessageChannelPolyfill'], + MessageEvent: ['tuono/ssr', 'MessageEventPolyfill'], + Event: ['tuono/ssr', 'EventPolyfill'], }), }, ] diff --git a/packages/tuono/src/ssr/index.ts b/packages/tuono/src/ssr/index.ts new file mode 100644 index 00000000..40a81103 --- /dev/null +++ b/packages/tuono/src/ssr/index.ts @@ -0,0 +1,5 @@ +export { serverSideRendering } from './server' + +export { MessageChannelPolyfill } from './polyfills/MessageChannel' +export { EventPolyfill } from './polyfills/Event' +export { MessageEventPolyfill } from './polyfills/MessageEvent' diff --git a/packages/tuono/src/ssr/polyfills/Event.ts b/packages/tuono/src/ssr/polyfills/Event.ts new file mode 100644 index 00000000..645461ea --- /dev/null +++ b/packages/tuono/src/ssr/polyfills/Event.ts @@ -0,0 +1,25 @@ +/** + * https://dom.spec.whatwg.org/#interface-event + */ +// @ts-expect-error Not all the properties are implemented +export class EventPolyfill implements Event { + type: string + bubbles: boolean + cancelable: boolean + composed: boolean + currentTarget: EventTarget | null = null + defaultPrevented = false + eventPhase = 0 + isTrusted = false + target: EventTarget | null = null + timeStamp: number = Date.now() + returnValue = true + srcElement: EventTarget | null = null + + constructor(type: string, eventInitDict?: EventInit) { + this.type = type + this.bubbles = eventInitDict?.bubbles ?? false + this.cancelable = eventInitDict?.cancelable ?? false + this.composed = eventInitDict?.composed ?? false + } +} diff --git a/packages/tuono/src/ssr/polyfills/messageChannel.spec.ts b/packages/tuono/src/ssr/polyfills/MessageChannel.spec.ts similarity index 98% rename from packages/tuono/src/ssr/polyfills/messageChannel.spec.ts rename to packages/tuono/src/ssr/polyfills/MessageChannel.spec.ts index 58d21fa7..83bcac6e 100644 --- a/packages/tuono/src/ssr/polyfills/messageChannel.spec.ts +++ b/packages/tuono/src/ssr/polyfills/MessageChannel.spec.ts @@ -1,6 +1,6 @@ import { describe, it, expect, vi } from 'vitest' -import { MessageChannelPolyfill, MessagePortPolyfill } from './messageChannel' +import { MessageChannelPolyfill, MessagePortPolyfill } from './MessageChannel' describe('MessagePortPolyfill', () => { it('should invoke onmessage when a message is posted', () => { diff --git a/packages/tuono/src/ssr/polyfills/messageChannel.ts b/packages/tuono/src/ssr/polyfills/MessageChannel.ts similarity index 100% rename from packages/tuono/src/ssr/polyfills/messageChannel.ts rename to packages/tuono/src/ssr/polyfills/MessageChannel.ts diff --git a/packages/tuono/src/ssr/polyfills/MessageEvent.ts b/packages/tuono/src/ssr/polyfills/MessageEvent.ts new file mode 100644 index 00000000..6d9ad9fc --- /dev/null +++ b/packages/tuono/src/ssr/polyfills/MessageEvent.ts @@ -0,0 +1,25 @@ +import { EventPolyfill } from './Event' + +/** + * https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interface + */ +// @ts-expect-error Not all the properties are implemented +export class MessageEventPolyfill + extends EventPolyfill + implements MessageEvent +{ + data?: T + lastEventId: string + origin: string + ports: ReadonlyArray + source: MessageEventSource | null + + constructor(type: string, options: MessageEventInit) { + super(type, options) + this.data = options.data + this.lastEventId = options.lastEventId ?? '' + this.origin = options.origin ?? '' + this.ports = options.ports ?? [] + this.source = options.source ?? null + } +} diff --git a/packages/tuono/src/ssr/index.tsx b/packages/tuono/src/ssr/server.tsx similarity index 96% rename from packages/tuono/src/ssr/index.tsx rename to packages/tuono/src/ssr/server.tsx index 67e17123..843938f3 100644 --- a/packages/tuono/src/ssr/index.tsx +++ b/packages/tuono/src/ssr/server.tsx @@ -8,7 +8,6 @@ import { HelmetProvider } from 'react-helmet-async' import { RouterProvider, createRouter } from 'tuono-router' import type { createRoute } from 'tuono-router' -import { MessageChannelPolyfill } from './polyfills/messageChannel' import { streamToString } from './utils' type RouteTree = ReturnType @@ -95,5 +94,3 @@ export function serverSideRendering(routeTree: RouteTree) { ` } } - -export { MessageChannelPolyfill } diff --git a/packages/tuono/vite.config.ts b/packages/tuono/vite.config.ts index 854eb189..7bb6cfe2 100644 --- a/packages/tuono/vite.config.ts +++ b/packages/tuono/vite.config.ts @@ -15,7 +15,7 @@ export default mergeConfig( './src/index.ts', './src/build/index.ts', './src/config/index.ts', - './src/ssr/index.tsx', + './src/ssr/index.ts', './src/hydration/index.tsx', ], srcDir: './src',