@wildwinter/app-shell 0.57.0 → 0.58.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +195 -0
  2. package/dist/chunk-4JQWNC6Z.js +319 -0
  3. package/dist/chunk-4JQWNC6Z.js.map +1 -0
  4. package/dist/chunk-ICYPXUNA.js +8 -0
  5. package/dist/chunk-ICYPXUNA.js.map +1 -0
  6. package/dist/{chunk-XJM733E6.js → chunk-OO6O4LEL.js} +6 -2
  7. package/dist/chunk-OO6O4LEL.js.map +1 -0
  8. package/dist/{chunk-CPNTROWD.js → chunk-OZQ2BYXH.js} +13 -4
  9. package/dist/chunk-OZQ2BYXH.js.map +1 -0
  10. package/dist/{chunk-5BKGDTYD.js → chunk-RMQNBWLZ.js} +3 -3
  11. package/dist/{chunk-5BKGDTYD.js.map → chunk-RMQNBWLZ.js.map} +1 -1
  12. package/dist/index.cjs +334 -3
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +2 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.js +4 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/property-list.cjs.map +1 -1
  19. package/dist/property-list.js +2 -2
  20. package/dist/tool-window.cjs +11 -2
  21. package/dist/tool-window.cjs.map +1 -1
  22. package/dist/tool-window.d.cts +10 -4
  23. package/dist/tool-window.d.ts +10 -4
  24. package/dist/tool-window.js +1 -1
  25. package/dist/updater.cjs.map +1 -1
  26. package/dist/updater.js +1 -1
  27. package/dist/value-control.cjs +4 -0
  28. package/dist/value-control.cjs.map +1 -1
  29. package/dist/value-control.d.cts +4 -4
  30. package/dist/value-control.d.ts +4 -4
  31. package/dist/value-control.js +1 -1
  32. package/dist/value-rows.cjs +8 -1
  33. package/dist/value-rows.cjs.map +1 -1
  34. package/dist/value-rows.js +5 -2
  35. package/dist/value-rows.js.map +1 -1
  36. package/dist/view-client.cjs +172 -0
  37. package/dist/view-client.cjs.map +1 -0
  38. package/dist/view-client.d.cts +46 -0
  39. package/dist/view-client.d.ts +46 -0
  40. package/dist/view-client.js +165 -0
  41. package/dist/view-client.js.map +1 -0
  42. package/dist/view-host-web.cjs +327 -0
  43. package/dist/view-host-web.cjs.map +1 -0
  44. package/dist/view-host-web.d.cts +61 -0
  45. package/dist/view-host-web.d.ts +61 -0
  46. package/dist/view-host-web.js +4 -0
  47. package/dist/view-host-web.js.map +1 -0
  48. package/dist/view-host.cjs +532 -0
  49. package/dist/view-host.cjs.map +1 -0
  50. package/dist/view-host.d.cts +178 -0
  51. package/dist/view-host.d.ts +178 -0
  52. package/dist/view-host.js +426 -0
  53. package/dist/view-host.js.map +1 -0
  54. package/dist/view-preload.cjs +16 -0
  55. package/dist/view-preload.cjs.map +1 -0
  56. package/dist/view-preload.js +8 -0
  57. package/dist/view-preload.js.map +1 -0
  58. package/dist/view-protocol.cjs +12 -0
  59. package/dist/view-protocol.cjs.map +1 -0
  60. package/dist/view-protocol.d.cts +257 -0
  61. package/dist/view-protocol.d.ts +257 -0
  62. package/dist/view-protocol.js +3 -0
  63. package/dist/view-protocol.js.map +1 -0
  64. package/package.json +25 -4
  65. package/dist/chunk-CPNTROWD.js.map +0 -1
  66. package/dist/chunk-XJM733E6.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/value-control.ts"],"names":[],"mappings":"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","file":"chunk-OO6O4LEL.js","sourcesContent":["// ---------------------------------------------------------------------------\n// Typed value controls: how both apps show and set a value of a declared type.\n//\n// The first is the quality's. A quality is a step on a ladder, so its value is\n// shown as the LADDER, with the current rung marked, rather than a dropdown that\n// shows one name and hides where it stands (patterkit design/proposals/\n// patter-qualities.md section 4). Storyletter's Board drew it this way first;\n// it lives here so Storyletter's Fields tab, Patterpad's play panel and Game\n// Data rows, and the play inspectors all draw the same strip.\n//\n// An UNSET value (a field or game-data value the node leaves out) names what it\n// falls back to, \"default (x)\", by the family's one rule: the declaration's own\n// default, else the type's (a quality's first stage). A value that is no longer\n// a stage (a deleted one) is shown as such, so it can be put back on the ladder.\n//\n// No Electron, no app state: this module is DOM only, and is its own entry point\n// (`@wildwinter/app-shell/value-control`) so a play inspector outside the apps\n// can take it.\n// ---------------------------------------------------------------------------\n\nimport { el, tagChips } from \"./dom.js\";\n\n/** A declaration as these controls read it: a property's, a field's or a game-data field's. */\nexport interface ValueDeclLike {\n type: string;\n default?: unknown;\n /** enum / flags */\n values?: readonly string[];\n /** quality: the ladder, in order */\n stages?: readonly string[];\n}\n\n/**\n * What an unset value of `decl` falls back to, as the words a control shows: its own default where it has\n * one, else its type's (False, 0, the first value, no flags, the first stage, empty text). The kernel's\n * `defaultFor`, in words; a host reads the same value from the bundle.\n */\nexport function fallbackText(decl: ValueDeclLike): string {\n const d = decl.default;\n if (d !== undefined && d !== null) {\n if (typeof d === \"boolean\") return d ? \"True\" : \"False\";\n if (Array.isArray(d)) return d.length === 0 ? \"none\" : d.join(\", \");\n return d === \"\" ? \"none\" : String(d);\n }\n switch (decl.type) {\n case \"boolean\": return \"False\";\n case \"number\": return \"0\";\n case \"enum\": return decl.values?.[0] ?? \"none\";\n case \"quality\": return decl.stages?.[0] ?? \"first stage\";\n case \"flags\": return \"none\";\n default: return \"empty\";\n }\n}\n\n/** The label an unset value shows: \"default (x)\", naming what it falls back to. */\nexport const defaultLabel = (decl: ValueDeclLike): string => `default (${fallbackText(decl)})`;\n\n/**\n * The quiet line under a ladder that has just been reordered: how many gates order against it. A reorder\n * changes no value, and is the one edit that changes what a gate MEANS without saying so (patter-qualities.md\n * section 2), so the editor says so. Empty when no gate orders the quality.\n */\nexport function stageGateNote(gates: number): string {\n if (gates <= 0) return \"\";\n return gates === 1\n ? \"1 gate compares against this ladder, and it now reads the new order.\"\n : `${gates} gates compare against this ladder, and each now reads the new order.`;\n}\n\nexport interface RungStripOptions {\n /** The ladder, in order. */\n stages: readonly string[];\n /** The value held, or undefined when unset: a field or game-data value the node leaves out. */\n value: string | undefined;\n /** The declaration, for what an unset value falls back to (its default, else the first stage). */\n decl?: ValueDeclLike;\n /** Pick a stage. Absent: the strip is read-only. */\n onPick?: (stage: string) => void;\n /** Clear back to unset. With it, the strip leads with \"default (x)\", which clears the value. */\n onClear?: () => void;\n /** The rollover on a rung that is not the current one (default: `Set to \"x\"`). */\n pickTip?: (stage: string) => string;\n /**\n * The document to build in, for a host outside the apps (a play inspector in a page or a frame of its\n * own). Given, rollovers are plain `title`s and the family's themed tooltips are not mounted; the host\n * styles `.seg`, `.seg-opt` and `.shell-rung` itself. Absent: the apps' document and themed rollovers.\n */\n doc?: Document;\n}\n\n/**\n * A quality's value as its ladder: one rung per stage, in order, the current one marked (`on`). Unset, the\n * rung it falls back to is marked as the fallback (`fallback`), and with `onClear` a leading \"default (x)\"\n * option is the current choice. A value that is not a stage (a deleted one) is shown after the ladder,\n * marked `stray`, until a rung is picked.\n */\nexport function rungStrip(opts: RungStripOptions): HTMLElement {\n const make = opts.doc === undefined ? el : (tag: \"span\" | \"button\", props: { className: string; text?: string; tip?: string; onClick?: () => void }) => {\n const node = opts.doc!.createElement(tag);\n node.className = props.className;\n if (props.text !== undefined) node.textContent = props.text;\n if (props.tip !== undefined) { node.title = props.tip; node.setAttribute(\"aria-label\", props.tip); }\n if (props.onClick) node.addEventListener(\"click\", props.onClick);\n if (tag === \"button\") (node as HTMLButtonElement).type = \"button\";\n return node;\n };\n const strip = make(\"span\", { className: \"seg shell-rungs\" });\n const decl: ValueDeclLike = opts.decl ?? { type: \"quality\", stages: opts.stages };\n const unset = opts.value === undefined;\n const fallback = typeof decl.default === \"string\" && opts.stages.includes(decl.default) ? decl.default : opts.stages[0];\n const readOnly = opts.onPick === undefined;\n if (opts.onClear) {\n strip.append(make(\"button\", {\n className: `seg-opt shell-rung shell-rung-default${unset ? \" on\" : \"\"}`, text: defaultLabel(decl),\n tip: unset ? \"Not set here: the declared default holds\" : \"Clear the value, back to the default\",\n onClick: () => { if (!unset) opts.onClear!(); },\n }));\n }\n for (const stage of opts.stages) {\n const current = opts.value === stage;\n const falls = unset && stage === fallback;\n const rung = make(readOnly ? \"span\" : \"button\", {\n className: `seg-opt shell-rung${current ? \" on\" : \"\"}${falls ? \" fallback\" : \"\"}`, text: stage,\n tip: current ? \"The current stage\" : falls ? \"The stage it falls back to\" : readOnly ? stage : (opts.pickTip?.(stage) ?? `Set to \"${stage}\"`),\n ...(readOnly ? {} : { onClick: () => { if (!current) opts.onPick!(stage); } }),\n });\n strip.append(rung);\n }\n if (!unset && !opts.stages.includes(opts.value!)) {\n strip.append(make(\"span\", {\n className: \"seg-opt shell-rung stray on\", text: opts.value!,\n tip: `\"${opts.value}\" is not one of the stages: pick the one it belongs at now`,\n }));\n }\n return strip;\n}\n\n// ---------------------------------------------------------------------------\n// The field row: ONE control for a node's value of a declared field, driven by\n// the declared type, for the family's seven types (text, multiline, number,\n// boolean, enum, flags, quality). Storyletter's card and outcome Fields and\n// Patterpad's Game Data rows both draw it, which settles the disagreements the\n// parity review found (patterkit design/family-parity-2026-10.md item 10):\n//\n// - the declared purpose is shown, under the control, not hidden in a rollover;\n// - unset says what it falls back to, \"default (x)\", by `defaultLabel`;\n// - flags are a picker of the declared values, not comma-separated text;\n// - multiline is a text area;\n// - a value the declaration refuses (not a number, not one of the values, not\n// a stage) is said under the control, and the app may add its own message;\n// - text commits as typed, and Escape puts back what the field held when it\n// took focus (the family's field rule).\n//\n// Committing as typed means a host that redraws on every change (Patterpad's\n// inspector rebuilds its whole stack) would drop the focus at every keystroke.\n// `fieldRows()` is the answer: it hands back the SAME element for the same key\n// across a redraw, updated in place, and gives the focus (and the caret) back\n// to it once the redraw has put it in the page again.\n// ---------------------------------------------------------------------------\n\n/** A value a field row commits: a flags value is the list of names set. */\nexport type FieldValue = string | number | boolean | string[];\n\n/** A field's declaration as the row reads it: a card field's, an outcome field's or a game-data field's. */\nexport interface FieldDeclLike extends ValueDeclLike {\n name: string;\n /** What the field is for, shown under the control. */\n purpose?: string;\n /** A sentence about each value (an enum's values, the flags, a quality's stages, a pick's fixed words), as an\n * extension's manifest gives them: the chosen value's is shown under the control, and each chosen flag's. */\n valueHelp?: Readonly<Record<string, string>>;\n}\n\n/**\n * The help for what `decl` holds: the chosen enum value's, stage's or pick word's (the one it falls back to, when\n * unset), or each chosen flag's, \"name: sentence\" a line each. Empty when the declaration describes none of them.\n */\nexport function valueHelpText(decl: FieldDeclLike, value: unknown): string {\n const help = decl.valueHelp;\n if (help === undefined) return \"\";\n const said = (v: string): string | undefined => (Object.prototype.hasOwnProperty.call(help, v) ? help[v] : undefined);\n if (decl.type === \"enum\" || decl.type === \"quality\") {\n const held = typeof value === \"string\" && value !== \"\" ? value\n : typeof decl.default === \"string\" && decl.default !== \"\" ? decl.default\n : decl.type === \"enum\" ? decl.values?.[0] : decl.stages?.[0];\n return held === undefined ? \"\" : said(held) ?? \"\";\n }\n if (decl.type === \"flags\") {\n const held = Array.isArray(value) ? value.map(String) : Array.isArray(decl.default) ? decl.default.map(String) : [];\n return held.flatMap((v) => { const h = said(v); return h === undefined ? [] : [`${v}: ${h}`]; }).join(\"\\n\");\n }\n if (decl.type === \"pick\") {\n // A pick's help describes its fixed words only; empty is automatic, so nothing is chosen to describe.\n const held = typeof value === \"string\" && value !== \"\" ? value : typeof decl.default === \"string\" ? decl.default : \"\";\n return held === \"\" ? \"\" : said(held) ?? \"\";\n }\n return \"\";\n}\n\nexport interface FieldRowOptions {\n decl: FieldDeclLike;\n /** The node's own value, typed (a flags value is a string list), or undefined where the node sets none. */\n value: unknown;\n /** Commit a value; `undefined` clears it, back to the default. Absent: the row is read-only. */\n onCommit?: (value: FieldValue | undefined) => void;\n /** Drawn but not editable, as when there is no node to write to. */\n disabled?: boolean;\n /** A message of the app's own about this value (a check the row cannot make), shown under the control. */\n problem?: string;\n /** The app's own sentence INSTEAD of the row's (a renamed stage said better than \"not one of the stages\").\n * Given, it is the whole message; `problem` is ignored. */\n replaceProblem?: string;\n /** The caption; default the field's name. */\n label?: string | Node;\n /** Added to the row and its caption, so a row sits in its app's layout. */\n className?: string;\n labelClassName?: string;\n /** The app's class for a text field or select, used instead of the shell's `.field`. */\n controlClassName?: string;\n}\n\nexport interface FieldRowHandle {\n /** The row: its caption, then the control with the purpose and any message under it. */\n readonly el: HTMLElement;\n /** Redraw for a new value, declaration or message, keeping the element. A field being typed in keeps its\n * text: what the author is typing is newer than what the app last stored. */\n update(opts: FieldRowOptions): void;\n}\n\n/** The type's fallback as a value, for a flags picker to start from when the node sets none. */\nconst fallbackFlags = (decl: ValueDeclLike): string[] => (Array.isArray(decl.default) ? decl.default.filter((v): v is string => typeof v === \"string\") : []);\n\n/** What the row says about a value the declaration refuses, or \"\" when it fits. */\nexport function fieldValueProblem(decl: ValueDeclLike, value: unknown): string {\n if (value === undefined || value === null || value === \"\") return \"\";\n switch (decl.type) {\n case \"number\":\n return typeof value === \"number\" && Number.isFinite(value) ? \"\" : \"Not a number.\";\n case \"boolean\":\n return typeof value === \"boolean\" ? \"\" : \"Not True or False.\";\n case \"enum\":\n return decl.values && !decl.values.includes(String(value)) ? `\"${String(value)}\" is not one of the values.` : \"\";\n case \"quality\":\n return decl.stages && !decl.stages.includes(String(value)) ? `\"${String(value)}\" is not one of the stages.` : \"\";\n case \"flags\": {\n if (!Array.isArray(value)) return \"Not a list of flags.\";\n const strays = decl.values ? value.filter((v) => !decl.values!.includes(String(v))) : [];\n if (strays.length === 0) return \"\";\n return strays.length === 1 ? `\"${String(strays[0])}\" is not one of the values.` : `${strays.map((s) => `\"${String(s)}\"`).join(\", \")} are not among the values.`;\n }\n default:\n return \"\";\n }\n}\n\nconst isTextual = (type: string): boolean => type !== \"boolean\" && type !== \"enum\" && type !== \"flags\" && type !== \"quality\";\n\n/** Everything that decides which control is drawn: a change here rebuilds it, anything else updates it. */\nconst controlShape = (o: FieldRowOptions): string => JSON.stringify([\n o.decl.type, o.decl.values ?? null, o.decl.stages ?? null, o.decl.default ?? null,\n o.onCommit === undefined, o.disabled === true, o.controlClassName ?? \"\",\n o.decl.type === \"quality\" && (o.decl.stages?.length ?? 0) === 0,\n]);\n\n/**\n * One declared field's value as a row: the caption, then the control the declared type calls for, with the\n * purpose and any message under it. See the section comment above for the rules it carries.\n */\nexport function fieldRow(initial: FieldRowOptions): FieldRowHandle {\n let opts = initial;\n const row = el(\"div\", `shell-fieldrow${opts.className ? ` ${opts.className}` : \"\"}`);\n const caption = el(\"span\", `shell-fieldrow-label${opts.labelClassName ? ` ${opts.labelClassName}` : \"\"}`);\n caption.id = `shell-fr-${Math.random().toString(36).slice(2, 9)}`;\n const body = el(\"div\", \"shell-fieldrow-body\");\n const purpose = el(\"p\", \"shell-fieldrow-purpose\");\n const valueHelp = el(\"p\", \"shell-fieldrow-purpose shell-fieldrow-valuehelp\");\n const problem = el(\"p\", \"shell-fieldrow-problem\");\n problem.setAttribute(\"role\", \"status\");\n row.append(caption, body);\n\n let shape = \"\";\n /** Redraw the control for the current value; set by whichever control is built. */\n let show: (value: unknown) => void = () => {};\n /** A local problem the control found while typing (a number that is not one yet). */\n let typing = \"\";\n\n const commit = (v: FieldValue | undefined): void => { opts.onCommit?.(v); };\n const editable = (): boolean => opts.onCommit !== undefined && opts.disabled !== true;\n // An app's own field class replaces the shell's `.field`, so its controls look like its other fields.\n const ctl = (base: string): string => (opts.controlClassName ? `${base.replace(/^field /, \"\")} ${opts.controlClassName}` : base);\n const labelledBy = (node: HTMLElement): void => {\n node.setAttribute(\"aria-labelledby\", caption.id);\n const described = [purpose.id, problem.id].filter(Boolean).join(\" \");\n if (described) node.setAttribute(\"aria-describedby\", described);\n };\n purpose.id = `${caption.id}-p`; problem.id = `${caption.id}-m`;\n\n const sayProblem = (): void => {\n // The chosen value's own help travels with every change of value, as the message does.\n const help = valueHelpText(opts.decl, opts.value);\n valueHelp.textContent = help;\n valueHelp.hidden = help === \"\";\n const words = opts.replaceProblem !== undefined\n ? [opts.replaceProblem].filter((w) => w !== \"\")\n : [typing || fieldValueProblem(opts.decl, opts.value), opts.problem ?? \"\"].filter((w) => w !== \"\");\n problem.textContent = words.join(\" \");\n problem.hidden = words.length === 0;\n row.classList.toggle(\"has-problem\", words.length > 0);\n row.classList.toggle(\"shell-fieldrow-textual\", isTextual(opts.decl.type));\n };\n\n const build = (): HTMLElement => {\n const decl = opts.decl;\n typing = \"\";\n if (decl.type === \"quality\" && (decl.stages?.length ?? 0) > 0) {\n const holder = el(\"span\", \"shell-fieldrow-rungs\");\n show = (value) => {\n holder.replaceChildren(rungStrip({\n stages: decl.stages!, value: typeof value === \"string\" && value !== \"\" ? value : undefined, decl,\n ...(editable() ? { onPick: (stage: string) => { opts = { ...opts, value: stage }; show(stage); sayProblem(); commit(stage); }, onClear: () => { opts = { ...opts, value: undefined }; show(undefined); sayProblem(); commit(undefined); } } : {}),\n }));\n const strip = holder.firstElementChild as HTMLElement | null;\n if (strip) { strip.setAttribute(\"role\", \"group\"); labelledBy(strip); }\n };\n return holder;\n }\n if (decl.type === \"boolean\" || decl.type === \"enum\") {\n const sel = el(\"select\", ctl(\"field shell-fieldrow-select\"));\n labelledBy(sel);\n sel.disabled = !editable();\n const choices: Array<[string, string]> = decl.type === \"boolean\"\n ? [[\"true\", \"True\"], [\"false\", \"False\"]]\n : (decl.values ?? []).map((v): [string, string] => [v, v]);\n show = (value) => {\n const current = value === undefined || value === null || value === \"\" ? \"\" : String(value);\n sel.replaceChildren();\n const add = (v: string, label: string): void => { const o = el(\"option\", undefined, label); o.value = v; sel.append(o); };\n add(\"\", defaultLabel(decl));\n for (const [v, label] of choices) add(v, label);\n // A value the declaration no longer offers stays visible, so the author sees what is held.\n if (current !== \"\" && !choices.some(([v]) => v === current)) add(current, current);\n sel.value = current;\n };\n sel.addEventListener(\"change\", () => {\n const raw = sel.value;\n const v: FieldValue | undefined = raw === \"\" ? undefined : decl.type === \"boolean\" ? raw === \"true\" : raw;\n opts = { ...opts, value: v }; sayProblem(); commit(v);\n });\n return sel;\n }\n if (decl.type === \"flags\" && (decl.values?.length ?? 0) > 0) {\n const holder = el(\"span\", \"shell-flags\");\n holder.setAttribute(\"role\", \"group\");\n labelledBy(holder);\n show = (value) => {\n const unset = !Array.isArray(value);\n const held = unset ? fallbackFlags(decl) : (value as unknown[]).map(String);\n holder.replaceChildren();\n const chip = (text: string, cls: string, pressed: boolean | undefined, tip: string, onClick?: () => void): void => {\n const b = el(onClick && editable() ? \"button\" : \"span\", { className: `shell-flag${cls}`, text, tip });\n b.setAttribute(\"aria-label\", `${text}: ${tip}`); // the tip alone would hide the value's name\n if (b instanceof HTMLButtonElement) { b.type = \"button\"; b.addEventListener(\"click\", onClick!); }\n if (pressed !== undefined) b.setAttribute(\"aria-pressed\", String(pressed));\n holder.append(b);\n };\n const set = (next: string[] | undefined): void => { opts = { ...opts, value: next }; show(next); sayProblem(); commit(next); };\n chip(defaultLabel(decl), ` shell-flag-default${unset ? \" on\" : \"\"}`, undefined,\n unset ? \"Not set here: the declared default holds\" : \"Clear the value, back to the default\",\n unset ? undefined : () => set(undefined));\n for (const v of decl.values!) {\n const on = held.includes(v);\n chip(v, `${on ? \" on\" : \"\"}${on && unset ? \" fallback\" : \"\"}`, on, on ? `Unset ${v}` : `Set ${v}`,\n () => set(on ? held.filter((x) => x !== v) : decl.values!.filter((x) => x === v || held.includes(x)).concat(held.filter((x) => !decl.values!.includes(x)))));\n }\n // A held value the declaration does not offer: shown, struck, and a click drops it.\n for (const v of held.filter((x) => !decl.values!.includes(x))) {\n chip(v, \" stray on\", true, `\"${v}\" is not one of the values: click to drop it`, () => set(held.filter((x) => x !== v)));\n }\n };\n return holder;\n }\n if (decl.type === \"flags\") {\n // No values declared to pick from: the shell's chip editor, each name typed.\n const holder = el(\"span\", \"shell-fieldrow-chips\");\n show = (value) => {\n const box = { values: Array.isArray(value) ? (value as unknown[]).map(String) : [] };\n const chips = tagChips(box, () => {\n const next = box.values.length > 0 ? [...box.values] : undefined;\n opts = { ...opts, value: next }; sayProblem(); commit(next);\n });\n const input = chips.querySelector(\"input\");\n if (input) { labelledBy(input); input.placeholder = Array.isArray(value) ? \"Add value\" : defaultLabel(decl); input.disabled = !editable(); }\n chips.querySelectorAll(\"button\").forEach((b) => { (b as HTMLButtonElement).disabled = !editable(); });\n holder.replaceChildren(chips);\n };\n return holder;\n }\n // text, multiline, number, and any type the row does not know: typed, committed as typed.\n const multiline = decl.type === \"multiline\";\n const field = multiline ? el(\"textarea\", ctl(\"field shell-fieldrow-text\")) : el(\"input\", ctl(\"field shell-fieldrow-text\"));\n if (field instanceof HTMLInputElement) {\n field.type = \"text\";\n if (decl.type === \"number\") field.inputMode = \"decimal\";\n } else field.rows = 3;\n labelledBy(field);\n field.placeholder = defaultLabel(decl);\n field.disabled = !editable();\n const asText = (value: unknown): string =>\n value === undefined || value === null ? \"\" : Array.isArray(value) ? value.join(\", \") : String(value);\n const read = (raw: string): { value?: FieldValue; bad?: string } => {\n if (raw.trim() === \"\") return {};\n if (decl.type !== \"number\") return { value: raw };\n const n = Number(raw.trim());\n return Number.isFinite(n) ? { value: n } : { bad: \"Not a number.\" };\n };\n let atFocus = \"\";\n show = (value) => {\n // What the author is typing is newer than the stored value, so a focused field keeps its text.\n // So does one the author was in when a redraw took the row out of the page, until they leave it.\n if (field.ownerDocument.activeElement === field || keeper.restoring(field) || keeper.holds(row)) return;\n field.value = asText(value);\n };\n const take = (): void => {\n const r = read(field.value);\n typing = r.bad ?? \"\";\n if (r.bad === undefined) opts = { ...opts, value: r.value };\n sayProblem();\n if (r.bad === undefined) commit(r.value);\n };\n field.addEventListener(\"focus\", () => { if (!keeper.restoring(field)) atFocus = field.value; });\n field.addEventListener(\"input\", take);\n field.addEventListener(\"keydown\", (e) => {\n if ((e as KeyboardEvent).key !== \"Escape\" || field.value === atFocus) return;\n field.value = atFocus;\n take();\n });\n return field;\n };\n\n const draw = (next: FieldRowOptions): void => {\n const decl = next.decl;\n const label = next.label ?? decl.name;\n if (typeof label === \"string\") caption.textContent = label; else caption.replaceChildren(label);\n caption.className = `shell-fieldrow-label${next.labelClassName ? ` ${next.labelClassName}` : \"\"}`;\n row.className = `shell-fieldrow${next.className ? ` ${next.className}` : \"\"}`;\n const nextShape = controlShape(next);\n opts = next;\n if (nextShape !== shape) {\n shape = nextShape;\n body.replaceChildren(build());\n }\n show(next.value);\n purpose.textContent = decl.purpose ?? \"\";\n if (decl.purpose) body.append(purpose); else purpose.remove();\n body.append(valueHelp, problem);\n sayProblem();\n };\n\n draw(initial);\n keeper.watch(row);\n return { el: row, update: draw };\n}\n\n// --- keeping the focus across a redraw -------------------------------------\n//\n// A host that rebuilds its view takes the row out of the page and puts it back.\n// Taking a focused element out drops its focus, which is the same thing as\n// the author losing their place mid-word. So a row remembers whether the\n// author was in it, and where the caret was, and the cache gives both back\n// once the row is in the page again (a microtask: after the host's redraw).\n\ninterface FocusMemo { field: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement; start: number | null; end: number | null }\n\nconst keeper = (() => {\n const memos = new WeakMap<HTMLElement, FocusMemo>();\n const restoringNow = new WeakSet<Element>();\n /** When each row was last handed back by the cache, to tell a move's late blur from the author's. */\n const redrawn = new WeakMap<HTMLElement, number>();\n const put = (row: HTMLElement): void => {\n const memo = memos.get(row);\n if (!memo) return;\n const doc = row.ownerDocument;\n const active = doc.activeElement;\n if (!row.isConnected || !memo.field.isConnected || !row.contains(memo.field)) return;\n if (active && active !== doc.body && !row.contains(active)) { memos.delete(row); return; }\n if (active === memo.field && memo.field.matches(\":focus\")) return;\n restoringNow.add(memo.field);\n try {\n memo.field.focus({ preventScroll: true });\n if (!(memo.field instanceof HTMLSelectElement) && memo.start !== null) memo.field.setSelectionRange(memo.start, memo.end ?? memo.start);\n } finally { restoringNow.delete(memo.field); }\n };\n return {\n watch(row: HTMLElement): void {\n const note = (e: Event): void => {\n const t = e.target;\n if (!(t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement)) return;\n const text = !(t instanceof HTMLSelectElement);\n memos.set(row, { field: t, start: text ? (t as HTMLInputElement).selectionStart : null, end: text ? (t as HTMLInputElement).selectionEnd : null });\n };\n row.addEventListener(\"focusin\", note);\n row.addEventListener(\"input\", note);\n row.addEventListener(\"keyup\", note);\n row.addEventListener(\"mouseup\", note);\n // A blur the author made (the row still in the page) forgets; one caused by the row leaving the page\n // does not, and is what the cache puts back. Chromium drops the focus of a moved element LATE: the\n // blur arrives after the redraw, the row already back in the page, so a blur to nowhere just after a\n // redraw is the move's, and the focus goes straight back.\n // Chromium may also fire that blur synchronously, as the host clears its view and before the cache\n // has handed the row back: so the decision waits for the microtask, by which time a row the redraw\n // asked for again is marked as redrawn since the blur.\n row.addEventListener(\"focusout\", (e) => {\n const at = performance.now();\n const late = (e as FocusEvent).relatedTarget === null && at - (redrawn.get(row) ?? -Infinity) < 250;\n if (late && memos.has(row)) { queueMicrotask(() => put(row)); return; }\n queueMicrotask(() => {\n if ((redrawn.get(row) ?? -Infinity) >= at) { put(row); return; }\n if (row.isConnected && !row.contains(row.ownerDocument.activeElement)) memos.delete(row);\n });\n });\n },\n /** Give the focus back to the row, if the author was in it and has not gone anywhere else since. */\n restore(row: HTMLElement): void {\n if (!memos.has(row)) return;\n redrawn.set(row, performance.now());\n // At the microtask, not now: the event that caused the redraw may still note the caret.\n queueMicrotask(() => put(row));\n },\n restoring: (field: Element): boolean => restoringNow.has(field),\n /** Forget the row's focus if the author has since gone somewhere else (before the row is redrawn). */\n settle(row: HTMLElement): void {\n const active = row.ownerDocument.activeElement;\n if (active && active !== row.ownerDocument.body && !row.contains(active)) memos.delete(row);\n },\n /** The row the author is in (before a redraw takes it out). */\n holds: (row: HTMLElement): boolean => memos.has(row),\n };\n})();\n\n/**\n * The focus keeping `fieldRows` does, for a host (or a structured row) that keeps row elements itself: call\n * `settle` before it updates a row and `restore` once the row is back in the page.\n */\nexport const fieldRowFocus = {\n settle: (row: HTMLElement): void => keeper.settle(row),\n restore: (row: HTMLElement): void => keeper.restore(row),\n};\n\nexport interface FieldRows {\n /**\n * The row for `key` (a node and a field, say `${nodeId}:${field}`): the same element as last time when\n * there was one, updated for these options, else a new one. A row the author was typing in gets its focus\n * and caret back once the redraw has put it in the page.\n */\n row(key: string, opts: FieldRowOptions): HTMLElement;\n /** Forget every row not asked for since the last sweep (call at the end of a redraw). */\n sweep(): void;\n}\n\n/** A cache of field rows for a host that redraws its whole view on every change. */\nexport function fieldRows(): FieldRows {\n const rows = new Map<string, { handle: FieldRowHandle; used: boolean }>();\n return {\n row(key, opts) {\n const had = rows.get(key);\n if (had) {\n had.used = true;\n keeper.settle(had.handle.el);\n had.handle.update(opts);\n keeper.restore(had.handle.el);\n return had.handle.el;\n }\n const handle = fieldRow(opts);\n rows.set(key, { handle, used: true });\n return handle.el;\n },\n sweep() {\n for (const [key, entry] of rows) { if (!entry.used) rows.delete(key); else entry.used = false; }\n },\n };\n}\n"]}
