Avatar for the rethinkhealth user
rethinkhealth
glion
BlogDocsChangelog

Performance History

Latest Results

feat(mllp-client)!: tls now boolean | TlsOptions; defaults to TLS-on Two breaking changes to MllpClientOptions.tls, both grounded in the fact that HL7v2 messages commonly carry PHI and "secure by default" is the right stance for a healthcare client. (1) Reshape: `tls?: boolean | MllpClientTlsOptions` ============================================================ Previously: `tls?: MllpClientTlsOptions` — the implicit "object provided → TLS on" rule. This was hiding the wire-protocol intent behind structural type duck-typing and was the root cause of Copilot's review finding (a `tls.insecure: true` config that silently downgraded to plain TCP on Workers, because the rule "tls is on iff tls is set" was applied independently per-runtime with no shared activator). Now: `tls: true` is the explicit "use TLS with defaults" form, matching the mainstream pattern (MongoDB, pg). The object form still works for custom config. The core normalises `tls: true` to `tls: {}` before reaching the adapter, so `MllpConnectParams.tls` stays `MllpClientTlsOptions | undefined` and adapters see only the object shape. (2) Default: TLS-on ============================================================ Previously: `tls` undefined → plain TCP. Now: `tls` undefined → TLS on (same as `tls: true`). Plain TCP requires explicit `tls: false`. Migration: every call site that relied on "no tls field → plain TCP" must now pass `tls: false`. Call sites that already passed a tls object are unchanged. Implementation ============================================================ - `MllpClientOptions.tls`: type widened to `boolean | TlsOptions` with `@default true`. JSDoc explains the four shapes (default, true, object, false) and when to use each. - `MllpClient` constructor: normalises the union to `TlsOptions | undefined` for adapters. `false` → undefined; `true | undefined` → {} (TLS-on, no config); object passes through. - `validateOptions`: accepts `boolean | object | undefined`; rejects anything else with INVALID_INPUT. - Workers adapter: removes the now-redundant `params.tls.insecure` check from the secureTransport calculation (the core normalises before reaching here; `params.tls` is truthy iff TLS should negotiate). `rejectUnsupportedTlsMaterial` still rejects ca/cert/key/passphrase/insecure as before — Workers can't honour them. - Node adapter: no logic change; still receives `params.tls` as `TlsOptions | undefined`. Test surface ============================================================ - All Node + core tests that assumed plain-TCP-by-default now pass `tls: false` explicitly. ~50 mechanical edits via awk script. - New core construction tests verify the default-true behaviour: one asserts `received.tls` is set when no tls field is passed; another asserts it's undefined when `tls: false` is passed. - Workers happy-path and CONNECTION_REFUSED tests pass `tls: false` to connect to the plain-TCP ack server. - Workers harness `SendRequest.tls` widened to accept boolean. Total: 56 Node + 63 workerd = 119 tests, all green. Type-check clean, build clean. Changeset bumps `@glion/mllp-client` from minor to major. https://claude.ai/code/session_01MvBEUcGkRokNw2GWYVHADg
claude/mllp-client-workers-runtime
1 day ago
fix(mllp-client/workers): reject tls.insecure to prevent silent plaintext downgrade Per Copilot review on PR #616: the previous behaviour mapped `tls.insecure: true` to `secureTransport: "off"`, which silently downgraded an explicitly TLS-typed configuration to plain TCP on Workers — a runtime-dependent security regression vs. the Node adapter, where `insecure: true` keeps TLS on and only disables certificate verification. Workers does not expose a way to disable certificate verification independently of `secureTransport`, so the only honest options are (a) silently ignore `insecure` (still encrypted, intent partially honoured) or (b) reject with INVALID_INPUT. We pick (b) because it matches how we already handle ca/cert/key/passphrase: Workers does not support programmatic TLS configuration; operators should use the platform's TLS facilities instead. Caller migration: - Want plain TCP? Omit `tls` entirely. - Want TLS with verification? `tls: {}` (or with `servername`). - Want TLS without verification? Not supported on Workers — use Cloudflare's platform TLS configuration. Changes: - workers.ts: rejectUnsupportedTlsMaterial now also rejects `insecure: true`. The `secureTransport` calculation simplifies to `params.tls ? "on" : "off"` because the insecure-true branch is now rejected before reaching it. - JSDoc on workersConnect updated to spell out the trade-off. - Changeset updated: drop the "insecure → plain TCP" claim, add the new rejection to the INVALID_INPUT list. - New test in adapter.test.ts covering the rejection (61 tests total in the workerd project, was 60). https://claude.ai/code/session_01MvBEUcGkRokNw2GWYVHADg
claude/mllp-client-workers-runtime
1 day ago
refactor(mllp-client): polish workers adapter + test harness Code review pass focused on elegance, simplicity, and CLAUDE.md design philosophy. No behaviour changes; 54 Node tests + 60 workerd tests still green. harness.ts - Replace string-name class detection (`e.constructor.name === "X"`) with `instanceof` checks against MllpClientError + AckException. The string form was fragile under any name-mangling minifier. - Drop the redundant `className` field — it duplicates `kind` for typed errors and was never read by the test assertions. - Trim the JSDoc header: drop the abandoned-vitest-pool-workers history paragraph (CLAUDE.md §10 — that belongs in the PR description, not in code that lives forever). - Add `message: "invalid JSON body"` to the BadRequest response so malformed-payload failures are debuggable. - Extract `DEFAULT_TIMEOUT_MS` instead of inline 5000. workers.ts - Drop the `noop()` function — replace with `null` + optional invocation (`dispose?.()`). - Drop `pickError(...candidates)` — used once, inline the two-arg precedence directly into `toAbortError` as a small if/else. - Drop `closeWorkerSocketIgnoringErrors` — collapse the two fire-and-forget `socket.close()` paths (abort handler + duplex close) into the same inline `.catch(() => undefined)` pattern, with one short comment explaining the contract. - Trim the duplicated comment block in `MllpDuplexStream.close` (was two paragraphs saying the same thing). adapter.test.ts - Import `TEST_PORT` from `global-setup` instead of redeclaring it. The two values can no longer drift. Net: -56 lines. https://claude.ai/code/session_01MvBEUcGkRokNw2GWYVHADg
claude/mllp-client-workers-runtime
1 day ago
refactor(mllp-client): migrate Workers tests to Hono's wrangler.unstable_dev pattern Replaces @cloudflare/vitest-pool-workers with the same testing pattern Hono uses (`runtime-tests/workerd/` in honojs/hono): a small harness Worker exposes the adapter over HTTP, Node-side vitest spawns it via wrangler.unstable_dev, and tests assert on the HTTP response. Why: - vitest-pool-workers' coverage instrumentation depends on node:inspector/promises which workerd doesn't ship; the workers project couldn't run under pnpm test:coverage. - The pool also failed to boot reliably across CI runners and inside containerised environments, leaving us unable to verify Workers behaviour in CI. - Hono's pattern works on standard ubuntu-latest GH Actions runners and is the de-facto standard for multi-runtime libraries. Test surface (6 tests): - Happy-path round-trip: harness connects via cloudflare:sockets, writes the MLLP frame, parses the AA from the Node-side ack server, returns it over HTTP. - CONNECTION_REFUSED when the TCP target is closed. - INVALID_INPUT for tls.ca, tls.cert, tls.key, tls.passphrase. Files: - test/workers/harness.ts (new) — harness Worker exposing POST /send - test/workers/adapter.test.ts (rewritten) — Node-side tests via wrangler.unstable_dev - test/workers/wrangler.toml — points at harness.ts; compat date bumped to 2025-09-23 - test/workers/global-setup.ts — unchanged (TCP ack server) - vitest.config.ts — drops the cloudflareTest plugin; both projects are now plain vitest. Bun can load the config cleanly so vitest.bun.config.ts is no longer needed. - vitest.bun.config.ts — deleted - package.json — drops @cloudflare/vitest-pool-workers, adds wrangler Generic CI scaffolding (so future packages get this for free): - turbo.json declares test:bun, test:cf, test:deno tasks - Workspace package.json adds test:bun / test:cf / test:deno scripts that delegate to turbo - .github/workflows/ci.yml: e2e-bun renamed to testing-bun and now runs `pnpm test:bun` (turbo dispatches across all opted-in packages); new testing-cf job runs `pnpm test:cf` with NODE_OPTIONS=--max_old_space_size=8192 - @glion/cli gets a test:bun script wrapping its existing e2e command, so the renamed testing-bun job continues to cover it Adding multi-runtime tests to a new package is now: define test:bun / test:cf / test:deno in that package.json. CI picks it up automatically; no workflow edits. https://claude.ai/code/session_01MvBEUcGkRokNw2GWYVHADg
claude/mllp-client-workers-runtime
1 day ago
feat!: sunset legacy empty-mode; remove loadConfig from @glion/builder BREAKING CHANGE: Empty fields, repetitions, and components are now always represented with `children: []`. The `experimental.emptyMode` setting (which toggled between "legacy" full-skeleton-with-empty-string-leaf and "empty" empty-children-array) is removed entirely. Why this matters now ==================== Every @glion/builder factory call (f(), r(), c()) was routing through loadConfig() from @glion/config to decide which AST shape to produce. That imported cosmiconfig + Node-only modules (fs, path, os, crypto, module, url) into every consumer's bundle: @glion/mllp-client → @glion/ack → @glion/builder → @glion/config (loadConfig) → cosmiconfig → fs, path, os, crypto, ... This broke runtime portability: Workers and Deno bundles dragged in Node builtins they couldn't resolve, even though the harness/runtime never invoked config-loading code. The architectural fix is to remove disk-based config discovery from leaf factory functions; sunsetting `legacy` mode is the cleanest way to do that, since it was the only thing the lookup gated. Migration ========= Consumers branching on placeholder leaves of empty fields: -if (field.children[0]?.children[0]?.children[0]?.value === "") { ... } +if (field.children.length === 0) { ... } Config files carrying `experimental.emptyMode` are now rejected by the @glion/config schema validator. Remove that block from .hl7v2rc.* files. @glion/util-query's `value()` helper already returns `null` for empty children — most consumers using it need no change. What changed ============ - @glion/builder: dropped @glion/config dependency entirely; f()/r()/c() now always emit `children: []` for empty inputs. - @glion/parser: dropped emptyMode plumbing from parser.ts/processor.ts/ types.ts. parseHL7v2's settings argument no longer accepts experimental.emptyMode. - @glion/config: removed ExperimentalSchema from the settings schema. The `loadConfig`/`loadConfigAsync` API is unchanged but no longer exposes any experimental keys. - @glion/util-visit: deleted the test-helpers + legacy/empty fixture configs; the visit() implementation was already mode-agnostic. - @glion/jsonify: updated the runtime serializer to materialize empty fields/ repetitions as "" (preserving the existing JSON output shape — empty children now flow through here, where previously legacy always produced a full skeleton with "" leaves). Side effects ============ - @glion/builder/dist/index.js no longer contains `import "@glion/config"`; consumers' bundles shrink (cosmiconfig + dependencies dropped). - The Workers and Deno runtime adapters of @glion/mllp-client (PR #615, #616) bundle cleanly without `nodejs_compat` polyfills; the cosmiconfig bundle leak is resolved. Tests ===== All affected packages green: - @glion/builder: 25 tests - @glion/parser: 56 tests (parser.legacy.test.ts + processor.legacy.test.ts deleted; their behaviour is now the default) - @glion/config: 34 tests - @glion/util-query: 224 tests - @glion/util-visit: 31 tests (visit.legacy.test.ts deleted; redundant) - @glion/jsonify: 12 tests - @glion/hl7v2: 9 tests The pre-existing @glion/cli config-discover.test.ts flake (.js vs .ts) is unrelated and was already failing on main before this PR. https://claude.ai/code/session_01MvBEUcGkRokNw2GWYVHADg
claude/sunset-legacy-empty-mode
2 days ago

Latest Branches

CodSpeed Performance Gauge
0%
feat(mllp-client): Cloudflare Workers runtime adapter#616
1 day ago
4d8edeb
claude/mllp-client-workers-runtime
CodSpeed Performance Gauge
+12%
feat!: sunset legacy empty-mode; remove loadConfig from @glion/builder#624
2 days ago
baf9431
claude/sunset-legacy-empty-mode
CodSpeed Performance Gauge
0%
2 days ago
ada4336
dependabot/npm_and_yarn/vitest/coverage-v8-4.1.5
© 2026 CodSpeed Technology
Home Terms Privacy Docs