mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
0b167cc478
Bundle-weight optimization of @plannotator/ui for multi-chunk hosts, requested by Workspaces: the Mermaid runtime and Graphviz engine load inside the render effect, the username dictionary sits behind a synchronous identity generator slot, and KaTeX sits behind a math renderer slot with a loader seam on configurePlannotatorUI. Plannotator's own apps import eager entries (math, identity, and Mermaid for the plan editor) so their behavior is unchanged: single-file builds within noise of main, math typeset on first paint, identities from the full dictionary, and the share portal keeps Mermaid in its entry chunk so its failure surface matches main. Built-HTML registration markers guard the eager imports. Hosts that omit the eager entries get the lazy paths, a one-shot automatic re-attempt, and a Retry affordance on the diagram error panel; the module-map limitation of in-page retries is documented. AI-assisted (Claude) under maintainer direction.
80 lines
2.9 KiB
TypeScript
80 lines
2.9 KiB
TypeScript
/**
|
|
* Tater name generator: pure function, no storage dependencies.
|
|
*
|
|
* Extracted to its own module to avoid circular imports:
|
|
* settings.ts needs this for the default value, and identity.ts
|
|
* needs configStore (which imports settings.ts).
|
|
*
|
|
* The full `unique-username-generator` dictionary is NOT imported here. It is
|
|
* registered into the slot below by `./identity-tater`, which every
|
|
* Plannotator entry imports eagerly, so Plannotator mints names from the
|
|
* full dictionary exactly as before. A host that provides its own
|
|
* `identityProvider` never calls the generator and, with the static import
|
|
* gone, no longer ships the word lists.
|
|
*
|
|
* The slot is SYNCHRONOUS on purpose: `configStore.ensureLoaded()` evaluates
|
|
* this default during the first settings read (a render-time read) and
|
|
* persists the result to the identity cookie at once, so a name that arrived
|
|
* later would be a visible identity change. The built-in fallback below keeps
|
|
* the same `{adjective}-{noun}-tater` shape from a small inline pool.
|
|
*/
|
|
|
|
export type IdentityGenerator = () => string;
|
|
|
|
const FALLBACK_ADJECTIVES = [
|
|
'swift', 'gentle', 'brave', 'calm', 'clever', 'bright', 'quiet', 'bold',
|
|
'eager', 'kind', 'lucky', 'merry', 'nimble', 'proud', 'sunny', 'witty',
|
|
] as const;
|
|
|
|
const FALLBACK_NOUNS = [
|
|
'falcon', 'crystal', 'river', 'meadow', 'harbor', 'comet', 'maple', 'otter',
|
|
'summit', 'lantern', 'willow', 'ember', 'pebble', 'breeze', 'orchid', 'canyon',
|
|
] as const;
|
|
|
|
/** Pool words: exported for tests only. */
|
|
export const FALLBACK_IDENTITY_POOL: {
|
|
readonly adjectives: readonly string[];
|
|
readonly nouns: readonly string[];
|
|
} = {
|
|
adjectives: FALLBACK_ADJECTIVES,
|
|
nouns: FALLBACK_NOUNS,
|
|
};
|
|
|
|
function pick<T>(list: readonly T[]): T {
|
|
return list[Math.floor(Math.random() * list.length)]!;
|
|
}
|
|
|
|
/** Built-in generator: same shape as the dictionary one, from a 16 x 16 pool. */
|
|
export const fallbackIdentityGenerator: IdentityGenerator = () =>
|
|
`${pick(FALLBACK_ADJECTIVES)}-${pick(FALLBACK_NOUNS)}-tater`;
|
|
|
|
let generator: IdentityGenerator = fallbackIdentityGenerator;
|
|
|
|
/**
|
|
* Register the generator `generateIdentity()` delegates to. Must return a
|
|
* string synchronously. `./identity-tater` registers the full dictionary;
|
|
* a host may register its own via `configurePlannotatorUI({ identityGenerator })`.
|
|
*/
|
|
export function setIdentityGenerator(next: IdentityGenerator): void {
|
|
generator = next;
|
|
}
|
|
|
|
/** The active generator. Exported so a test can assert which one is registered. */
|
|
export function getIdentityGenerator(): IdentityGenerator {
|
|
return generator;
|
|
}
|
|
|
|
/** Reset to the built-in fallback pool. Mainly for tests. */
|
|
export function resetIdentityGenerator(): void {
|
|
generator = fallbackIdentityGenerator;
|
|
}
|
|
|
|
/**
|
|
* Generate a new random tater identity.
|
|
* Format: {adjective}-{noun}-tater
|
|
* Examples: "swift-falcon-tater", "gentle-crystal-tater"
|
|
*/
|
|
export function generateIdentity(): string {
|
|
return generator();
|
|
}
|