@peripheries/renderer 0.1.0
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.
- package/README.md +65 -0
- package/dist/chunks/create-store-CglsI7tw.js +90 -0
- package/dist/chunks/create-store-CglsI7tw.js.map +1 -0
- package/dist/chunks/load-6zEgvJ6I.js +60 -0
- package/dist/chunks/load-6zEgvJ6I.js.map +1 -0
- package/dist/chunks/page-bundles-C4VW3dsK.js +87 -0
- package/dist/chunks/page-bundles-C4VW3dsK.js.map +1 -0
- package/dist/chunks/projection-Dsy9ruj8.js +592 -0
- package/dist/chunks/projection-Dsy9ruj8.js.map +1 -0
- package/dist/core.js +740 -0
- package/dist/core.js.map +1 -0
- package/dist/react.js +357 -0
- package/dist/react.js.map +1 -0
- package/dist/runtime.js +91 -0
- package/dist/runtime.js.map +1 -0
- package/dist/styles.css +51 -0
- package/dist/testing.js +944 -0
- package/dist/testing.js.map +1 -0
- package/dist/types/core/bundles/load.d.ts +49 -0
- package/dist/types/core/bundles/page-bundles.d.ts +17 -0
- package/dist/types/core/bundles/refs.d.ts +41 -0
- package/dist/types/core/bundles/resolve.d.ts +25 -0
- package/dist/types/core/cell-props.d.ts +39 -0
- package/dist/types/core/cells.d.ts +39 -0
- package/dist/types/core/data-context.d.ts +38 -0
- package/dist/types/core/graph.d.ts +95 -0
- package/dist/types/core/index.d.ts +19 -0
- package/dist/types/core/layout.d.ts +12 -0
- package/dist/types/core/load-page.d.ts +72 -0
- package/dist/types/core/references.d.ts +43 -0
- package/dist/types/core/store/create-store.d.ts +26 -0
- package/dist/types/core/store/persistence.d.ts +9 -0
- package/dist/types/core/store/projection.d.ts +15 -0
- package/dist/types/core/store/scope-keys.d.ts +10 -0
- package/dist/types/core/store/types.d.ts +37 -0
- package/dist/types/core/structure.d.ts +72 -0
- package/dist/types/core/types.d.ts +30 -0
- package/dist/types/core/validate.d.ts +14 -0
- package/dist/types/react/cell-states.d.ts +25 -0
- package/dist/types/react/cell-view.d.ts +31 -0
- package/dist/types/react/index.d.ts +6 -0
- package/dist/types/react/page-renderer.d.ts +30 -0
- package/dist/types/react/structure-view.d.ts +30 -0
- package/dist/types/react/use-cell-store.d.ts +13 -0
- package/dist/types/react/use-container-size.d.ts +11 -0
- package/dist/types/runtime/boot.d.ts +7 -0
- package/dist/types/runtime/index.d.ts +4 -0
- package/dist/types/runtime/install.d.ts +21 -0
- package/dist/types/runtime/shims.d.ts +11 -0
- package/dist/types/runtime/store-export.d.ts +18 -0
- package/dist/types/testing/base-props.d.ts +3 -0
- package/dist/types/testing/components.d.ts +51 -0
- package/dist/types/testing/golden.d.ts +51 -0
- package/dist/types/testing/ids.d.ts +14 -0
- package/dist/types/testing/index.d.ts +5 -0
- package/dist/types/testing/sources.d.ts +25 -0
- package/package.json +51 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { PageCell } from './types.js';
|
|
2
|
+
import { SECTION_KINDS, type LayoutNode, type SectionKind, type SectionReference } from '@peripheries/runtime';
|
|
3
|
+
export { SECTION_KINDS };
|
|
4
|
+
export type { LayoutNode, SectionKind, SectionReference };
|
|
5
|
+
export type ResolvedLayoutNode = Omit<LayoutNode, 'children'> & {
|
|
6
|
+
children?: ResolvedLayoutNode[];
|
|
7
|
+
};
|
|
8
|
+
/** The page's own document, which almost every page is. */
|
|
9
|
+
export declare const PAGE_DOCUMENT = "__page__";
|
|
10
|
+
/** A string child is sugar for `{ cellId }`. */
|
|
11
|
+
export declare function normalizeStructure(nodes: ReadonlyArray<LayoutNode | string> | null | undefined): ResolvedLayoutNode[];
|
|
12
|
+
/** Siblings by `order` (default 0), stable. */
|
|
13
|
+
export declare const sortByOrder: <T extends {
|
|
14
|
+
order?: number;
|
|
15
|
+
}>(nodes: readonly T[]) => T[];
|
|
16
|
+
export declare const isSectionNode: (n: ResolvedLayoutNode) => boolean;
|
|
17
|
+
export declare const isSectionKind: (v: unknown) => v is SectionKind;
|
|
18
|
+
/** A section's anchor: its cell, else its section id (the same value `DocumentSection` and the contents use). */
|
|
19
|
+
export declare const sectionAnchor: (n: Pick<ResolvedLayoutNode, "cellId" | "sectionId">) => string;
|
|
20
|
+
/**
|
|
21
|
+
* Hierarchical rendering when the structure wants it: `type: 'document'`, or
|
|
22
|
+
* any top-level node naming a section or carrying children. A flat list of
|
|
23
|
+
* `{ cellId }` is only an ordering hint for print, and renders flat.
|
|
24
|
+
*/
|
|
25
|
+
export declare function usesStructureLayout(layout: Record<string, unknown> | null | undefined): boolean;
|
|
26
|
+
export type DocumentNumbering = {
|
|
27
|
+
/** Only `kind: 'article'` sections are numbered, per document, prefixed by the parent trail. */
|
|
28
|
+
numbers: Record<string, number[]>;
|
|
29
|
+
/** Structural depth of each section. */
|
|
30
|
+
levels: Record<string, number>;
|
|
31
|
+
authoredLevels: Record<string, number>;
|
|
32
|
+
titles: Record<string, string>;
|
|
33
|
+
anchors: Record<string, string>;
|
|
34
|
+
};
|
|
35
|
+
export type SectionNumbering = {
|
|
36
|
+
byDocument: Record<string, DocumentNumbering>;
|
|
37
|
+
unknownKinds: Array<{
|
|
38
|
+
path: string;
|
|
39
|
+
sectionId?: string;
|
|
40
|
+
kind: string;
|
|
41
|
+
}>;
|
|
42
|
+
};
|
|
43
|
+
export declare const numberingFor: (numbering: SectionNumbering | undefined, documentId: string | undefined) => DocumentNumbering;
|
|
44
|
+
export declare function deriveSectionNumbering(structure: ReadonlyArray<LayoutNode | string> | null | undefined): SectionNumbering;
|
|
45
|
+
/** Per document: every target a cell in it may cite, by role (`residue`), `label:role`, or `role#clause`. */
|
|
46
|
+
export type SectionReferences = Record<string, Record<string, SectionReference>>;
|
|
47
|
+
type Documents = Record<string, {
|
|
48
|
+
label?: unknown;
|
|
49
|
+
}> | null | undefined;
|
|
50
|
+
/** Same-page section references: a document's own roles, plus `label:role` for every uniquely labelled document. */
|
|
51
|
+
export declare function deriveSectionReferences(numbering: SectionNumbering, documents: Documents): SectionReferences;
|
|
52
|
+
/**
|
|
53
|
+
* Clause citations (`role#clauseId`): each section's cells' resolved
|
|
54
|
+
* `props.blocks`, where a `clause` block's items carry ids. The item's index
|
|
55
|
+
* and the clause shape let a Reference render the clause's number.
|
|
56
|
+
*/
|
|
57
|
+
export declare function deriveElementReferences(structure: ReadonlyArray<LayoutNode | string> | null | undefined, blocksByCellId: Readonly<Record<string, unknown>>, documents: Documents): SectionReferences;
|
|
58
|
+
/** Same-page references win over data-derived ones (clauses; cross-page arrive in R5). */
|
|
59
|
+
export declare function mergeSectionReferences(samePage: SectionReferences, other: SectionReferences | undefined): SectionReferences;
|
|
60
|
+
export declare const referencesFor: (refs: SectionReferences | undefined, documentId: string | undefined) => Record<string, SectionReference>;
|
|
61
|
+
/** What stops a structure rendering: a node naming a missing cell, or an unknown section kind (a refusal, by design). */
|
|
62
|
+
export declare function structureIssues(structure: ReadonlyArray<LayoutNode | string> | null | undefined, cells: PageCell[]): string[];
|
|
63
|
+
/**
|
|
64
|
+
* A node's extrinsic pagination: a page break before, keep-with-previous
|
|
65
|
+
* (break-before: avoid), or avoid breaking inside. `breakInside: 'auto'` is
|
|
66
|
+
* dropped, so a node can't relax what a component declares; a break before
|
|
67
|
+
* wins over keep-with-previous. The component's own @printPolicy joins in R5.
|
|
68
|
+
*/
|
|
69
|
+
export declare function nodePrintStyle(node: Pick<LayoutNode, 'print'>): {
|
|
70
|
+
breakBefore?: 'page' | 'avoid';
|
|
71
|
+
breakInside?: 'avoid';
|
|
72
|
+
} | undefined;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DeclaredBinding, PageCell } from '@peripheries/runtime';
|
|
2
|
+
/** One source in a DataContext: the value and its state. */
|
|
3
|
+
export type DataEntry = {
|
|
4
|
+
data: unknown;
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
error: Error | null;
|
|
7
|
+
};
|
|
8
|
+
export type DataContext = Record<string, DataEntry>;
|
|
9
|
+
export type { CellData, CellLayout, DeclaredBinding, PageCell, ResponsiveBucket } from '@peripheries/runtime';
|
|
10
|
+
export type PageContent = {
|
|
11
|
+
cells?: PageCell[];
|
|
12
|
+
data?: {
|
|
13
|
+
static?: Record<string, unknown>;
|
|
14
|
+
queries?: Record<string, DeclaredBinding>;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export type ProjectPage = {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string | null;
|
|
20
|
+
org_id: string | null;
|
|
21
|
+
project_id: string | null;
|
|
22
|
+
process_id: string | null;
|
|
23
|
+
graph_node_id: string | null;
|
|
24
|
+
page_type: string | null;
|
|
25
|
+
status: string | null;
|
|
26
|
+
is_template: boolean | null;
|
|
27
|
+
content: PageContent | null;
|
|
28
|
+
layout: Record<string, unknown> | null;
|
|
29
|
+
metadata: Record<string, unknown> | null;
|
|
30
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Diagnostic } from './graph.js';
|
|
2
|
+
import type { PageCell, ProjectPage } from './types.js';
|
|
3
|
+
/** What validation knows about the components in scope. Stream 3 fills it from the catalog. */
|
|
4
|
+
export type Catalog = {
|
|
5
|
+
components: Record<string, {
|
|
6
|
+
props_schema?: {
|
|
7
|
+
required?: readonly string[];
|
|
8
|
+
} | null;
|
|
9
|
+
} | undefined>;
|
|
10
|
+
};
|
|
11
|
+
/** One cell's configuration. `ids` are the page's cell ids, for `children`. */
|
|
12
|
+
export declare function validateCell(cell: PageCell, catalog?: Catalog, path?: string, ids?: ReadonlySet<string>): Diagnostic[];
|
|
13
|
+
/** A whole page: every cell, the page's own declarations, unique cell ids, and its document structure. */
|
|
14
|
+
export declare function validatePage(page: Pick<ProjectPage, 'content' | 'layout'>, catalog?: Catalog): Diagnostic[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Component, type ReactNode } from 'react';
|
|
2
|
+
/** A placeholder the size of the cell's slot, so the page doesn't shift when components arrive. */
|
|
3
|
+
export declare function CellPlaceholder({ state }: {
|
|
4
|
+
state: 'loading' | 'pending';
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
export declare function CellNotice({ state, children }: {
|
|
7
|
+
state: 'not-found' | 'error';
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
/** One cell's crash stays in that cell. */
|
|
11
|
+
export declare class CellErrorBoundary extends Component<{
|
|
12
|
+
cellId: string;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}, {
|
|
15
|
+
error: Error | null;
|
|
16
|
+
}> {
|
|
17
|
+
state: {
|
|
18
|
+
error: Error | null;
|
|
19
|
+
};
|
|
20
|
+
static getDerivedStateFromError(error: Error): {
|
|
21
|
+
error: Error;
|
|
22
|
+
};
|
|
23
|
+
componentDidCatch(error: Error): void;
|
|
24
|
+
render(): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
25
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LoadedBundle } from '../core/bundles/load.js';
|
|
2
|
+
import { type CoreRegistry } from '../core/bundles/resolve.js';
|
|
3
|
+
import type { CellData } from '../core/load-page.js';
|
|
4
|
+
import { type ResolutionContext } from '../core/references.js';
|
|
5
|
+
import type { StackStoreApi } from '../core/store/create-store.js';
|
|
6
|
+
import type { ScopeContext } from '../core/store/scope-keys.js';
|
|
7
|
+
import type { PageCell } from '../core/types.js';
|
|
8
|
+
export type CellEnvironment = {
|
|
9
|
+
cellsById: Map<string, PageCell>;
|
|
10
|
+
page: ResolutionContext;
|
|
11
|
+
baseProps: unknown;
|
|
12
|
+
/** null while the page's bundles are loading (and always on the server). */
|
|
13
|
+
bundles: LoadedBundle[] | null;
|
|
14
|
+
bundleFor: (cell: PageCell) => LoadedBundle | null;
|
|
15
|
+
core: CoreRegistry;
|
|
16
|
+
navigate: (to: string) => void;
|
|
17
|
+
store: StackStoreApi;
|
|
18
|
+
scope: ScopeContext;
|
|
19
|
+
context: Record<string, unknown>;
|
|
20
|
+
/** Each cell's own data, by cell id (loadPageData). */
|
|
21
|
+
cellData?: Record<string, CellData>;
|
|
22
|
+
/** Labels the page declares, which no walk's label replaces. */
|
|
23
|
+
declared?: ReadonlySet<string>;
|
|
24
|
+
};
|
|
25
|
+
export declare function CellView({ cell, env, nested, injectedProps, }: {
|
|
26
|
+
cell: PageCell;
|
|
27
|
+
env: CellEnvironment;
|
|
28
|
+
nested?: boolean;
|
|
29
|
+
/** Host-derived facts merged over the resolved props (a structure's numbering, anchors, references). */
|
|
30
|
+
injectedProps?: Record<string, unknown>;
|
|
31
|
+
}): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { CellErrorBoundary, CellNotice, CellPlaceholder } from './cell-states.js';
|
|
2
|
+
export { CellView, type CellEnvironment } from './cell-view.js';
|
|
3
|
+
export { PageRenderer, type PageRendererProps, type RendererEnvironment } from './page-renderer.js';
|
|
4
|
+
export { StructureView, useStructureFacts } from './structure-view.js';
|
|
5
|
+
export { useCellStore } from './use-cell-store.js';
|
|
6
|
+
export { useContainerSize, type Size } from './use-container-size.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PageBundles } from '../core/bundles/page-bundles.js';
|
|
2
|
+
import { type CoreRegistry } from '../core/bundles/resolve.js';
|
|
3
|
+
import type { Diagnostic } from '../core/graph.js';
|
|
4
|
+
import type { PageRuntime } from '../core/load-page.js';
|
|
5
|
+
import type { StackStoreApi } from '../core/store/create-store.js';
|
|
6
|
+
/** What differs between the host, the component repos' harness and the agency's preview (design/renderer.md §6). */
|
|
7
|
+
export type RendererEnvironment = {
|
|
8
|
+
/** Default components: what a name resolves to when no bundle in scope exports it. */
|
|
9
|
+
core: CoreRegistry;
|
|
10
|
+
navigate: (to: string) => void;
|
|
11
|
+
/** The shared store the cells' selections, viewState and live read. */
|
|
12
|
+
store: StackStoreApi;
|
|
13
|
+
/** A page configuration problem, for whoever is building the page. Default: a console warning. */
|
|
14
|
+
onDiagnostic?: (d: Diagnostic) => void;
|
|
15
|
+
};
|
|
16
|
+
export type PageRendererProps = {
|
|
17
|
+
runtime: PageRuntime;
|
|
18
|
+
bundles: PageBundles;
|
|
19
|
+
params: Record<string, unknown>;
|
|
20
|
+
baseProps: unknown;
|
|
21
|
+
context: Record<string, unknown>;
|
|
22
|
+
environment: RendererEnvironment;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* One page, one renderer (design/core.md §3, stages 4–5). It fetches nothing:
|
|
26
|
+
* the page's data comes in `runtime` (loadPageData) and its bundles in
|
|
27
|
+
* `bundles`. On the server the bundles haven't imported, so each cell renders
|
|
28
|
+
* as a placeholder sized by its layout.
|
|
29
|
+
*/
|
|
30
|
+
export declare function PageRenderer({ runtime, bundles, params, baseProps, context, environment }: PageRendererProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type LayoutNode, type ResolvedLayoutNode, type SectionNumbering, type SectionReferences } from '../core/structure.js';
|
|
2
|
+
import type { PageCell } from '../core/types.js';
|
|
3
|
+
import { type CellEnvironment } from './cell-view.js';
|
|
4
|
+
type Derived = {
|
|
5
|
+
numbering: SectionNumbering;
|
|
6
|
+
references: SectionReferences;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Numbering and references for the whole page, derived once: a nested
|
|
10
|
+
* renderer that re-derived them from its subtree would number the same
|
|
11
|
+
* section differently. Clause citations read each cell's resolved `props.blocks`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useStructureFacts(structure: LayoutNode[], cells: PageCell[], env: CellEnvironment, documents: Record<string, {
|
|
14
|
+
label?: unknown;
|
|
15
|
+
}> | undefined): Derived;
|
|
16
|
+
/**
|
|
17
|
+
* The document renderer (the PWA's StructureRenderer). A node naming a cell
|
|
18
|
+
* renders it with the whole document's numbering, levels, titles, anchors and
|
|
19
|
+
* references for the node's own document, and with the node's children as the
|
|
20
|
+
* cell's child cells. A section node is a real `<section>` with a heading; a
|
|
21
|
+
* container section with no cell renders its children itself.
|
|
22
|
+
*/
|
|
23
|
+
export declare function StructureView({ nodes, env, facts, level, documentId, }: {
|
|
24
|
+
nodes: Array<LayoutNode | string> | ResolvedLayoutNode[];
|
|
25
|
+
env: CellEnvironment;
|
|
26
|
+
facts: Derived;
|
|
27
|
+
level?: number;
|
|
28
|
+
documentId?: string;
|
|
29
|
+
}): import("react").JSX.Element;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { StackStoreApi } from '../core/store/create-store.js';
|
|
2
|
+
import type { ScopeContext } from '../core/store/scope-keys.js';
|
|
3
|
+
import type { PageCell } from '../core/types.js';
|
|
4
|
+
/**
|
|
5
|
+
* A cell's `selections`, `viewState` and `live` props from the shared store.
|
|
6
|
+
* The selector returns values only, compared shallowly, so a cell re-renders
|
|
7
|
+
* only when one of its own channels changes; setters are attached after.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useCellStore(cell: PageCell, scope: ScopeContext, api: StackStoreApi): {
|
|
10
|
+
selections: import("../core/index.js").ProjectedBundle | undefined;
|
|
11
|
+
viewState: import("../core/index.js").ProjectedBundle | undefined;
|
|
12
|
+
live: import("../core/index.js").ProjectedBundle | undefined;
|
|
13
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
export type Size = {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* The element's measured size, in whole pixels, updated at most once per
|
|
8
|
+
* frame (design/core.md §4). Only for components that declare they need it:
|
|
9
|
+
* CSS container queries cover the rest for free.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useContainerSize(ref: RefObject<HTMLElement | null>, enabled: boolean): Size | undefined;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A classic inline script that must run before any module: it creates the
|
|
3
|
+
* promise every shim awaits. `installRuntime` resolves it.
|
|
4
|
+
*/
|
|
5
|
+
export declare const RUNTIME_BOOT_SCRIPT: string;
|
|
6
|
+
/** The import map, serialised for `<script type="importmap">`. */
|
|
7
|
+
export declare const IMPORT_MAP_JSON: string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { IMPORT_MAP_JSON, RUNTIME_BOOT_SCRIPT } from './boot.js';
|
|
2
|
+
export { buildRuntime, installRuntime, runtimeReady, type StackRuntime } from './install.js';
|
|
3
|
+
export { renderShim, shimFileName } from './shims.js';
|
|
4
|
+
export { getStackStore, selectors, useStackStore } from './store-export.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LEGACY_RUNTIME_GLOBAL, READY_GLOBAL, RESOLVE_GLOBAL, RUNTIME_GLOBAL, type RuntimeSpecifier } from '@peripheries/runtime';
|
|
2
|
+
export type StackRuntime = Record<RuntimeSpecifier, unknown> & Record<string, unknown>;
|
|
3
|
+
type RuntimeGlobals = {
|
|
4
|
+
[RUNTIME_GLOBAL]?: StackRuntime;
|
|
5
|
+
[LEGACY_RUNTIME_GLOBAL]?: StackRuntime;
|
|
6
|
+
[READY_GLOBAL]?: Promise<void>;
|
|
7
|
+
[RESOLVE_GLOBAL]?: () => void;
|
|
8
|
+
require?: (specifier: string) => unknown;
|
|
9
|
+
};
|
|
10
|
+
export declare function buildRuntime(): StackRuntime;
|
|
11
|
+
/**
|
|
12
|
+
* Puts the host's module instances where the `/_shared/*.js` shims look for
|
|
13
|
+
* them, and releases every shim waiting on the boot promise. Idempotent.
|
|
14
|
+
*
|
|
15
|
+
* Also installs a `globalThis.require` for Rolldown's CJS interop: bundles
|
|
16
|
+
* built with Vite 8 call `require('react')` from transitive CJS dependencies
|
|
17
|
+
* at module init, which throws in a browser without it. The runtime modules
|
|
18
|
+
* are already loaded, so it answers synchronously.
|
|
19
|
+
*/
|
|
20
|
+
export declare function installRuntime(g?: RuntimeGlobals): StackRuntime;
|
|
21
|
+
export { runtimeReady } from '../core/bundles/load.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type RuntimeSpecifier } from '@peripheries/runtime';
|
|
2
|
+
/** Output file name, taken from the URL the import map advertises, so the two can't disagree. */
|
|
3
|
+
export declare function shimFileName(specifier: RuntimeSpecifier): string;
|
|
4
|
+
/**
|
|
5
|
+
* An ESM module that forwards `specifier` to the host's instance.
|
|
6
|
+
*
|
|
7
|
+
* It awaits the ready promise the boot script creates, so a bundle imported
|
|
8
|
+
* before the host has installed its runtime waits instead of failing: the
|
|
9
|
+
* "Failed to resolve module specifier" race cannot happen (channel-06 #10).
|
|
10
|
+
*/
|
|
11
|
+
export declare function renderShim(specifier: RuntimeSpecifier, names: string[], hasDefault: boolean): string;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type StackStoreApi } from '../core/store/create-store.js';
|
|
2
|
+
import type { LiveEntry, ScopeId, StackStoreState } from '../core/store/types.js';
|
|
3
|
+
export declare function getStackStore(): StackStoreApi;
|
|
4
|
+
/** Subscribe a component to a slice of the shared store. */
|
|
5
|
+
export declare function useStackStore<T>(selector: (state: StackStoreState) => T): T;
|
|
6
|
+
export declare const selectors: {
|
|
7
|
+
selection: (scope: ScopeId, channel: string) => (s: StackStoreState) => unknown;
|
|
8
|
+
viewState: (scope: ScopeId, key: string) => (s: StackStoreState) => unknown;
|
|
9
|
+
live: <T = unknown>(channel: string) => (s: StackStoreState) => LiveEntry<T> | undefined;
|
|
10
|
+
};
|
|
11
|
+
export interface StoreRuntime {
|
|
12
|
+
useStore: typeof useStackStore;
|
|
13
|
+
/** The PWA's name, kept while bundles migrate. */
|
|
14
|
+
useOAStore: typeof useStackStore;
|
|
15
|
+
getStore: typeof getStackStore;
|
|
16
|
+
selectors: typeof selectors;
|
|
17
|
+
}
|
|
18
|
+
export declare function buildStoreRuntime(): StoreRuntime;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
type Props = Record<string, unknown>;
|
|
2
|
+
type SectionMaps = {
|
|
3
|
+
sectionNumbers?: Record<string, number[]>;
|
|
4
|
+
sectionAnchors?: Record<string, string>;
|
|
5
|
+
sectionReferences?: Record<string, {
|
|
6
|
+
number?: number[];
|
|
7
|
+
title?: string;
|
|
8
|
+
href?: string;
|
|
9
|
+
element?: {
|
|
10
|
+
index: number;
|
|
11
|
+
};
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
export declare function Masthead({ title, subtitle }: Props): import("react").JSX.Element;
|
|
15
|
+
/** Authored text arrives as `children` unless the cell has child cells. */
|
|
16
|
+
export declare function Prose({ children }: Props): import("react").JSX.Element;
|
|
17
|
+
/** A section body in the style of acrc's DocumentSection: it owns its section's anchor. */
|
|
18
|
+
export declare function DocumentSection({ sectionId, title, body, blocks, children, sectionNumbers, sectionAnchors }: Props & SectionMaps): import("react").JSX.Element;
|
|
19
|
+
/** A same-page citation: `§<number> <title>`, plus the clause's letter when it names one. */
|
|
20
|
+
export declare function SectionReference({ to, sectionReferences }: Props & SectionMaps): import("react").JSX.Element;
|
|
21
|
+
export declare function KpiCard({ label, value, data, status }: Props): import("react").JSX.Element;
|
|
22
|
+
/** Writes a shared selection. */
|
|
23
|
+
export declare function OptionList({ options, selections }: Props): import("react").JSX.Element;
|
|
24
|
+
/** Reads the same selection. */
|
|
25
|
+
export declare function SelectionEcho({ selections }: Props): import("react").JSX.Element;
|
|
26
|
+
export declare function Boom(): never;
|
|
27
|
+
/** Lists a walk's nodes with their plan and data states, as a backlog or flow cell would. */
|
|
28
|
+
export declare function FlowList({ nodes, edges }: Props): import("react").JSX.Element;
|
|
29
|
+
export declare function Badge({ text }: Props): import("react").JSX.Element;
|
|
30
|
+
export declare function ThemeProvider({ children }: {
|
|
31
|
+
children?: unknown;
|
|
32
|
+
}): import("react").JSX.Element;
|
|
33
|
+
/** The example client org's main lineage. */
|
|
34
|
+
export declare const clientKit: {
|
|
35
|
+
Masthead: typeof Masthead;
|
|
36
|
+
Prose: typeof Prose;
|
|
37
|
+
DocumentSection: typeof DocumentSection;
|
|
38
|
+
SectionReference: typeof SectionReference;
|
|
39
|
+
KpiCard: typeof KpiCard;
|
|
40
|
+
OptionList: typeof OptionList;
|
|
41
|
+
SelectionEcho: typeof SelectionEcho;
|
|
42
|
+
FlowList: typeof FlowList;
|
|
43
|
+
Boom: typeof Boom;
|
|
44
|
+
ThemeProvider: typeof ThemeProvider;
|
|
45
|
+
};
|
|
46
|
+
/** The advisor org's main lineage: its own Prose (which the client's shadows) and a Badge only it has. */
|
|
47
|
+
export declare const advisorKit: {
|
|
48
|
+
Prose: ({ children }: Props) => import("react").JSX.Element;
|
|
49
|
+
Badge: typeof Badge;
|
|
50
|
+
};
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { BundleRow } from '../core/bundles/load.js';
|
|
2
|
+
import type { RawWalk } from '../core/graph.js';
|
|
3
|
+
import type { ProjectPage } from '../core/types.js';
|
|
4
|
+
export type GoldenBundle = {
|
|
5
|
+
row: Omit<BundleRow, 'components'>;
|
|
6
|
+
module: Record<string, unknown>;
|
|
7
|
+
contracts?: Record<string, unknown>;
|
|
8
|
+
};
|
|
9
|
+
export type GoldenPage = {
|
|
10
|
+
name: string;
|
|
11
|
+
/** What it proves, in one line. */
|
|
12
|
+
purpose: string;
|
|
13
|
+
page: ProjectPage;
|
|
14
|
+
/** The process row: its id and its `<tier>_<role>_system_id` columns. */
|
|
15
|
+
process?: {
|
|
16
|
+
id: string;
|
|
17
|
+
} & Record<string, string | null>;
|
|
18
|
+
/** walk_graph's answers, by start node (and depth, when two walks share a start); states keyed by system id. */
|
|
19
|
+
walks?: Array<{
|
|
20
|
+
start: string;
|
|
21
|
+
maxDepth?: number;
|
|
22
|
+
result: RawWalk;
|
|
23
|
+
}>;
|
|
24
|
+
/** Newest `page_cell_config` per cell node (cell_config_latest). */
|
|
25
|
+
configs?: Array<{
|
|
26
|
+
system_id: string;
|
|
27
|
+
graph_node_id: string;
|
|
28
|
+
config: Record<string, unknown>;
|
|
29
|
+
}>;
|
|
30
|
+
/** Newest state per node (node_state_latest). */
|
|
31
|
+
states?: Array<{
|
|
32
|
+
system_id: string;
|
|
33
|
+
graph_node_id: string;
|
|
34
|
+
data: unknown;
|
|
35
|
+
}>;
|
|
36
|
+
/** Live bundles the viewer can see; the page's scope picks among them. */
|
|
37
|
+
bundles: GoldenBundle[];
|
|
38
|
+
/** The org template's advisor org, whose main lineage is in scope after the page's own org. */
|
|
39
|
+
advisorOrgId?: string;
|
|
40
|
+
};
|
|
41
|
+
/** An SCG document: a frame cell, then sections numbered through a transparent container, a clause citation and child cells. */
|
|
42
|
+
export declare const documentPage: GoldenPage;
|
|
43
|
+
/** A grid dashboard fed by declared producers, with conditions, a crash, a missing component and a shared selection. */
|
|
44
|
+
export declare const dashboardPage: GoldenPage;
|
|
45
|
+
/** A legacy page of thin refs: configs from the cells' DSNS, their declarations hoisted, one config missing. */
|
|
46
|
+
export declare const thinRefPage: GoldenPage;
|
|
47
|
+
/** Every cell form on one page: inline, refs (one with a config, one falling back), a legacy thin ref, form 4, and a cross-org bundle. */
|
|
48
|
+
export declare const mixedPage: GoldenPage;
|
|
49
|
+
/** Walks from the page node: @_traversal with two systems, walk labels scoped to their cell, declarations winning, walks skipped when not needed. */
|
|
50
|
+
export declare const walkPage: GoldenPage;
|
|
51
|
+
export declare const GOLDEN_PAGES: GoldenPage[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** A synthetic UUID: `fixtureId(7)` → `00000000-0000-4000-8000-000000000007`. */
|
|
2
|
+
export declare const fixtureId: (n: number) => string;
|
|
3
|
+
export declare const FIXTURE_ID: RegExp;
|
|
4
|
+
/** The only org slugs and email domain a fixture may use. */
|
|
5
|
+
export declare const FIXTURE_ORG_SLUGS: readonly ["example-client", "example-advisor"];
|
|
6
|
+
export declare const FIXTURE_EMAIL_DOMAIN = "example.test";
|
|
7
|
+
export declare const CLIENT_ORG: {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly slug: "example-client";
|
|
10
|
+
};
|
|
11
|
+
export declare const ADVISOR_ORG: {
|
|
12
|
+
readonly id: string;
|
|
13
|
+
readonly slug: "example-advisor";
|
|
14
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { FIXTURE_BASE_PROPS } from './base-props.js';
|
|
2
|
+
export * as fixtureComponents from './components.js';
|
|
3
|
+
export { dashboardPage, documentPage, GOLDEN_PAGES, mixedPage, thinRefPage, walkPage, type GoldenBundle, type GoldenPage } from './golden.js';
|
|
4
|
+
export { ADVISOR_ORG, CLIENT_ORG, FIXTURE_EMAIL_DOMAIN, FIXTURE_ID, FIXTURE_ORG_SLUGS, fixtureId } from './ids.js';
|
|
5
|
+
export { goldenBundleRow, goldenBundles, goldenGraphSource, goldenScope, type SourceCall } from './sources.js';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type BundleRow } from '../core/bundles/load.js';
|
|
2
|
+
import { type PageBundles } from '../core/bundles/page-bundles.js';
|
|
3
|
+
import { type LineageRef } from '../core/bundles/refs.js';
|
|
4
|
+
import type { GraphSource } from '../core/load-page.js';
|
|
5
|
+
import type { PageCell } from '../core/types.js';
|
|
6
|
+
import type { GoldenBundle, GoldenPage } from './golden.js';
|
|
7
|
+
export type SourceCall = {
|
|
8
|
+
method: keyof GraphSource;
|
|
9
|
+
args: unknown[];
|
|
10
|
+
};
|
|
11
|
+
/** A GraphSource over a golden page's process, configs, states and walks. */
|
|
12
|
+
export declare function goldenGraphSource(g: GoldenPage): GraphSource & {
|
|
13
|
+
calls: SourceCall[];
|
|
14
|
+
};
|
|
15
|
+
/** A golden bundle's registry row: every export but the bundle-level ones, under its own name. */
|
|
16
|
+
export declare function goldenBundleRow(b: GoldenBundle): BundleRow;
|
|
17
|
+
/** The page's bundle scope, nearest first: its own refs, then its org's main lineage, then the advisor org's. */
|
|
18
|
+
export declare function goldenScope(g: GoldenPage): LineageRef[];
|
|
19
|
+
/**
|
|
20
|
+
* The page's bundles, "imported" from the golden modules. `loaded: false` gives
|
|
21
|
+
* what the server renders with: the rows, and no bundle yet.
|
|
22
|
+
*/
|
|
23
|
+
export declare function goldenBundles(g: GoldenPage, cells: PageCell[], { loaded }?: {
|
|
24
|
+
loaded?: boolean | undefined;
|
|
25
|
+
}): PageBundles;
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@peripheries/renderer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The one renderer for pages of federated component bundles: a framework-free core, a React renderer, the runtime a page boots with, and golden pages for testing.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"*.css"
|
|
8
|
+
],
|
|
9
|
+
"exports": {
|
|
10
|
+
"./core": {
|
|
11
|
+
"types": "./dist/types/core/index.d.ts",
|
|
12
|
+
"default": "./dist/core.js"
|
|
13
|
+
},
|
|
14
|
+
"./react": {
|
|
15
|
+
"types": "./dist/types/react/index.d.ts",
|
|
16
|
+
"default": "./dist/react.js"
|
|
17
|
+
},
|
|
18
|
+
"./runtime": {
|
|
19
|
+
"types": "./dist/types/runtime/index.d.ts",
|
|
20
|
+
"default": "./dist/runtime.js"
|
|
21
|
+
},
|
|
22
|
+
"./testing": {
|
|
23
|
+
"types": "./dist/types/testing/index.d.ts",
|
|
24
|
+
"default": "./dist/testing.js"
|
|
25
|
+
},
|
|
26
|
+
"./styles.css": "./dist/styles.css"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@peripheries/runtime": "0.1.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@tanstack/react-store": "0.11.1",
|
|
37
|
+
"@tanstack/store": "0.11.1",
|
|
38
|
+
"react": "^19.2.4",
|
|
39
|
+
"react-dom": "^19.2.4",
|
|
40
|
+
"zustand": "^5.0.0"
|
|
41
|
+
},
|
|
42
|
+
"license": "UNLICENSED",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/peripheries-clients/peripheries-stack.git",
|
|
46
|
+
"directory": "packages/renderer"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|