Skip to content

refactor(utils): canonical subscriber-set observable plus exact-dupe cleanups - #3047

Merged
kwakayama merged 8 commits into
mainfrom
refactor/consolidate-subscriber-sets
Jul 24, 2026
Merged

refactor(utils): canonical subscriber-set observable plus exact-dupe cleanups#3047
kwakayama merged 8 commits into
mainfrom
refactor/consolidate-subscriber-sets

Conversation

@kojiwakayama

@kojiwakayama kojiwakayama commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Third PR in the code-reduction campaign (after #3045, #3046). Six modules hand-rolled the same Set-based subscribe/notify observable with inconsistent notify semantics; this adds one canonical createSubscriberSet to #veryfront/utils and migrates the accidental copies, plus two byte-identical dupe groups flagged by deno task dupes, plus fixes for two review findings against the already-merged #3045.

Note (force-pushed): the original push accidentally contained only the 2 new files — a git stash/stash pop during verification unstaged the 9 migrated files before commit. The amended commit contains the full change set; the earlier bot comments about dead/unwired code are resolved.

Net: −1 line (+163/−164, 13 files). The raw counter is thin because ~40 lines are review-driven additions fixing #3045 fallout (see below); the consolidation itself removes ~120 lines of duplicated logic. 2634 unit tests pass.

Changes

  1. createSubscriberSet<Args>(onListenerError?) — subscribe→unsubscribe, snapshot-during-notify, isolated listener errors (including a throwing onListenerError itself), size/clear. Migrated: observability/error-collector, observability/log-buffer, server/reload-notifier (both listener sets, per-set error logs preserved; dead getInvalidateListenerCount removed), workflow/claude-code/websocket-publisher.
    Two of these sites previously iterated the live Set during notify — a listener unsubscribing mid-notify could skip listeners. Snapshot semantics closes that bug class.
  2. Server-Timing dedupe — the metric-building loop plus roundMs/formatDuration/sanitizeMetricName were duplicated between proxy/server-timing.ts and observability/request-profiler.ts; proxy now uses the exported buildServerTimingValue/roundMs and the format helpers went back to private.
  3. modules/server — four identical findFirstSecureFile/findFirstPlatformFile copies collapsed into one structurally-typed findFirstExistingFile (fs-probe.ts).
  4. refactor(utils): consolidate hash, sleep, and base64 helpers onto canonical utils #3045 review fixes (Codex/Copilot findings on the merged PR):
    • UTF-8 regression in plugin-loader: encodeBase64(code) for data: URLs emits Latin-1 bytes for chars in [0x80–0xFF] via btoa, corrupting non-ASCII plugin source outside Deno. Now encodeBase64Bytes(new TextEncoder().encode(code)), restoring the pre-refactor(utils): consolidate hash, sleep, and base64 helpers onto canonical utils #3045 always-UTF-8 behavior.
    • Bare btoa in base64urlEncodeBytes: now routed through the new fallback-safe encodeBase64Bytes (btoa → Buffer → clear error), and encodeBase64's non-Latin1 fallback reuses it.

Deliberately left (documented in code or genuinely different)

  • rendering/client/navigation-store + react/runtime/core mirror — documented cross-bundle contract; react runtime bundle intentionally imports nothing
  • workflow/claude-code/event-publisher — throwing handlers intentionally propagate; converting would change behavior
  • proxy Redis channel map — keyed pubsub with connection lifecycle, different abstraction

Verification

  • deno task verify:quick exit 0; deno task test:unit 2634 passed / 0 failed; affected suites (observability, proxy, modules/server, workflow, utils, html) pass unmodified; pre-push hook (fmt + full suite) passed on the amended commit

Copilot AI review requested due to automatic review settings July 23, 2026 17:14
@kojiwakayama
kojiwakayama requested a review from kwakayama as a code owner July 23, 2026 17:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new shared utilities intended to reduce duplicated patterns across the codebase, specifically a canonical subscribe/notify listener registry and a shared filesystem probe helper.

Changes:

  • Introduces createSubscriberSet() in src/utils/subscriber-set.ts to standardize Set-backed subscribe/notify behavior (snapshot during notify, optional listener-error hook).
  • Introduces findFirstExistingFile() in src/modules/server/fs-probe.ts to consolidate repeated “probe a list of paths via stat” logic.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/utils/subscriber-set.ts Adds a generic subscriber-set helper intended to replace duplicated Set-based observables.
src/modules/server/fs-probe.ts Adds a helper to probe multiple candidate paths and return the first existing file.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils/subscriber-set.ts
Comment thread src/utils/subscriber-set.ts
Comment thread src/modules/server/fs-probe.ts Outdated
Comment thread src/modules/server/fs-probe.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eada5dd87d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/utils/subscriber-set.ts
Comment thread src/modules/server/fs-probe.ts
…cleanups

Six modules hand-rolled the same Set-based subscribe/notify observable with
inconsistent notify semantics (live vs snapshot iteration, varying error
isolation). This adds createSubscriberSet to #veryfront/utils and migrates
the accidental copies, plus two byte-identical dupe groups found by the
duplicate scanner:

- createSubscriberSet<Args>(onListenerError?): snapshot-during-notify (safe
  mid-notify unsubscribe) with isolated listener errors; migrated
  observability/error-collector, observability/log-buffer,
  server/reload-notifier (both listener sets, log messages preserved), and
  workflow/claude-code/websocket-publisher
- Server-Timing helpers (roundMs, formatDuration, sanitizeMetricName)
  deduplicated: proxy/server-timing now imports them from
  observability/request-profiler
- modules/server: four identical findFirstSecureFile/findFirstPlatformFile
  copies collapsed into one structurally-typed findFirstExistingFile

Deliberately left: rendering/client navigation-store + react/runtime mirror
(documented cross-bundle contract), workflow event-publisher (throwing
handlers intentionally propagate), proxy Redis channel map (keyed lifecycle,
different shape).
Copilot AI review requested due to automatic review settings July 23, 2026 17:35
@kojiwakayama
kojiwakayama force-pushed the refactor/consolidate-subscriber-sets branch from eada5dd to 121b590 Compare July 23, 2026 17:35
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

Review comments addressed in the force-pushed commit:

  • Missing call sites / not exported (Copilot, Codex) — correct catch, thank you. The original commit accidentally contained only the 2 new files (a git stash pop during verification unstaged the 9 migrated files before commit; the pre-push test suite passed because the working tree was complete). The amended commit contains the full migration: barrel export, error-collector, log-buffer, reload-notifier, websocket-publisher, proxy server-timing, and both modules/server call-site files.
  • Throwing onListenerError escapes isolation (Copilot) — fixed; the handler is now wrapped so it can't break notification.
  • fs-probe docstring ambiguity (Copilot) — clarified: first path in paths order wins, probes run in parallel.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/utils/subscriber-set.ts:23

  • createSubscriberSet is a new canonical primitive that changes notification semantics across multiple modules (snapshot iteration, error isolation). It should have focused unit tests covering: (1) snapshot behavior when listeners unsubscribe/subscribe during notify, (2) listener exceptions not stopping later listeners, and (3) a throwing onListenerError not breaking notification.
export function createSubscriberSet<Args extends unknown[] = []>(
  onListenerError?: (error: unknown) => void,
): SubscriberSet<Args> {
  const listeners = new Set<(...args: Args) => void>();

Comment thread src/utils/base64url.ts
Copilot AI review requested due to automatic review settings July 23, 2026 17:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Comment thread src/utils/base64url.ts
Copilot AI review requested due to automatic review settings July 23, 2026 18:59
kwakayama
kwakayama previously approved these changes Jul 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Comment thread src/utils/subscriber-set.ts Outdated
Comment thread src/utils/subscriber-set.ts
Copilot AI review requested due to automatic review settings July 23, 2026 19:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Comment thread src/observability/request-profiler.ts Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 05:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Comment thread src/utils/subscriber-set.test.ts Outdated
Copilot AI review requested due to automatic review settings July 24, 2026 05:54
@kwakayama
kwakayama enabled auto-merge (squash) July 24, 2026 05:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 24, 2026 05:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 15 out of 15 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 24, 2026 06:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@kwakayama
kwakayama merged commit 119ca7e into main Jul 24, 2026
28 checks passed
@kwakayama
kwakayama deleted the refactor/consolidate-subscriber-sets branch July 24, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants