Skip to content

fix(host): release the pricing file source with the fiber, not at apply time - #10

Merged
Max-Samson merged 1 commit into
Max-Samson:mainfrom
rezon-aki:pr/pricing-file-source-disposed
Sep 19, 2026
Merged

Max-Samson merged 1 commit into
Max-Samson:mainfrom
rezon-aki:pr/pricing-file-source-disposed

Conversation

@rezon-aki

Copy link
Copy Markdown
Contributor

Problem

The pricing.json override never applies. /dsh-usage-chart/pricing reports source: "builtin" for every model even when the file exists and parses, and editing the file has no effect (the watcher never fires either).

Root cause

src/index.ts:

ctx.effect(() => fileSource.dispose(), 'dsh-usage-chart: pricing file watcher')

That is an expression-bodied arrow: it calls dispose() while the fiber is being built and registers undefined as the disposer. The file source is destroyed before its first read, so its entries stay {} forever and ensureWatcher() is skipped.

Fix

One line — return a disposer instead of calling it:

ctx.effect(() => () => fileSource.dispose(), 'dsh-usage-chart: pricing file watcher')

Tests

  • The mock effect in tests/core.test.mjs, tests/pricing.test.mjs and tests/rounds.test.mjs now follows cordis semantics (run setup, keep the returned disposer, release it in after()); the previous effect(setup) { setup() } mock discarded the disposer and hid this bug.
  • New regression test: /pricing route serves the user pricing.json override (file source survives startup). Against the old form it fails (source === 'builtin'); with the fix it passes (source === 'file', file price wins).

Verification

npm ci → npm run typecheck → npm test: 41/41 pass (node 22, DSH 0.1.5-rc.2). The live host served deepseek-flash -> file, deepseek-v4-pro -> file from /dsh-usage-chart/pricing after the fix.

…ly time

ctx.effect(() => fileSource.dispose(), ...) calls dispose while the fiber is
being built and registers undefined as the disposer: the file source is dead
before its first read, so pricing.json is never applied and the change watcher
never fires. Return a disposer instead.

Test mocks now follow cordis semantics (run setup, keep the returned disposer,
release it in after()) and a /pricing route regression test covers the override
path - it fails against the old form.
@Max-Samson
Max-Samson self-requested a review September 19, 2026 04:22
@Max-Samson Max-Samson mentioned this pull request Sep 19, 2026
5 tasks done
@Max-Samson
Max-Samson merged commit 885b0dc into Max-Samson:main Sep 19, 2026
rezon-aki added a commit to rezon-aki/dsh-usage-chart that referenced this pull request Sep 19, 2026
rezon-aki added a commit to rezon-aki/dsh-usage-chart that referenced this pull request Sep 20, 2026
rezon-aki added a commit to rezon-aki/dsh-usage-chart that referenced this pull request Sep 23, 2026
- 上游 v1.1.7 已收录本 fork 早先提的 4 项修复(PR Max-Samson#10/Max-Samson#12/Max-Samson#14/Max-Samson#15)与合并事故修复
  (9753856),fork 不再重复维护它们;README / FORK_NOTES 改为「已并入上游」的口径。
- fork 独有改动只剩「面板可拖动」:panel-position.ts(持久化 + 包含块夹取)+
  UsageIndicator 把手/双击复位 + i18n/styles + tests/panel-position.test.mjs,
  直接取自上游 v1.1.7 基线上的实现(与本地 live 仓库同一份代码)。
- CHANGELOG 中英新增 [1.1.7-dsh.1] 段。
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.

2 participants