Merge worktree-llm-dynamic-config (884, with latest master) into worktree-llm-web-config

# Conflicts:
#	docs/cordis-catalog/services.md
#	docs/core-data-structures/core.i18n.yaml
#	packages/client/runtime/README.i18n.yaml
#	packages/host/apiproxy/README.i18n.yaml
#	packages/host/apiproxy/README.md
#	packages/host/apiproxy/README.zh.md
This commit is contained in:
Yichen Jiang
2026-07-30 23:32:31 +08:00
117 changed files with 2093 additions and 525 deletions

View File

@@ -859,6 +859,11 @@ export function installSettingsSection<T>(
})
hooks.onChange()
scope.watch(() => {
// A stored change landing while the consumer unloads reaches the watcher
// before the registration is released, and `onChange` is exactly as
// harmful here as in the disposer above: it re-registers routes against
// a fiber whose resources are being let go.
if (isUnloading(ctx)) return
hooks.onChange()
})
})

View File

@@ -724,6 +724,38 @@ describe('installSettingsSection', () => {
await new Promise(resolve => setTimeout(resolve, 20))
expect(changes).toEqual(['user'])
})
it('stays silent for a stored change that lands while the consumer unloads', async () => {
// The watcher outlives the start of teardown by the width of the unload,
// so a document change arriving in that window reaches it. Notifying then
// is exactly as harmful as notifying from the disposer.
const { ctx, provider } = await boot({ doc: { 'helper-ns': { theme: 'user' } } })
const entry = { theme: 'entry' }
let current: () => { theme: string } = () => entry
const changes: string[] = []
const consumer = ctx.plugin({
inject: ['settings'],
apply: (child: Context) => {
installSettingsSection(child, settingsNamespace('helper-ns'), HelperSchema, entry, {
setSource: (source) => {
current = source
},
onChange: () => {
changes.push(current().theme)
},
})
},
})
await consumer
await vi.waitFor(() => {
expect(changes).toEqual(['user'])
})
const unloading = consumer.dispose()
provider.pushExternal({ 'helper-ns': { theme: 'racing' } })
await unloading
expect(changes).toEqual(['user'])
})
})
describe('mutate (path-addressed writes)', () => {