@peripheries/renderer 0.23.0 → 0.23.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 (100) hide show
  1. package/README.md +45 -33
  2. package/dist/catalog.js +2 -6
  3. package/dist/chunks/{forms-CCAE7sCu.js → forms-DxA9WzCt.js} +0 -6
  4. package/dist/chunks/{load-CjPvISzH.js → load-b38vUiZM.js} +0 -4
  5. package/dist/chunks/{page-bundles-DLRIBP8g.js → page-bundles-CPj_vx-J.js} +1 -5
  6. package/dist/chunks/{persistence-DCMakM9H.js → persistence-hurkUUQ0.js} +0 -6
  7. package/dist/chunks/{projection-yvYKzMOS.js → projection-zhu32_KJ.js} +1 -15
  8. package/dist/chunks/{query-LnTbQghF.js → query-D6xQbTFK.js} +0 -6
  9. package/dist/chunks/{refs-BLUokra5.js → refs-Csgh6rXq.js} +0 -4
  10. package/dist/chunks/{structure-BrKSgzRJ.js → structure-CKBtQHJq.js} +1 -7
  11. package/dist/chunks/{validate-B_g7719l.js → validate-BcB_PA1k.js} +2 -10
  12. package/dist/core.js +9 -25
  13. package/dist/forms.js +1 -1
  14. package/dist/print.js +0 -24
  15. package/dist/react.js +4 -22
  16. package/dist/runtime.js +2 -12
  17. package/dist/styles.css +9 -15
  18. package/dist/testing.js +5 -21
  19. package/dist/theme.js +0 -10
  20. package/dist/types/catalog/check.d.ts +0 -13
  21. package/dist/types/core/actions.d.ts +0 -24
  22. package/dist/types/core/bundles/load.d.ts +0 -23
  23. package/dist/types/core/bundles/page-bundles.d.ts +0 -9
  24. package/dist/types/core/bundles/refs.d.ts +1 -28
  25. package/dist/types/core/bundles/resolve.d.ts +0 -10
  26. package/dist/types/core/cell-props.d.ts +0 -20
  27. package/dist/types/core/cells.d.ts +0 -21
  28. package/dist/types/core/data-context.d.ts +0 -22
  29. package/dist/types/core/diagnostics.d.ts +1 -3
  30. package/dist/types/core/graph.d.ts +0 -54
  31. package/dist/types/core/layout.d.ts +0 -9
  32. package/dist/types/core/load-page.d.ts +0 -111
  33. package/dist/types/core/query.d.ts +0 -64
  34. package/dist/types/core/references.d.ts +0 -21
  35. package/dist/types/core/release.d.ts +0 -10
  36. package/dist/types/core/rules.d.ts +0 -1
  37. package/dist/types/core/selected.d.ts +0 -5
  38. package/dist/types/core/sources.d.ts +5 -64
  39. package/dist/types/core/store/create-store.d.ts +0 -6
  40. package/dist/types/core/store/persistence.d.ts +0 -1
  41. package/dist/types/core/store/projection.d.ts +0 -5
  42. package/dist/types/core/store/scope-keys.d.ts +0 -1
  43. package/dist/types/core/store/types.d.ts +0 -6
  44. package/dist/types/core/structure.d.ts +0 -33
  45. package/dist/types/core/types.d.ts +0 -13
  46. package/dist/types/core/validate.d.ts +0 -12
  47. package/dist/types/core/values.d.ts +0 -6
  48. package/dist/types/forms/conditions.d.ts +0 -37
  49. package/dist/types/forms/model.d.ts +0 -44
  50. package/dist/types/forms/port.d.ts +0 -22
  51. package/dist/types/print/document-bindings.d.ts +0 -61
  52. package/dist/types/print/document-profile.d.ts +0 -137
  53. package/dist/types/print/map-staleness.d.ts +0 -66
  54. package/dist/types/print/page-map.d.ts +1 -334
  55. package/dist/types/print/paginate.d.ts +0 -190
  56. package/dist/types/print/print-layout.d.ts +0 -161
  57. package/dist/types/print/print-lint.d.ts +0 -109
  58. package/dist/types/print/print-policy.d.ts +0 -184
  59. package/dist/types/print/print-stylesheet.d.ts +0 -135
  60. package/dist/types/print/running-header.d.ts +0 -86
  61. package/dist/types/print/structure-print.d.ts +1 -243
  62. package/dist/types/react/cell-states.d.ts +0 -2
  63. package/dist/types/react/cell-view.d.ts +0 -16
  64. package/dist/types/react/page-renderer.d.ts +0 -37
  65. package/dist/types/react/structure-view.d.ts +0 -12
  66. package/dist/types/react/use-cell-store.d.ts +0 -5
  67. package/dist/types/react/use-container-size.d.ts +0 -5
  68. package/dist/types/react/use-forms-runtime.d.ts +1 -55
  69. package/dist/types/react/use-paging.d.ts +0 -9
  70. package/dist/types/runtime/boot.d.ts +0 -11
  71. package/dist/types/runtime/install.d.ts +0 -15
  72. package/dist/types/runtime/shims.d.ts +0 -8
  73. package/dist/types/runtime/store-export.d.ts +0 -7
  74. package/dist/types/testing/base-props.d.ts +0 -1
  75. package/dist/types/testing/components.d.ts +0 -8
  76. package/dist/types/testing/form-workbook.d.ts +0 -3
  77. package/dist/types/testing/golden.d.ts +0 -16
  78. package/dist/types/testing/ids.d.ts +0 -2
  79. package/dist/types/testing/sources.d.ts +0 -7
  80. package/dist/types/theme/check.d.ts +0 -2
  81. package/dist/types/theme/color.d.ts +0 -12
  82. package/dist/types/theme/derive.d.ts +0 -12
  83. package/dist/types/theme/parse.d.ts +0 -7
  84. package/package.json +2 -2
  85. package/dist/catalog.js.map +0 -1
  86. package/dist/chunks/forms-CCAE7sCu.js.map +0 -1
  87. package/dist/chunks/load-CjPvISzH.js.map +0 -1
  88. package/dist/chunks/page-bundles-DLRIBP8g.js.map +0 -1
  89. package/dist/chunks/persistence-DCMakM9H.js.map +0 -1
  90. package/dist/chunks/projection-yvYKzMOS.js.map +0 -1
  91. package/dist/chunks/query-LnTbQghF.js.map +0 -1
  92. package/dist/chunks/refs-BLUokra5.js.map +0 -1
  93. package/dist/chunks/structure-BrKSgzRJ.js.map +0 -1
  94. package/dist/chunks/validate-B_g7719l.js.map +0 -1
  95. package/dist/core.js.map +0 -1
  96. package/dist/print.js.map +0 -1
  97. package/dist/react.js.map +0 -1
  98. package/dist/runtime.js.map +0 -1
  99. package/dist/testing.js.map +0 -1
  100. package/dist/theme.js.map +0 -1