@@ -124,6 +124,9 @@ function openToolWindow(existing, opts) {
124
124
  existing.focus();
125
125
  return existing;
126
126
  }
127
+ if (opts.url === void 0 && (opts.page === void 0 || opts.rendererDir === void 0)) {
128
+ throw new Error("openToolWindow needs a url, or a page and its rendererDir");
129
+ }
127
130
  const w = new BrowserWindow({
128
131
  ...opts.rect,
129
132
  ...opts.min !== void 0 ? { minWidth: opts.min.width, minHeight: opts.min.height } : {},
@@ -134,14 +137,20 @@ function openToolWindow(existing, opts) {
134
137
  contextIsolation: true,
135
138
  nodeIntegration: false,
136
139
  sandbox: true,
137
- preload: opts.preload
140
+ // Electron's defaults, said out loud: no webview tag, and a dropped file never navigates the window.
141
+ webviewTag: false,
142
+ navigateOnDragDrop: false,
143
+ preload: opts.preload,
144
+ ...opts.partition !== void 0 ? { partition: opts.partition } : {},
145
+ ...opts.devTools !== void 0 ? { devTools: opts.devTools } : {}
138
146
  }
139
147
  });
140
148
  if (opts.pinTo !== void 0) pinToolWindow(w, opts.pinTo(), opts.pinned ?? false);
