Merge remote-tracking branch 'origin/master' into worktree/i18n-complete-non-readme

# Conflicts:
#	packages/client/i18n/README.md
#	packages/client/locale/README.i18n.yaml
#	packages/client/locale/README.zh.md
#	packages/client/ui-layout/README.md
#	packages/client/ui-theme/README.md
This commit is contained in:
Tianyi Cui
2026-07-26 14:37:46 +08:00
136 files changed
+4696 -459

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
/**
* Declaration-aware registration deferral: the shared timing machinery for
* registering into a slot whose declaring entry activates in unconstrained
* order (dshClient.inject edges never sequence apply). Presence is judged on
* the LEDGER, not a local flag — after an HMR collapse re-declares the slot,
* the cascade has already removed the entry while the local disposer went
* stale, and a flag guard would block the re-registration.
*/
/** Minimal registry face the deferral reads (SlotsService satisfies it). */
export interface DeferralRegistry {
/** Declared spec lookup (undefined = not declared yet). */
spec(name: string): unknown
/** Current entries of the slot (component identity is the presence judge). */
entries(name: string): readonly { component: unknown }[]
/** Subscribe to the slot's ledger changes; returns the unsubscriber. */
subscribe(name: string, listener: () => void): () => void
}
/** Handle over one deferred registration. */
export interface DeferredRegistration {
/**
* Drop the current registration (stale disposers are harmless no-ops) and
* immediately re-attempt — the refresh path for registrants whose options
* carry localized text.
*/
refresh(): void
/** Unsubscribe and unregister (idempotent through the slot core). */
dispose(): void
}
/**
* Register into `name` as soon as its declaration is on the ledger, and
* re-register whenever the declaration reappears after a collapse.
* @param registry - the slot registry face.
* @param name - target slot name.
* @param component - the component whose ledger presence marks "registered".
* @param register - performs the actual registration; returns its disposer.
* @returns the deferral handle (dispose in the owning effect's disposer).
*/
export function deferRegistration(
registry: DeferralRegistry,
name: string,
component: unknown,
register: () => () => void,
): DeferredRegistration {
let dispose: (() => void) | undefined
const tryRegister = (): void => {
if (registry.spec(name) === undefined) return
if (registry.entries(name).some(e => e.component === component)) return
dispose = register()
}
const unsubscribe = registry.subscribe(name, () => { tryRegister() })
tryRegister()
return {
refresh() {
dispose?.()
dispose = undefined
tryRegister()
},
dispose() {
unsubscribe()
dispose?.()
},
}
}
+1
View File
@@ -18,6 +18,7 @@ import type { BoundActions, HandleOf, PropsStore, SnapshotSelectorHook, StoreDec
export * from './store.ts'
export * from './renderer.ts'
export * from './deferred.ts'
/** Slot contract table. Owners extend via declaration merging; entries are {@link SlotEntryDef}. */
export interface SlotMap {}