a post-component library for building user-interfaces on the web.
1import { createBirpc } from 'birpc'
2import * as mitata from 'mitata'
3import * as devalue from './devalue.ts'
4import type { ServerFunctions } from './main.ts'
5
6export type TestResult = { name: string } & ({ result: 'pass'; duration: number } | { result: 'fail'; reason: unknown })
7
8export interface ClientFunctions {
9 define<K extends keyof typeof globalThis>(name: K, value: (typeof globalThis)[K]): void
10 import(path: string): Promise<unknown>
11 run_tests(options: { filter?: RegExp }): Promise<void>
12 run_benchmarks(options: { filter?: RegExp }): Promise<mitata.trial[]>
13 stop_coverage(): Promise<void>
14}
15
16const client: ClientFunctions = {
17 define(name, value) {
18 globalThis[name] = value
19 },
20 import(path) {
21 return import(path)
22 },
23 async run_tests(options) {
24 for (const test of tests) {
25 if (options.filter?.test(test.name) === false) continue
26
27 try {
28 const start = performance.now()
29 await test.fn()
30 const end = performance.now()
31 await server.report_result({ name: test.name, result: 'pass', duration: end - start })
32 } catch (error) {
33 await server.report_result({ name: test.name, result: 'fail', reason: error })
34 }
35 }
36 },
37 async run_benchmarks(options) {
38 const { benchmarks } = await mitata.run({ filter: options.filter })
39 return benchmarks
40 },
41 async stop_coverage() {
42 if (typeof process === 'undefined') return
43 const v8 = await import('node:v8')
44 v8.takeCoverage()
45 v8.stopCoverage()
46 },
47}
48
49declare global {
50 var __onmessage: (fn: (data: any) => void) => void
51 var __postMessage: (data: any) => void
52}
53
54const server = createBirpc<ServerFunctions, ClientFunctions>(
55 client,
56 typeof process === 'undefined'
57 ? {
58 post: window.__postMessage,
59 on: fn => (window.__onmessage = fn),
60 serialize: devalue.stringify,
61 deserialize: devalue.parse,
62 }
63 : {
64 post: data => process.send!(data),
65 on: fn => process.on('message', fn),
66 serialize: devalue.stringify,
67 deserialize: devalue.parse,
68 },
69)
70
71export const tests: Array<{ name: string; fn: () => void | Promise<void> }> = []