141
149
  if (opts.remember) rememberBounds(w, opts.remember);
142
150
  w.once("ready-to-show", () => w.show());
143
151
  if (opts.onClosed) w.on("closed", opts.onClosed);
144
- if (process.env["ELECTRON_RENDERER_URL"]) void w.loadURL(`${process.env["ELECTRON_RENDERER_URL"]}/${opts.page}`);
152
+ if (opts.url !== void 0) void w.loadURL(opts.url);
153
+ else if (process.env["ELECTRON_RENDERER_URL"]) void w.loadURL(`${process.env["ELECTRON_RENDERER_URL"]}/${opts.page}`);
145
154
  else void w.loadFile(join(opts.rendererDir, opts.page));
146
155
  return w;
147
156
  }
@@ -209,5 +218,5 @@ function defineToolWindows(specs, env) {
209
218
  }
210
219
 
211
220
  export { centeredOnPrimary, defineToolWindows, frontForModal, openToolWindow, pinToolWindow, rememberBounds, rescueToolWindow, savedWindowRect };
212
- //# sourceMappingURL=chunk-CPNTROWD.js.map
213
- //# sourceMappingURL=chunk-CPNTROWD.js.map
221
+ //# sourceMappingURL=chunk-OZQ2BYXH.js.map
222
+ //# sourceMappingURL=chunk-OZQ2BYXH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tool-window.ts"],"names":[],"mappings":"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","file":"chunk-OZQ2BYXH.js","sourcesContent":["// ---------------------------------------------------------------------------\n// The tool-window kit, MAIN-PROCESS half: the detached helper-window\n// machinery both apps had grown four copies of (Patterpad's Play + Search +\n// Coverage, Storyletter's Board + Find). Remembered bounds with a\n// disconnected-monitor guard, debounced persistence, the Reset View rescue,\n// and the pinnable window factory they compose into.\n//\n// This module imports electron, so it ships as its own subpath\n// (@wildwinter/app-shell/tool-window) - never import it from renderer code.\n// The renderer half (pin button, .swin drag-bar grammar) lives in the root\n// export + tool-window.css.\n//\n// Two deliberate corrections over the Patterpad originals, for when it\n// migrates here: rescueToolWindow re-pins EVERY window it rescues (Patterpad\n// re-pinned only Play, so its store lied about Search + Coverage), and the\n// factory always wires closed-cleanup through an identity guard.\n// ---------------------------------------------------------------------------\n\nimport { BrowserWindow, app, screen } from \"electron\";\nimport { join } from \"node:path\";\nimport type { Satellite } from \"./session.js\";\n\nexport interface ToolWindowSize {\n width: number;\n height: number;\n}\n\nexport interface ToolWindowBounds {\n x?: number;\n y?: number;\n width: number;\n height: number;\n}\n\n/** The per-window store slice every app remembers: where it was, whether it\n * floats. (Patterpad's PlayWindowState, generalised.) */\nexport interface ToolWindowState {\n bounds?: ToolWindowBounds;\n pinned: boolean;\n}\n\n/** Use a remembered rect only if it still intersects a live display (a window\n * saved on a now-disconnected monitor must not open offscreen). Falls back\n * to the default size; a remembered size is kept even when the position is\n * dropped (Electron then centres it). */\nexport function savedWindowRect(\n saved: ToolWindowBounds | undefined,\n def: ToolWindowSize,\n min: ToolWindowSize,\n): ToolWindowBounds {\n if (!saved) return { ...def };\n const w = Math.max(min.width, saved.width), h = Math.max(min.height, saved.height);\n if (saved.x != null && saved.y != null) {\n const onScreen = screen.getAllDisplays().some((d) => {\n const a = d.workArea;\n return saved.x! + w > a.x + 40 && saved.x! < a.x + a.width - 40 && saved.y! + h > a.y + 20 && saved.y! < a.y + a.height - 20;\n });\n if (onScreen) return { x: saved.x, y: saved.y, width: w, height: h };\n }\n return { width: w, height: h };\n}\n\n/** Persist a helper window's bounds as the user moves / resizes / closes it\n * (debounced 400ms; close flushes synchronously). */\nexport function rememberBounds(w: BrowserWindow, write: (bounds: ToolWindowBounds) => void): void {\n const saveBounds = (): void => { if (!w.isDestroyed()) write(w.getBounds()); };\n let boundsTimer: ReturnType<typeof setTimeout> | undefined;\n const queueSave = (): void => { clearTimeout(boundsTimer); boundsTimer = setTimeout(saveBounds, 400); };\n w.on(\"resize\", queueSave);\n w.on(\"move\", queueSave);\n w.on(\"close\", () => { clearTimeout(boundsTimer); saveBounds(); });\n}\n\n/** Centre a rect on the primary display's work area. */\nexport function centeredOnPrimary(size: ToolWindowSize): { x: number; y: number } {\n const a = screen.getPrimaryDisplay().workArea;\n return { x: Math.round(a.x + (a.width - size.width) / 2), y: Math.round(a.y + (a.height - size.height) / 2) };\n}\n\n/** Reset View's per-window half: un-minimise, re-pin (always - the store\n * says pinned:true after a rescue, so the window must agree), default size,\n * centred on the primary display, shown. The host clears its remembered\n * bounds itself (that's a store concern). No focus steal: helpers show\n * behind the editor. */\nexport function rescueToolWindow(w: BrowserWindow | undefined | null, def: ToolWindowSize): void {\n if (!w || w.isDestroyed()) return;\n if (w.isMinimized()) w.restore();\n w.setBounds({ ...def, ...centeredOnPrimary(def) });\n w.show();\n // Raise within OUR stack. This used to setAlwaysOnTop(true), which on macOS\n // and Windows floats the window above every other APPLICATION - and stuck\n // that way, since nothing ever unset it.\n w.moveTop();\n}\n\n/** macOS pinned windows, for the activation toggle below. */\nconst macPinned = new Set<BrowserWindow>();\nlet macActivationWired = false;\nfunction wireMacActivation(): void {\n if (macActivationWired) return;\n macActivationWired = true;\n // Floating is a GLOBAL window level: left on while another app is front,\n // the pinned window would sit over that app too - the exact 2026-08-25\n // complaint. Scoping it to our app's active state keeps the pin meaning\n // \"above my editor\" and nothing more.\n // Not while a modal has the pins held (frontForModal): the editor is in\n // front for it, and coming back to the app must not cover it again.\n app.on(\"did-become-active\", () => { if (pinsHeld > 0) return; for (const w of macPinned) if (!w.isDestroyed()) w.setAlwaysOnTop(true, \"floating\"); });\n app.on(\"did-resign-active\", () => { for (const w of macPinned) if (!w.isDestroyed()) w.setAlwaysOnTop(false); });\n}\n\n/**\n * The pin: keep a tool window above THIS APP'S MAIN WINDOW, not above the\n * world. Two findings shaped the mechanism, one per platform family:\n *\n * - Bare `alwaysOnTop` (the first implementation) floats the window over\n * every other application on macOS and Windows, so a pinned Board meant\n * nothing else on the machine could come to the front (a Storyletter user\n * report, 2026-08-25).\n * - A CHILD window (the second implementation) is position-coupled to its\n * parent on macOS: dragging the editor dragged the Board with it (a\n * Storyletter user report, 2026-08-28). Windows and Linux owned windows do\n * not move with their owner, so the child mechanism stays right for them.\n *\n * So: on macOS the pin is ACTIVATION-SCOPED alwaysOnTop - floating while\n * this app is active, dropped the moment it resigns - which is above the\n * editor without following its drags and without covering anyone else. On\n * Windows and Linux the pin is a child window, which stays over its parent\n * and stacks normally against everything else. Each branch clears the other\n * mechanism first, which also heals a window an older build pinned the old\n * way. `platform` is a seam for the tests; leave it defaulted.\n */\nexport function pinToolWindow(\n w: BrowserWindow | undefined | null, parent: BrowserWindow | undefined | null, on: boolean,\n platform: NodeJS.Platform = process.platform,\n): void {\n if (!w || w.isDestroyed()) return;\n if (platform === \"darwin\") {\n w.setParentWindow(null);\n if (on) {\n if (!macPinned.has(w)) {\n macPinned.add(w);\n w.once(\"closed\", () => macPinned.delete(w));\n }\n wireMacActivation();\n // Raise only when the app is active now and no modal has the pins\n // held; otherwise the next did-become-active, or the release, raises it.\n w.setAlwaysOnTop(pinsHeld === 0 && BrowserWindow.getFocusedWindow() !== null, \"floating\");\n } else {\n macPinned.delete(w);\n w.setAlwaysOnTop(false);\n }\n return;\n }\n w.setAlwaysOnTop(false);\n const owner = on && parent && !parent.isDestroyed() ? parent : null;\n // While a modal has the pins held, remember the choice and apply it at the\n // release, so the editor stays in front until the modal closes.\n if (pinsHeld > 0) {\n if (owner) heldChildren.set(w, owner); else heldChildren.delete(w);\n w.setParentWindow(null);\n return;\n }\n w.setParentWindow(owner);\n}\n\n// ---------------------------------------------------------------------------\n// Fronting the main window for a modal. A pinned tool window rides above the\n// editor by design, so a modal the EDITOR shows (the updater's prompts) opened\n// underneath one: the editor blurred behind its scrim and the prompt was\n// hidden, with nothing on screen to say why (both apps, 2026-10-02, the Play\n// window over the editor). While such a modal is up the pins step aside and\n// the editor comes forward; when it closes, every pin goes back as it was.\n// ---------------------------------------------------------------------------\n\n/** How many modals are holding the pins down. The pins return at zero. */\nlet pinsHeld = 0;\n/** Windows and Linux: the tool windows unparented by the hold, and the window\n * each goes back to. */\nconst heldChildren = new Map<BrowserWindow, BrowserWindow>();\n\n/**\n * Bring `main` in front of every tool window, pinned ones included, for as\n * long as a modal it shows is open: un-minimise, show, focus, with the pins\n * set aside. Returns the release, which puts the pins back (idempotent; holds\n * nest, and the pins return when the last is released). Call it only while\n * the app is active: focusing a window of an inactive app is the focus steal\n * the platforms forbid. `platform` is a seam for the tests.\n */\nexport function frontForModal(main: BrowserWindow, platform: NodeJS.Platform = process.platform): () => void {\n if (main.isDestroyed()) return () => {};\n pinsHeld++;\n if (platform === \"darwin\") {\n for (const w of macPinned) if (!w.isDestroyed()) w.setAlwaysOnTop(false);\n } else {\n for (const w of BrowserWindow.getAllWindows()) {\n if (w === main || w.isDestroyed()) continue;\n const owner = w.getParentWindow();\n if (owner !== main) continue;\n heldChildren.set(w, main);\n w.setParentWindow(null);\n }\n }\n if (main.isMinimized()) main.restore();\n main.show();\n main.focus();\n\n let released = false;\n return () => {\n if (released) return;\n released = true;\n if (--pinsHeld > 0) return;\n if (platform === \"darwin\") {\n // Only float again if the app is active; otherwise did-become-active does.\n const active = BrowserWindow.getFocusedWindow() !== null;\n if (active) for (const w of macPinned) if (!w.isDestroyed()) w.setAlwaysOnTop(true, \"floating\");\n } else {\n for (const [w, owner] of heldChildren) {\n if (!w.isDestroyed() && !owner.isDestroyed()) w.setParentWindow(owner);\n }\n heldChildren.clear();\n }\n };\n}\n\nexport interface ToolWindowOptions {\n title: string;\n /** Renderer entry, relative to rendererDir (e.g. \"table.html\", \"search/index.html\"). Not used with `url`. */\n page?: string;\n /** Absolute path of the built renderer dir (join(import.meta.dirname, \"../renderer\")). Not used with `url`. */\n rendererDir?: string;\n /** Load this URL instead of a page from the renderer dir (a view window's `patter-view://...`). */\n url?: string;\n /** Absolute path of the preload bridge. */\n preload: string;\n /** A session partition of the window's own (a view's in-memory `view-<id>`); the default session otherwise. */\n partition?: string;\n /** Whether the window may open devtools; Electron's default (yes) when absent. */\n devTools?: boolean;\n rect: ToolWindowBounds;\n min?: ToolWindowSize;\n /** false = frameless: the renderer draws its own slim drag bar (.swin-head). */\n frame?: boolean;\n /** The window to PIN ABOVE: the app's main window, resolved at open time (a\n * getter, because the main window can be recreated). With `pinned` true\n * the new tool window rides above it - on macOS via activation-scoped\n * alwaysOnTop (a child window there follows the editor's drags), on\n * Windows and Linux as a child window (bare alwaysOnTop there floats over\n * the whole machine). See pinToolWindow for both findings. */\n pinTo?: () => BrowserWindow | undefined;\n /** Start pinned (the host remembers); flip later with `pinToolWindow`. */\n pinned?: boolean;\n /** Wire debounced bounds persistence into the host's store slice. */\n remember?: (bounds: ToolWindowBounds) => void;\n /** Fired when THIS window closes (identity-guarded; a stale close never\n * clears a newer window). Null the host's handle here. */\n onClosed?: () => void;\n}\n\n/** The pinnable detached-window factory (hardened webPreferences, one\n * preload, electron-vite's dev-URL/file split). Focuses and returns the\n * existing window when there is one; otherwise creates, wires, and loads. */\nexport function openToolWindow(existing: BrowserWindow | undefined | null, opts: ToolWindowOptions): BrowserWindow {\n if (existing && !existing.isDestroyed()) { existing.focus(); return existing; }\n if (opts.url === undefined && (opts.page === undefined || opts.rendererDir === undefined)) {\n throw new Error(\"openToolWindow needs a url, or a page and its rendererDir\");\n }\n const w = new BrowserWindow({\n ...opts.rect,\n ...(opts.min !== undefined ? { minWidth: opts.min.width, minHeight: opts.min.height } : {}),\n show: false,\n title: opts.title,\n ...(opts.frame !== undefined ? { frame: opts.frame } : {}),\n webPreferences: {\n contextIsolation: true, nodeIntegration: false, sandbox: true,\n // Electron's defaults, said out loud: no webview tag, and a dropped file never navigates the window.\n webviewTag: false, navigateOnDragDrop: false,\n preload: opts.preload,\n ...(opts.partition !== undefined ? { partition: opts.partition } : {}),\n ...(opts.devTools !== undefined ? { devTools: opts.devTools } : {}),\n },\n });\n if (opts.pinTo !== undefined) pinToolWindow(w, opts.pinTo(), opts.pinned ?? false);\n if (opts.remember) rememberBounds(w, opts.remember);\n w.once(\"ready-to-show\", () => w.show());\n if (opts.onClosed) w.on(\"closed\", opts.onClosed);\n if (opts.url !== undefined) void w.loadURL(opts.url);\n else if (process.env[\"ELECTRON_RENDERER_URL\"]) void w.loadURL(`${process.env[\"ELECTRON_RENDERER_URL\"]}/${opts.page}`);\n else void w.loadFile(join(opts.rendererDir!, opts.page!));\n return w;\n}\n\n// ---------------------------------------------------------------------------\n// The tool windows AS DATA: one row per window, and everything that walks the\n// windows walks the rows. Lifted from Storyletter's TOOL_WINDOWS table +\n// openToolWindowFor + rescueWindows (studio/src/main/index.ts), where it had\n// replaced four near-identical openX() functions whose differences were all\n// mistakes (only one forwarded its console; Reset View rescued two of four).\n// Patterpad's three hand copies (createPlayWindow / createSearchWindow /\n// createCoverageWindow and a four-branch rescueWindows) become three rows.\n//\n// Two things the table makes structurally impossible: forgetting to register\n// a window as a satellite for the project-changed nudge (every row is\n// registered when a session is given), and Reset View rescuing a subset (it\n// walks the rows).\n// ---------------------------------------------------------------------------\n\n\nexport interface ToolWindowSpec<N extends string = string> {\n /** The window's key: the store slice it remembers under, the dev-console\n * prefix, and what `open(name)` takes. */\n name: N;\n title: string;\n /** Renderer entry, relative to the env's rendererDir. */\n page: string;\n def: ToolWindowSize;\n min: ToolWindowSize;\n /** The remembered rect, read at open time (a store read-through). */\n bounds: () => ToolWindowBounds | undefined;\n /** Persist a moved / resized rect (debounced by the factory). */\n remember: (bounds: ToolWindowBounds) => void;\n /** Whether it starts pinned above the editor (both apps default true). */\n pinned: () => boolean;\n /** Frameless (the family's shape: the renderer draws `toolWindowHead`).\n * Default false = frameless; pass `frame: true` for an OS title bar. */\n frame?: boolean;\n /** The project-changed channel for THIS window when it differs from the\n * env's (Storyletter's Links window listens on \"links:focus\"). */\n channel?: string;\n /** Drop what main caches for the outgoing project on this window's behalf\n * (a coverage report, a search anchor). Runs whether the window is open\n * or not: see session.ts. */\n clear?: () => void;\n}\n\nexport interface ToolWindowEnv {\n /** Absolute path of the built renderer dir. */\n rendererDir: string;\n /** Absolute path of the preload bridge. */\n preload: string;\n /** The window to pin above: the app's main window, resolved at open time. */\n pinTo: () => BrowserWindow | undefined;\n /** Register every row as a satellite of the project session, so a new\n * project cannot open underneath a tool window that still shows the old\n * one. `channel` is the nudge each window listens on (a row may override). */\n session?: { addSatellite: (satellite: Satellite) => () => void; channel: string };\n /** Reset View's store half, run first: forget every remembered rect and\n * set pinned true (`resetWindows(store)` from app-store, or the app's own). */\n resetStore?: () => void;\n /** The channel a rescued window's renderer hears its re-pin on, so its pin\n * button agrees with the store (default \"state:pinned\"). */\n pinChannel?: string;\n /** Runs once per window created: forward its console in dev, say. */\n onOpened?: (w: BrowserWindow, name: string) => void;\n}\n\nexport interface ToolWindows<N extends string> {\n /** Open (or focus) one window by name. */\n open(name: N): BrowserWindow;\n /** The live window, if open. */\n get(name: N): BrowserWindow | undefined;\n /** Reset View's window half, over the table: store reset, then every open\n * window restored, default size, centred, re-pinned, and told so. */\n rescue(): void;\n /** Every window that is open right now. */\n all(): BrowserWindow[];\n readonly names: readonly N[];\n}\n\n/** Build the table. The windows are owned here: a host reads them through\n * `get(name)` rather than holding module variables of its own. */\nexport function defineToolWindows<N extends string>(specs: ToolWindowSpec<N>[], env: ToolWindowEnv): ToolWindows<N> {\n const live = new Map<N, BrowserWindow>();\n const byName = (name: N): ToolWindowSpec<N> => {\n const found = specs.find((s) => s.name === name);\n if (!found) throw new Error(`no tool window \"${name}\"`);\n return found;\n };\n const get = (name: N): BrowserWindow | undefined => {\n const w = live.get(name);\n return w && !w.isDestroyed() ? w : undefined;\n };\n if (env.session) {\n for (const spec of specs) {\n env.session.addSatellite({\n window: () => get(spec.name),\n channel: spec.channel ?? env.session.channel,\n ...(spec.clear ? { clear: spec.clear } : {}),\n });\n }\n }\n const open = (name: N): BrowserWindow => {\n const spec = byName(name);\n const existing = get(name);\n const opened = openToolWindow(existing, {\n title: spec.title, page: spec.page, frame: spec.frame ?? false,\n rendererDir: env.rendererDir, preload: env.preload,\n rect: savedWindowRect(spec.bounds(), spec.def, spec.min),\n min: spec.min,\n pinTo: env.pinTo,\n pinned: spec.pinned(),\n remember: spec.remember,\n });\n if (opened !== existing) {\n live.set(name, opened);\n // Identity-guarded: a stale close never clears a newer window.\n opened.on(\"closed\", () => { if (live.get(name) === opened) live.delete(name); });\n env.onOpened?.(opened, name);\n }\n return opened;\n };\n const rescue = (): void => {\n env.resetStore?.();\n for (const spec of specs) rescueToolWindow(get(spec.name), spec.def);\n // ACTUALLY pin them, then tell them. `rescueToolWindow` restores, resizes,\n // centres and raises but never pins; the store now says pinned, so the\n // window and its button have to agree before the claim is made.\n for (const spec of specs) {\n const w = get(spec.name);\n if (!w) continue;\n pinToolWindow(w, env.pinTo(), true);\n w.webContents.send(env.pinChannel ?? \"state:pinned\", true);\n }\n };\n return {\n open, get, rescue,\n all: () => specs.map((s) => get(s.name)).filter((w): w is BrowserWindow => w !== undefined),\n names: specs.map((s) => s.name),\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { defaultLabel, fallbackText } from './chunk-XJM733E6.js';
1
+ import { defaultLabel, fallbackText } from './chunk-OO6O4LEL.js';
2
2
  import { el, iconBtn, moveItem, labelled, tagChips, stageChips } from './chunk-W4WC4FO5.js';
3
3
 
4
4
  // src/settings.ts
@@ -563,5 +563,5 @@ function mountPropertyList(host, decls, opts = {}) {
563
563
  }
564
564
 
565
565
  export { PROPERTY_NAME_HINT, PROPERTY_TYPES, RESERVED_PROPERTY_NAMES, bindPropertyName, bindPropertyRef, defaultControl, dupGuard, expandableRow, firstIllegalPropertyName, focusNewRow, isCaseOnlyPropertyName, isValidPropertyName, mountPropertyList, mountSettingsDialog, propertyNameProblem, propertyNameify, propertyRefProblem, revalidatePropertyRefs, revealRow, revealRowWhenReady };
566
- //# sourceMappingURL=chunk-5BKGDTYD.js.map
567
- //# sourceMappingURL=chunk-5BKGDTYD.js.map
566
+ //# sourceMappingURL=chunk-RMQNBWLZ.js.map
567
+ //# sourceMappingURL=chunk-RMQNBWLZ.js.map