@@ -1,41 +1,4 @@
1
- /**
2
- * Values for the region bindings a profile names.
3
- *
4
- * ── The gap this closes ─────────────────────────────────────────────────────
5
- *
6
- * A profile says WHICH margin box holds WHAT: `instrument`'s footer is
7
- * `{ left: 'execution-state', right: 'page-x-of-y' }`. Only the second is
8
- * computable — CSS produces page numbers during pagination. The rest are facts
9
- * about *this document*, which the bundle cannot know and the host must supply.
10
- *
11
- * Until now it supplied none, so every `instrument` page was unprintable:
12
- * `execution-state` is in `requiredBindings`, and a will that does not say
13
- * "Not for execution" is a will that does not say it is a draft.
14
- *
15
- * ── Why the page declares them, keyed by binding name ───────────────────────
16
- *
17
- * `project_page.metadata.document.bindings` — a flat map from binding name to
18
- * string. Keyed by the binding name itself rather than by some host-side
19
- * camelCase alias, because a translation layer is one more place for
20
- * `document-id` and `documentId` to disagree, and because a binding a bundle adds
21
- * then works with no host change at all.
22
- *
23
- * ── What this deliberately does NOT do ──────────────────────────────────────
24
- *
25
- * It does not DERIVE anything. `execution-state` could plausibly be computed
26
- * from a document status — an org's naming system defines DRAFT / REVIEW /
27
- * FINAL / EXECUTED, and is emphatic that *"`FINAL` and `EXECUTED` are not the
28
- * same thing… never collapse these"*. Encoding that mapping here would be
29
- * inventing legal policy in a stylesheet helper, and getting it wrong prints a
30
- * document asserting the wrong status — the exact failure `requiredBindings`
31
- * exists to prevent, arriving through the fix for it.
32
- *
33
- * So: declared values only. A page that has not declared them stays unprintable,
34
- * visibly, with the reason on the button. That is the correct state for a
35
- * document nobody has said the status of.
36
- */
37
1
  import type { PageRegionValues } from './print-stylesheet.js';
