CultLib/packages/cultcache-ts/test/browser-entry.test.ts
Libby 23279b8e50
Some checks failed
CultMesh QUIC native / Build win32-x64 (pull_request) Has been skipped
CultMesh QUIC native / Build linux-x64 (pull_request) Has been skipped
CultMesh QUIC native / Release native binaries (pull_request) Has been skipped
CultMesh portability and performance / ubuntu-latest one-command multiplayer onboarding (pull_request) Failing after 1m19s
CultMesh portability and performance / ubuntu-latest reactive semantics and leases (pull_request) Failing after 6m36s
CultMesh QUIC native / Verify committed binaries match SHA256SUMS (pull_request) Successful in 36s
cultcache-ts: browser-safe entry that excludes the node-only single-file store
The package root imports node:fs, node:path and koffi through the single-file
store, so esbuild platform=browser fails on it. src/browser.ts is the root
surface minus that store; src/index.ts re-exports it and adds the store, so
the Node entry is unchanged. Exposed as ./browser and as the 'browser' export
condition on the root.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-07 11:37:03 +00:00

45 lines
1.9 KiB
TypeScript

import assert from "node:assert/strict";
import { join } from "node:path";
import test from "node:test";
import { runInNewContext } from "node:vm";
import { build } from "esbuild";
// dist-test/test/ -> dist-test/src/
const srcDir = join(__dirname, "..", "src");
async function bundleForBrowser(entry: string): Promise<string> {
const result = await build({
entryPoints: [join(srcDir, entry)],
bundle: true,
platform: "browser",
format: "iife",
globalName: "cultcache",
write: false,
logLevel: "silent",
});
return result.outputFiles[0].text;
}
test("the browser entry bundles for platform=browser and runs without node", async () => {
const code = await bundleForBrowser("browser.js");
assert.ok(!/node:fs|koffi/.test(code), "no node-only store in the browser bundle");
// A context with no require/process/Buffer: only what a browser page has.
const sandbox: Record<string, unknown> = { TextEncoder, TextDecoder };
runInNewContext(code + "\nglobalThis.__api = cultcache;", sandbox);
const api = sandbox.__api as Record<string, unknown>;
assert.equal(typeof api.CultCache, "function");
assert.equal(typeof api.defineDocumentType, "function");
assert.equal(api.SingleFileMessagePackBackingStore, undefined);
});
test("the node entry still exports the single-file store and everything the browser entry has", async () => {
const node = await import(join(srcDir, "index.js"));
const browser = await import(join(srcDir, "browser.js"));
assert.equal(typeof node.SingleFileMessagePackBackingStore, "function");
assert.equal(typeof node.readSingleFileStore, "function");
for (const name of Object.keys(browser)) assert.ok(name in node, `node entry lost ${name}`);
});
test("the package root keeps the node-only store out of the browser build", async () => {
await assert.rejects(bundleForBrowser("index.js"), /node:fs|node:path|koffi/);
});