38
- /** The `metadata.document` shape. Open — a profile may name bindings we predate. */
39
2
  export interface DocumentBindingsMetadata {
40
3
  bindings?: Record<string, unknown>;
41
4
  }
@@ -45,32 +8,8 @@ interface PageLike {
45
8
  }
46
9
  export interface ResolvedBindings {
47
10
  values: PageRegionValues;
48
- /** Declared keys whose value was not a usable string. Named, never coerced. */
49
11
  malformed: string[];
50
12
  }
51
- /**
52
- * Read declared binding values off a page record.
53
- *
54
- * Non-string values are DROPPED and reported rather than stringified. `42` would
55
- * render as "42" in a footer and look deliberate; `null` would render as "null".
56
- * A footer is read as an assertion about the document, so a value that arrived
57
- * by accident must not reach one.
58
- */
59
13
  export declare function resolveRegionBindings(page: PageLike | null | undefined): ResolvedBindings;
60
- /**
61
- * The profile id the page names, plus a detector for the second copy of it.
62
- *
63
- * `layout.profile` is authoritative — a profile is geometry and belongs beside
64
- * `structure`. But the proof page carries `metadata.profile` as well, with
65
- * the same value, and **the host reads only one of them**. Today they agree; the
66
- * database has 1 page with each key and 0 disagreements. That is two sources for
67
- * one fact, in sync by luck, with no detector — the shape this pair of repos has
68
- * now caught four times (`PaperConfig` vs the profile, two type scales, two
69
- * paginators, and the carried-field lists).
70
- *
71
- * Rather than reading both and picking, or silently ignoring one: read `layout`,
72
- * and say so loudly the moment the copies disagree. Enforcement is cheap here
73
- * precisely because it is not yet a problem.
74
- */
75
14
  export declare function resolveProfileId(page: PageLike | null | undefined): string | undefined;
76
15
  export {};
@@ -1,49 +1,4 @@
1
- /**
2
- * The host's read of a bundle's `documentProfiles`.
3
- *
4
- * ── Why the host reads this at all ──────────────────────────────────────────
5
- *
6
- * A `DocumentProfile` is authored in the component repo (an org's document
7
- * bundle owns its profile module) and describes everything two document styles
8
- * DISAGREE about — sheet, margins, measure, ink, rules, type scale, depth.
9
- * Most of those are the bundle's business and the host never looks at them.
10
- *
11
- * Two are not. `depth.max` and `depth.numbering` are needed **before anything
12
- * renders**, because the outline is derived from `layout.structure` rather than
13
- * discovered from the rendered tree (a nav slot is a sibling region, so React
14
- * context cannot reach it). A value the host needs pre-render cannot arrive
15
- * through a component prop, so it is lifted off the bundle barrel — exactly the
16
- * way `ThemeProvider` already is (`loadRemote.ts`).
17
- *
18
- * ── Why a resolved map and not `resolveProfile` ─────────────────────────────
19
- *
20
- * The bundle exports a plain frozen object with `extends` already applied, so
21
- * reading configuration never means executing bundle logic. The cost of that
22
- * trade is that a plain map has no behaviour to throw with — the bundle's
23
- * `resolveProfile` threw on an unknown id precisely to stop a document
24
- * rendering in the wrong system. **That behaviour moves here, because the shape
25
- * we asked for moved it here**.
26
- *
27
- * ── The three states, and why the third is not "absent" ─────────────────────
28
- *
29
- * documentProfiles absent -> host defaults, debug note. Benign:
30
- * bundles predating the contract.
31
- * present, id found -> use it.
32
- * present, id MISSING -> console.warn naming the id AND the
33
- * ids that ARE present, then defaults.
34
- *
35
- * The third case is the one worth the code. Folding it into "absent" makes a
36
- * page declaring `profile: 'instrument'` against a workbook-only bundle render
37
- * with a workbook's geometry, orange accents and unbounded depth — which looks
38
- * like a document rather than like an error. Naming what IS present is what
39
- * sends the reader to the bundle instead of to the page config.
40
- */
41
1
  import type { LoadedBundle } from '../core/bundles/load.js';
42
- /**
43
- * What the resolver reads off a bundle: its `documentProfiles`, and a name for
44
- * the warnings. The renderer's `LoadedBundle` satisfies it (named by `label`);
45
- * `key` is the legacy host's name, kept so a caller with only a key still works.
46
- */
47
2
  export type ProfileBundle = Pick<LoadedBundle, 'documentProfiles'> & {
48
3
  label?: string;
49
4
  key?: string;
@@ -56,24 +11,10 @@ export interface DocumentPageRegionSlots {
56
11
  centre?: string;
57
12
  right?: string;
58
13
  }
59
- /**
60
- * Named for CSS `@page` margin boxes. British spelling in, CSS spelling out:
61
- * `centre` maps to `@bottom-center` at the one place both spellings appear
62
- * (stage 5's print stylesheet).
63
- */
64
14
  export interface DocumentPageRegions {
65
15
  'page-header'?: DocumentPageRegionSlots;
66
16
  'page-footer'?: DocumentPageRegionSlots;
67
17
  }
68
- /**
69
- * The host's structural view of a profile.
70
- *
71
- * Deliberately NOT a copy of the bundle's interface. Every field the host does not
72
- * read is optional here, because the host has no business rejecting a profile
73
- * over a field it never looks at — and a stricter type would turn each new
74
- * authoring field into a host release. The fields the host DOES read carry
75
- * their own runtime guards below; the type is a convenience, not the check.
76
- */
77
18
  export interface DocumentProfile {
78
19
  id: ProfileId;
79
20
  extends?: ProfileId;
@@ -90,32 +31,13 @@ export interface DocumentProfile {
90
31
  };
91
32
  measure?: string;
92
33
  bodyMeasureCh?: number;
93
- /**
94
- * The marginalia column, on paper.
95
- *
96
- * **Not `layout.shell.regions.rail`**, which is the chat panel. Two different
97
- * things one word apart, both live in this system's vocabulary, and a reader
98
- * who conflates them concludes the rail is already handled.
99
- *
100
- * `placement: 'column'` establishes a real second column that the PAGE owns —
101
- * the bundle's `MetaRail` header is explicit that *"it is not something MetaRail
102
- * does to itself"*. `'strip'` and `'none'` establish nothing, which is why
103
- * `workbook` and `report` are unaffected by the column geometry.
104
- *
105
- * `gutter` was shipped by the bundle and absent from this interface until
106
- * the column geometry landed, so it was dropped on read — the declared-and-unread shape again,
107
- * in the type rather than in the code.
108
- */
109
34
  rail?: {
110
35
  placement: 'strip' | 'column' | 'none';
111
- /** Where the column starts, measured from the text block's left edge. */
112
36
  axis?: string;
113
37
  width?: string;
114
- /** Space between the measure and the column. */
115
38
  gutter?: string;
116
39
  };
117
40
  ink?: Partial<Record<DocumentInkRole, string>>;
118
- /** `Partial` is load-bearing: an undefined weight is a PROHIBITION, not a gap. */
119
41
  rules?: Partial<Record<DocumentRuleWeight, string>>;
120
42
  type?: Record<string, unknown>;
121
43
  floorPx?: number;
@@ -126,78 +48,19 @@ export interface DocumentProfile {
126
48
  };
127
49
  fills?: boolean;
128
50
  regions?: DocumentPageRegions;
129
- /**
130
- * `known` absent and `known: []` are DIFFERENT and must stay so. Empty means
131
- * "no sectionId is valid"; absent means "not enumerable in advance" — which is
132
- * the instrument profile's deliberate state, because articles are generated
133
- * from the instrument rather than drawn from a fixed skeleton. Any check that
134
- * compares against `known` must guard the absent branch or it fails every
135
- * instrument document at once.
136
- */
137
51
  sections?: {
138
52
  required?: string[];
139
53
  known?: string[];
140
54
  };
141
- /**
142
- * Region bindings the document MUST NOT be produced without.
143
- *
144
- * `instrument` declares `['execution-state']`. The reasoning is
145
- * domain, not mechanism, and it is the one place the host's general rule is
146
- * the wrong rule:
147
- *
148
- * Every other missing binding produces a document that is INCOMPLETE.
149
- * This one produces a document that is WRONG ABOUT ITS OWN LEGAL STATUS.
150
- *
151
- * A draft will that silently loses *"Not for execution"* is, on paper, a will
152
- * that does not say it is a draft. So an omitted margin box — correct
153
- * everywhere else, because a blank box is indistinguishable from a right one —
154
- * fails toward the dangerous side here. `buildPageStylesheet` refuses to
155
- * produce the stylesheet at all rather than produce one that misrepresents the
156
- * document.
157
- *
158
- * A **paginator** binding must never appear here. The host cannot supply
159
- * `page-x-of-y` — CSS computes it during pagination — so requiring one would
160
- * be a permanent, unsatisfiable failure.
161
- *
162
- * Open `string[]`, not a closed union, for the same reason `ProfileId` is
163
- * open: the vocabulary is authored in the component repo, and a binding a bundle
164
- * adds must not be a host type error before it is a design question.
165
- */
166
55
  requiredBindings?: string[];
167
56
  }
168
57
  export type DocumentProfileMap = Readonly<Record<ProfileId, DocumentProfile>>;
169
- /**
170
- * Where the resolved profile came from. Callers that render a diagnostic want
171
- * to distinguish "the bundle said so" from "nobody said anything".
172
- */
173
58
  export type DocumentProfileSource = 'bundle' | 'defaults';
174
59
  export interface ResolvedDocumentProfile {
175
- /** `null` when no profile was found. Callers fall back to their own defaults. */
176
60
  profile: DocumentProfile | null;
177
61
  source: DocumentProfileSource;
178
- /**
179
- * `profile.depth.max` when it is a usable bound, else `undefined`.
180
- *
181
- * `undefined` means UNBOUNDED, and that is a real answer rather than a
182
- * missing one — the 191 flat `grid` pages have no depth to bound and the
183
- * workbook profile's skeleton is flat. `deriveTableOfContents` and
184
- * `validateStructure` both treat `maxDepth: undefined` as "do not check".
185
- */
186
62
  maxDepth: number | undefined;
187
- /** `profile.depth.numbering`, defaulting to `'ladder'`. */
188
63
  numbering: 'none' | 'ladder';
189
64
  }
190
- /** Test seam. Nothing in the app should need this. */
191
65
  export declare function __clearDocumentProfileWarnings(): void;
192
- /**
193
- * Resolve `profileId` against an ordered bundle cascade.
194
- *
195
- * Order matches the cell cascade — earlier registries win — so a page-level
196
- * `bundle_refs` entry overrides the org default for the profile the same way it
197
- * does for a component. A page that declares no profile gets host defaults
198
- * without a word: that is the 191-flat-page case and it is not a fault.
199
- *
200
- * @param registries Ordered, highest priority first. Loading? Pass `[]`.
201
- * @param profileId From `layout.profile`. `undefined` when the page declares none.
202
- */
203
66
  export declare function resolveDocumentProfile(registries: readonly ProfileBundle[], profileId: ProfileId | undefined): ResolvedDocumentProfile;
@@ -1,75 +1,9 @@
1
- /**
2
- * Is the frozen page map still describing the document that is on the page?
3
- *
4
- * ── Why this needs to be asked at all ───────────────────────────────────────
5
- *
6
- * `DocPrintContent` measures the document once, assigns its rows to pages, and
7
- * freezes — because typesetting changes the document it measured, so measuring
8
- * the already-typeset document gives a different and wrong answer.
9
- *
10
- * Freezing needs the document to have finished rendering, and nothing can be
11
- * sure it has. The settle gate waits for the height to stop changing, and a
12
- * document that is halfway through drawing its charts STALLS: the height climbs
13
- * 4,472 → 10,283 → 11,083px in under a second on the proof document, with pauses.
14
- * Reads taken during a pause are indistinguishable from a finished document by
15
- * arithmetic. Observed twice: a **6-page map for a 15-page document**, and a
16
- * **7-page map for a 10,613px document** — and a reload of the same URL giving
17
- * 15 both times. Same code, two answers, nothing in the output saying which.
18
- *
19
- * A prediction cannot be made reliable by tightening it. So the map is checked
20
- * against the document afterwards, and a stale map fails by thousands of pixels
21
- * rather than by a rounding error.
22
- *
23
- * ── Why the arithmetic lives here and not in the component ─────────────────
24
- *
25
- * Because it is the part that was wrong, twice, and both times it FAILED SILENT
26
- * — a check that cannot conclude looks exactly like a check that passes:
27
- *
28
- * 1. It ignored the scaling the typesetting applies, so every document with an
29
- * over-tall row looked stale by that row's shrink.
30
- * 2. It ignored the on-screen page separators — margin and padding, ~66px per
31
- * page start, ~792px over 15 pages. That condemned a correct map, unfroze,
32
- * measured the now-shorter document, froze, and condemned it again:
33
- * an oscillation between 10,283 and 11,083px that sometimes ended with the
34
- * document not typeset at all. A check that creates the instability it was
35
- * added to detect.
36
- *
37
- * Both are arithmetic about heights, testable with numbers, and were shipped
38
- * un-unit-tested because they lived inside an effect that needs a browser.
39
- */
40
1
  import type { PrintLayout } from './print-layout.js';
41
- /**
42
- * The container height to expect once a layout has been applied.
43
- *
44
- * Forced page breaks change nothing on screen, so only two things move:
45
- *
46
- * - **Scaling shortens** an over-tall row: its box goes from `heightPx` to
47
- * `scaledHeightPx`. Subtract the difference.
48
- * - **Screen separators lengthen** the document: they are margin, border and
49
- * padding on each page's first row. Add `screenExtraPx`, which the layout
50
- * reports rather than this function re-deriving from the CSS text.
51
- *
52
- * @param measuredContainerPx The container height the map was measured from —
53
- * `reconciliation.containerPx`, not a fresh read.
54
- */
55
2
  export declare function expectedHeightAfterTypesetting(measuredContainerPx: number, layout: Pick<PrintLayout, 'scaled' | 'screenExtraPx'>): number;
56
3
  export interface Staleness {
57
4
  stale: boolean;
58
- /** Live height minus expected. Positive means the document grew. */
59
5
  deltaPx: number;
60
6
  tolerancePx: number;
61
7
  }
62
- /**
63
- * Half a page of slack.
64
- *
65
- * Chosen to sit in the wide gap between the two populations rather than tuned:
66
- * the things that legitimately move a settled document — a late font, sub-pixel
67
- * rounding, a border — are tens of pixels, and the observed stale maps were
68
- * 4,200 and 5,600px adrift. Anything in that range separates them.
69
- *
70
- * A floor of 120px, because a document on a very short page would otherwise get
71
- * a tolerance smaller than one row.
72
- */
73
8
  export declare function stalenessTolerancePx(textBlockPx: number): number;
74
- /** Compare the document on the page against the map that was frozen for it. */
75
9
  export declare function mapStaleness(liveHeightPx: number, expectedPx: number, textBlockPx: number): Staleness;