@peripheries/runtime 0.0.0-stage → 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 +20 -2
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/types/config.d.ts +126 -0
- package/dist/types/contract.d.ts +112 -0
- package/dist/types/graph.d.ts +76 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/pinned.d.ts +73 -0
- package/package.json +24 -4
package/README.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @peripheries/runtime
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The contract between the host and federated component bundles
|
|
4
|
+
([design/bundles.md](../../docs/plan/design/bundles.md) §6–7):
|
|
5
|
+
|
|
6
|
+
- **`pinned`**: the shared specifiers bundles leave external (`react`,
|
|
7
|
+
`react/jsx-runtime`, `react-dom`, `zustand`, `@stack/store`, and the old
|
|
8
|
+
`@oa/store`), their pinned ranges and `/_shared/*.js` URLs, and the import map
|
|
9
|
+
the host serves (`/_shared/import-map.json` is the same payload).
|
|
10
|
+
- **`contract`**: what a cell component receives (`CellProps`, `BaseProps`,
|
|
11
|
+
`DocumentCellProps`, `WriteResult`, `Size`, `CellContext`).
|
|
12
|
+
- **`config`**: the cell, page and structure configuration shapes.
|
|
13
|
+
- **`graph`**: `NodeRecord`, the state names, and the traversal configuration.
|
|
14
|
+
|
|
15
|
+
Types and plain data only. It replaces the component repos' scripts that copy
|
|
16
|
+
host files by relative path.
|
|
17
|
+
|
|
18
|
+
**Publishing:** on npm as `@peripheries/runtime`, built output only, with
|
|
19
|
+
`@peripheries/renderer` (`npm run publish:packages`; design/renderer.md §11).
|
|
20
|
+
Version it with the host: a breaking change here is a breaking change for
|
|
21
|
+
every bundle.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//#region packages/runtime/src/config.ts
|
|
2
|
+
var SECTION_KINDS = [
|
|
3
|
+
"preamble",
|
|
4
|
+
"article",
|
|
5
|
+
"appendix",
|
|
6
|
+
"execution"
|
|
7
|
+
];
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region packages/runtime/src/graph.ts
|
|
10
|
+
var STATE_TIERS = [
|
|
11
|
+
"meta",
|
|
12
|
+
"eng",
|
|
13
|
+
"ops"
|
|
14
|
+
];
|
|
15
|
+
var STATE_ROLES = [
|
|
16
|
+
"data",
|
|
17
|
+
"process",
|
|
18
|
+
"model",
|
|
19
|
+
"appraisal"
|
|
20
|
+
];
|
|
21
|
+
var STATE_NAMES = STATE_TIERS.flatMap((t) => STATE_ROLES.map((r) => `${t}_${r}`));
|
|
22
|
+
var DEFAULT_STATE = "eng_data";
|
|
23
|
+
var isStateName = (v) => typeof v === "string" && STATE_NAMES.includes(v);
|
|
24
|
+
var WALK_DEFAULTS = {
|
|
25
|
+
direction: "incoming",
|
|
26
|
+
maxDepth: 3,
|
|
27
|
+
maxNodes: 50,
|
|
28
|
+
maxNodesCeiling: 500
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region packages/runtime/src/pinned.ts
|
|
32
|
+
var STACK_RUNTIME_VERSION = "0.1.0";
|
|
33
|
+
var RUNTIME_GLOBAL = "__STACK_RUNTIME__";
|
|
34
|
+
var LEGACY_RUNTIME_GLOBAL = "__OA_RUNTIME";
|
|
35
|
+
var READY_GLOBAL = "__STACK_RUNTIME_READY__";
|
|
36
|
+
var RESOLVE_GLOBAL = "__STACK_RUNTIME_RESOLVE__";
|
|
37
|
+
var PINNED_RUNTIMES = {
|
|
38
|
+
react: {
|
|
39
|
+
version: "^19.2.4",
|
|
40
|
+
url: "/_shared/react.js"
|
|
41
|
+
},
|
|
42
|
+
"react/jsx-runtime": {
|
|
43
|
+
version: "^19.2.4",
|
|
44
|
+
url: "/_shared/react-jsx-runtime.js"
|
|
45
|
+
},
|
|
46
|
+
"react/jsx-dev-runtime": {
|
|
47
|
+
version: "^19.2.4",
|
|
48
|
+
url: "/_shared/react-jsx-dev-runtime.js"
|
|
49
|
+
},
|
|
50
|
+
"react-dom": {
|
|
51
|
+
version: "^19.2.4",
|
|
52
|
+
url: "/_shared/react-dom.js"
|
|
53
|
+
},
|
|
54
|
+
"react-dom/client": {
|
|
55
|
+
version: "^19.2.4",
|
|
56
|
+
url: "/_shared/react-dom-client.js"
|
|
57
|
+
},
|
|
58
|
+
zustand: {
|
|
59
|
+
version: "^5.0.5",
|
|
60
|
+
url: "/_shared/zustand.js"
|
|
61
|
+
},
|
|
62
|
+
"@stack/store": {
|
|
63
|
+
version: "*",
|
|
64
|
+
url: "/_shared/stack-store.js"
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var SPECIFIER_ALIASES = { "@oa/store": "@stack/store" };
|
|
68
|
+
var HOST_INTERNAL_SHIMS = { "@stack/store": {
|
|
69
|
+
named: [
|
|
70
|
+
"useStore",
|
|
71
|
+
"useOAStore",
|
|
72
|
+
"getStore",
|
|
73
|
+
"selectors"
|
|
74
|
+
],
|
|
75
|
+
hasDefault: false
|
|
76
|
+
} };
|
|
77
|
+
function buildImportMap() {
|
|
78
|
+
const imports = {};
|
|
79
|
+
const pins = {};
|
|
80
|
+
for (const [specifier, pin] of Object.entries(PINNED_RUNTIMES)) {
|
|
81
|
+
imports[specifier] = pin.url;
|
|
82
|
+
pins[specifier] = pin.version;
|
|
83
|
+
}
|
|
84
|
+
for (const [alias, target] of Object.entries(SPECIFIER_ALIASES)) {
|
|
85
|
+
imports[alias] = PINNED_RUNTIMES[target].url;
|
|
86
|
+
pins[alias] = PINNED_RUNTIMES[target].version;
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
version: STACK_RUNTIME_VERSION,
|
|
90
|
+
imports,
|
|
91
|
+
pins
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { DEFAULT_STATE, HOST_INTERNAL_SHIMS, LEGACY_RUNTIME_GLOBAL, PINNED_RUNTIMES, READY_GLOBAL, RESOLVE_GLOBAL, RUNTIME_GLOBAL, SECTION_KINDS, SPECIFIER_ALIASES, STACK_RUNTIME_VERSION, STATE_NAMES, STATE_ROLES, STATE_TIERS, WALK_DEFAULTS, buildImportMap, isStateName };
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/config.ts","../src/graph.ts","../src/pinned.ts"],"mappings":";AAyGA,IAAa,gBAAgB;CAAC;CAAY;CAAW;CAAY;AAAW;;;ACtG5E,IAAa,cAAc;CAAC;CAAQ;CAAO;AAAK;AAChD,IAAa,cAAc;CAAC;CAAQ;CAAW;CAAS;AAAW;AASnE,IAAa,cAAc,YAAY,SAAS,MAAM,YAAY,KAAK,MAAM,GAAG,EAAE,GAAG,GAAgB,CAAC;AACtG,IAAa,gBAA2B;AACxC,IAAa,eAAe,MAA+B,OAAO,MAAM,YAAa,YAAyB,SAAS,CAAC;AAiExH,IAAa,gBAAgB;CAAE,WAAW;CAAY,UAAU;CAAG,UAAU;CAAI,iBAAiB;AAAI;;;ACpEtG,IAAa,wBAAwB;AAGrC,IAAa,iBAAiB;AAC9B,IAAa,wBAAwB;AAErC,IAAa,eAAe;AAC5B,IAAa,iBAAiB;AAS9B,IAAa,kBAAkB;CAC7B,OAAO;EAAE,SAAS;EAAW,KAAK;CAAoB;CACtD,qBAAqB;EAAE,SAAS;EAAW,KAAK;CAAgC;CAChF,yBAAyB;EAAE,SAAS;EAAW,KAAK;CAAoC;CACxF,aAAa;EAAE,SAAS;EAAW,KAAK;CAAwB;CAChE,oBAAoB;EAAE,SAAS;EAAW,KAAK;CAA+B;CAC9E,SAAS;EAAE,SAAS;EAAU,KAAK;CAAsB;CAEzD,gBAAgB;EAAE,SAAS;EAAK,KAAK;CAA0B;AACjE;AAKA,IAAa,oBAAsD,EACjE,aAAa,eACf;AAMA,IAAa,sBAAmG,EAC9G,gBAAgB;CAAE,OAAO;EAAC;EAAY;EAAc;EAAY;CAAW;CAAG,YAAY;AAAM,EAClG;AAUA,SAAgB,iBAAmC;CACjD,MAAM,UAAkC,CAAC;CACzC,MAAM,OAA+B,CAAC;CACtC,KAAK,MAAM,CAAC,WAAW,QAAQ,OAAO,QAAQ,eAAe,GAAG;EAC9D,QAAQ,aAAa,IAAI;EACzB,KAAK,aAAa,IAAI;CACxB;CACA,KAAK,MAAM,CAAC,OAAO,WAAW,OAAO,QAAQ,iBAAiB,GAAG;EAC/D,QAAQ,SAAS,gBAAgB,OAAO,CAAC;EACzC,KAAK,SAAS,gBAAgB,OAAO,CAAC;CACxC;CACA,OAAO;EAAE,SAAS;EAAuB;EAAS;CAAK;AACzD"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { StateName, TraversalConfig } from './graph.js';
|
|
2
|
+
/** A bundle reference: an org slug (its main lineage), a lineage, or a pinned bundle id. */
|
|
3
|
+
export type BundleRef = string | {
|
|
4
|
+
bundle_id: string;
|
|
5
|
+
} | {
|
|
6
|
+
bundle: string;
|
|
7
|
+
org_slug?: string;
|
|
8
|
+
};
|
|
9
|
+
export type ScopeKind = 'page' | 'project';
|
|
10
|
+
/** A shared-store selection a cell reads, and writes when `writable`. */
|
|
11
|
+
export interface SelectionDecl {
|
|
12
|
+
/** Channel shared by cells on the same scope. */
|
|
13
|
+
channel: string;
|
|
14
|
+
scope: ScopeKind;
|
|
15
|
+
/** Adds a `set<Name>` setter to the projection. */
|
|
16
|
+
writable?: boolean;
|
|
17
|
+
default?: unknown;
|
|
18
|
+
/** Mirror the value into a search param, so it survives refresh and sharing. */
|
|
19
|
+
url?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface ViewStateDecl {
|
|
22
|
+
key: string;
|
|
23
|
+
scope: ScopeKind;
|
|
24
|
+
/** viewState is writable unless this is `false`. */
|
|
25
|
+
writable?: boolean;
|
|
26
|
+
default?: unknown;
|
|
27
|
+
url?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface LiveDecl {
|
|
30
|
+
channel: string;
|
|
31
|
+
default?: unknown;
|
|
32
|
+
}
|
|
33
|
+
export type SelectionDeclarations = Record<string, SelectionDecl>;
|
|
34
|
+
export type ViewStateDeclarations = Record<string, ViewStateDecl>;
|
|
35
|
+
export type LiveDeclarations = Record<string, LiveDecl>;
|
|
36
|
+
/**
|
|
37
|
+
* A declared producer: a node's newest state, optionally at a dot-path.
|
|
38
|
+
* `state` names the systems to read (default `eng_data`), merged in order,
|
|
39
|
+
* later winning; `system_id` names one system outright. `as: 'record'` binds
|
|
40
|
+
* the whole NodeRecord instead of the state's data (design/renderer.md §4.3).
|
|
41
|
+
*/
|
|
42
|
+
export type DeclaredBinding = {
|
|
43
|
+
graph_node_id: string;
|
|
44
|
+
system_id?: string;
|
|
45
|
+
field?: string;
|
|
46
|
+
state?: StateName | StateName[];
|
|
47
|
+
as?: 'value' | 'record';
|
|
48
|
+
};
|
|
49
|
+
export type ResponsiveBucket = 'narrow' | 'compact' | 'wide';
|
|
50
|
+
export type CellLayout = {
|
|
51
|
+
span?: number;
|
|
52
|
+
order?: number;
|
|
53
|
+
className?: string;
|
|
54
|
+
sticky?: boolean;
|
|
55
|
+
zIndex?: number;
|
|
56
|
+
grid?: {
|
|
57
|
+
col?: string;
|
|
58
|
+
row?: string;
|
|
59
|
+
};
|
|
60
|
+
/** Each fires at or below its width: narrow 480, compact 720, wide 1024 (the page's width). */
|
|
61
|
+
hideWhen?: ResponsiveBucket;
|
|
62
|
+
showWhen?: ResponsiveBucket;
|
|
63
|
+
stackWhen?: ResponsiveBucket;
|
|
64
|
+
truncateWhen?: ResponsiveBucket;
|
|
65
|
+
};
|
|
66
|
+
export type CellData = {
|
|
67
|
+
static?: Record<string, unknown>;
|
|
68
|
+
queries?: Record<string, DeclaredBinding | {
|
|
69
|
+
registry: string;
|
|
70
|
+
params?: Record<string, unknown>;
|
|
71
|
+
}>;
|
|
72
|
+
};
|
|
73
|
+
/** The cell node that manages a cell's content: its newest `page_cell_config` in `system_id` (default the page's eng_data). */
|
|
74
|
+
export type CellRef = {
|
|
75
|
+
graph_node_id: string;
|
|
76
|
+
system_id?: string;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* A cell (design/renderer.md §3). Inline: the page holds its content. With a
|
|
80
|
+
* `ref`: the node manages its content and the page places it, and the inline
|
|
81
|
+
* fields are the fallback. Legacy forms are still read: `{ id, graph_node_id }`
|
|
82
|
+
* (a thin ref) as a ref, and an inline cell with a `graph_node_id` as inline,
|
|
83
|
+
* walking from that node.
|
|
84
|
+
*/
|
|
85
|
+
export type PageCell = {
|
|
86
|
+
id: string;
|
|
87
|
+
ref?: CellRef;
|
|
88
|
+
name?: string;
|
|
89
|
+
component?: string;
|
|
90
|
+
props?: Record<string, unknown>;
|
|
91
|
+
layout?: CellLayout;
|
|
92
|
+
conditions?: {
|
|
93
|
+
showIf?: unknown;
|
|
94
|
+
hideIf?: unknown;
|
|
95
|
+
};
|
|
96
|
+
children?: string[];
|
|
97
|
+
traversal?: TraversalConfig;
|
|
98
|
+
data?: CellData;
|
|
99
|
+
bundle_ref?: unknown;
|
|
100
|
+
actions?: Record<string, string>;
|
|
101
|
+
selections?: SelectionDeclarations;
|
|
102
|
+
viewState?: ViewStateDeclarations;
|
|
103
|
+
live?: LiveDeclarations;
|
|
104
|
+
metadata?: Record<string, unknown>;
|
|
105
|
+
graph_node_id?: string;
|
|
106
|
+
};
|
|
107
|
+
export declare const SECTION_KINDS: readonly ["preamble", "article", "appendix", "execution"];
|
|
108
|
+
export type SectionKind = (typeof SECTION_KINDS)[number];
|
|
109
|
+
/** A `layout.structure` node. A string is sugar for `{ cellId }`. */
|
|
110
|
+
export type LayoutNode = {
|
|
111
|
+
cellId?: string;
|
|
112
|
+
children?: Array<LayoutNode | string>;
|
|
113
|
+
order?: number;
|
|
114
|
+
sectionId?: string;
|
|
115
|
+
documentId?: string;
|
|
116
|
+
title?: string;
|
|
117
|
+
level?: number;
|
|
118
|
+
tocHidden?: boolean;
|
|
119
|
+
kind?: SectionKind | string;
|
|
120
|
+
slot?: string;
|
|
121
|
+
print?: {
|
|
122
|
+
breakBefore?: boolean;
|
|
123
|
+
breakInside?: 'auto' | 'avoid';
|
|
124
|
+
keepWithPrevious?: boolean;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { LiveDeclarations, SelectionDeclarations, ViewStateDeclarations } from './config.js';
|
|
2
|
+
export interface UserContext {
|
|
3
|
+
id: string;
|
|
4
|
+
email: string;
|
|
5
|
+
fullName: string;
|
|
6
|
+
}
|
|
7
|
+
export interface TenantContext {
|
|
8
|
+
id: string;
|
|
9
|
+
orgSlug: string;
|
|
10
|
+
name: string;
|
|
11
|
+
/** Present when the rendering tenant is a client of an advisor org. */
|
|
12
|
+
advisorOrgSlug?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Branding tokens: the org template's theme for the surface, camelCase and snake_case both present. */
|
|
15
|
+
export interface ThemeConfig {
|
|
16
|
+
primaryColor: string;
|
|
17
|
+
secondaryColor: string;
|
|
18
|
+
logoUrl?: string;
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface BaseProps {
|
|
22
|
+
user: UserContext;
|
|
23
|
+
tenant: TenantContext;
|
|
24
|
+
theme: ThemeConfig;
|
|
25
|
+
}
|
|
26
|
+
export interface CellStatus {
|
|
27
|
+
isLoading: boolean;
|
|
28
|
+
isError: boolean;
|
|
29
|
+
errors?: Error[];
|
|
30
|
+
}
|
|
31
|
+
/** What an action returns. Actions never throw. */
|
|
32
|
+
export interface WriteResult<T = unknown> {
|
|
33
|
+
success: boolean;
|
|
34
|
+
data?: T;
|
|
35
|
+
id?: string;
|
|
36
|
+
errors?: Array<{
|
|
37
|
+
message: string;
|
|
38
|
+
field?: string;
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
export type CellAction<TInput = unknown, TResult = unknown> = (input: TInput) => Promise<WriteResult<TResult>>;
|
|
42
|
+
/** Where the cell is: the same object an agent receives as its context. */
|
|
43
|
+
export interface CellContext {
|
|
44
|
+
environment?: string;
|
|
45
|
+
orgId?: string | null;
|
|
46
|
+
clientId?: string | null;
|
|
47
|
+
projectId?: string | null;
|
|
48
|
+
processId?: string | null;
|
|
49
|
+
pageId?: string;
|
|
50
|
+
/** The cell's own graph node, when it has one. */
|
|
51
|
+
nodeId?: string;
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
}
|
|
54
|
+
/** Projected shared-store values: each declared name, plus `set<Name>` where writable. */
|
|
55
|
+
export type ProjectedStore = Record<string, unknown>;
|
|
56
|
+
/** The measured container, for components whose contract declares `size: true`. */
|
|
57
|
+
export interface Size {
|
|
58
|
+
width: number;
|
|
59
|
+
height: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Every prop the host passes a cell component, in addition to its own
|
|
63
|
+
* `cell.props` (resolved). Host-provided props win over authored ones of the
|
|
64
|
+
* same name, except `children`: child cells replace it only when there are some.
|
|
65
|
+
*/
|
|
66
|
+
export interface CellProps<TData extends Record<string, unknown> = Record<string, unknown>> {
|
|
67
|
+
baseProps: BaseProps;
|
|
68
|
+
children?: unknown;
|
|
69
|
+
isLoading: boolean;
|
|
70
|
+
error: Error | null;
|
|
71
|
+
data?: TData;
|
|
72
|
+
status?: CellStatus;
|
|
73
|
+
actions?: Record<string, CellAction>;
|
|
74
|
+
selections?: ProjectedStore;
|
|
75
|
+
viewState?: ProjectedStore;
|
|
76
|
+
live?: ProjectedStore;
|
|
77
|
+
size?: Size;
|
|
78
|
+
navigate: (to: string) => void;
|
|
79
|
+
/** The PWA's name for `navigate`. */
|
|
80
|
+
onNavigate: (to: string) => void;
|
|
81
|
+
context: CellContext;
|
|
82
|
+
}
|
|
83
|
+
/** On a document page, the whole document's facts, narrowed to the cell's own document. */
|
|
84
|
+
export interface DocumentCellProps {
|
|
85
|
+
sectionNumbers: Record<string, number[]>;
|
|
86
|
+
sectionLevels: Record<string, number>;
|
|
87
|
+
sectionAuthoredLevels: Record<string, number>;
|
|
88
|
+
sectionTitles: Record<string, string>;
|
|
89
|
+
sectionAnchors: Record<string, string>;
|
|
90
|
+
sectionReferences: Record<string, SectionReference>;
|
|
91
|
+
}
|
|
92
|
+
export interface SectionReference {
|
|
93
|
+
number?: number[];
|
|
94
|
+
title?: string;
|
|
95
|
+
anchor?: string;
|
|
96
|
+
href?: string;
|
|
97
|
+
openable: boolean;
|
|
98
|
+
element?: {
|
|
99
|
+
index: number;
|
|
100
|
+
shape: ReadonlyArray<{
|
|
101
|
+
level?: number;
|
|
102
|
+
marker?: string;
|
|
103
|
+
}>;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** Per component in a bundle's contracts.json. */
|
|
107
|
+
export interface ComponentContract {
|
|
108
|
+
/** The host measures the container and passes `size`. */
|
|
109
|
+
size?: boolean;
|
|
110
|
+
[key: string]: unknown;
|
|
111
|
+
}
|
|
112
|
+
export type { LiveDeclarations, SelectionDeclarations, ViewStateDeclarations };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export declare const STATE_TIERS: readonly ["meta", "eng", "ops"];
|
|
2
|
+
export declare const STATE_ROLES: readonly ["data", "process", "model", "appraisal"];
|
|
3
|
+
export type StateTier = (typeof STATE_TIERS)[number];
|
|
4
|
+
export type StateRole = (typeof STATE_ROLES)[number];
|
|
5
|
+
/**
|
|
6
|
+
* A system, named for the `process.<tier>_<role>_system_id` column that holds
|
|
7
|
+
* it: `eng_data` is the engineering DSNS, `eng_process` its PSNS, and so on.
|
|
8
|
+
*/
|
|
9
|
+
export type StateName = `${StateTier}_${StateRole}`;
|
|
10
|
+
export declare const STATE_NAMES: ("meta_data" | "meta_process" | "meta_model" | "meta_appraisal" | "eng_data" | "eng_process" | "eng_model" | "eng_appraisal" | "ops_data" | "ops_process" | "ops_model" | "ops_appraisal")[];
|
|
11
|
+
export declare const DEFAULT_STATE: StateName;
|
|
12
|
+
export declare const isStateName: (v: unknown) => v is StateName;
|
|
13
|
+
/** A node's newest non-archived state in one system. */
|
|
14
|
+
export interface StateRecord {
|
|
15
|
+
id: string;
|
|
16
|
+
system_id: string;
|
|
17
|
+
data: unknown;
|
|
18
|
+
status: string | null;
|
|
19
|
+
created_at: string;
|
|
20
|
+
}
|
|
21
|
+
export interface NodeRecord {
|
|
22
|
+
/** `node.id`: what `EdgeRecord.source` and `.target` name. */
|
|
23
|
+
id: string;
|
|
24
|
+
/** `graph_node.id`: what state rows and page cells name. */
|
|
25
|
+
graph_node_id: string;
|
|
26
|
+
name: string | null;
|
|
27
|
+
node_type: string | null;
|
|
28
|
+
status: string | null;
|
|
29
|
+
content: Record<string, unknown> | null;
|
|
30
|
+
metadata?: Record<string, unknown> | null;
|
|
31
|
+
/** `graph_node.rank`, the sibling order. */
|
|
32
|
+
rank: string | null;
|
|
33
|
+
updated_at: string | null;
|
|
34
|
+
/** Hops from the walk's start (walks only). */
|
|
35
|
+
depth?: number;
|
|
36
|
+
/** Only the systems asked for: absent when not asked, `null` when asked and the node has none. */
|
|
37
|
+
state: Partial<Record<StateName, StateRecord | null>>;
|
|
38
|
+
}
|
|
39
|
+
export interface EdgeRecord {
|
|
40
|
+
/** `graph_edge.id` */
|
|
41
|
+
id: string;
|
|
42
|
+
/** `edge.id` */
|
|
43
|
+
edge_id: string;
|
|
44
|
+
source: string;
|
|
45
|
+
target: string;
|
|
46
|
+
edge_type: string | null;
|
|
47
|
+
content?: unknown;
|
|
48
|
+
}
|
|
49
|
+
/** `@_traversal`: the cell's walk, without its start node and the page artifact. */
|
|
50
|
+
export interface Traversal {
|
|
51
|
+
nodes: NodeRecord[];
|
|
52
|
+
edges: EdgeRecord[];
|
|
53
|
+
}
|
|
54
|
+
/** A cell's `traversal`: how its walk runs. */
|
|
55
|
+
export interface TraversalConfig {
|
|
56
|
+
/** Default `incoming`: from the cell or page toward its producers. */
|
|
57
|
+
direction?: 'incoming' | 'outgoing' | 'both';
|
|
58
|
+
/** Required: the edge types the walk follows. */
|
|
59
|
+
edgeTypes: string[];
|
|
60
|
+
/** The walk enters only these types, so nothing past another type is reached. */
|
|
61
|
+
nodeTypes?: string[];
|
|
62
|
+
/** Default 3. */
|
|
63
|
+
maxDepth?: number;
|
|
64
|
+
/** Default 50, at most 500, the start included. */
|
|
65
|
+
maxNodes?: number;
|
|
66
|
+
/** The systems each reached node's state is read from. Default `['eng_data']`. */
|
|
67
|
+
include_state?: StateName[];
|
|
68
|
+
excludeNodeTypes?: string[];
|
|
69
|
+
excludeEdgeTypes?: string[];
|
|
70
|
+
}
|
|
71
|
+
export declare const WALK_DEFAULTS: {
|
|
72
|
+
readonly direction: "incoming";
|
|
73
|
+
readonly maxDepth: 3;
|
|
74
|
+
readonly maxNodes: 50;
|
|
75
|
+
readonly maxNodesCeiling: 500;
|
|
76
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shared runtime the host lends to federated bundles: one React, one
|
|
3
|
+
* ReactDOM, zustand, and the shared store. Single source of truth for the
|
|
4
|
+
* import map, the generated `/_shared/*.js` shims, and
|
|
5
|
+
* `/_shared/import-map.json`, which FEC repos' `validate-externals` reads to
|
|
6
|
+
* check their `external` list and peer ranges.
|
|
7
|
+
*
|
|
8
|
+
* Names are generic (design/bundles.md §6). The `@oa/*` specifier and the
|
|
9
|
+
* `__OA_RUNTIME` global stay as aliases until every FEC repo builds with the
|
|
10
|
+
* new names.
|
|
11
|
+
*/
|
|
12
|
+
export declare const STACK_RUNTIME_VERSION = "0.1.0";
|
|
13
|
+
/** `globalThis[RUNTIME_GLOBAL][specifier]` is what each shim forwards. */
|
|
14
|
+
export declare const RUNTIME_GLOBAL = "__STACK_RUNTIME__";
|
|
15
|
+
export declare const LEGACY_RUNTIME_GLOBAL = "__OA_RUNTIME";
|
|
16
|
+
/** A promise created by the boot script; resolved once the runtime is installed. */
|
|
17
|
+
export declare const READY_GLOBAL = "__STACK_RUNTIME_READY__";
|
|
18
|
+
export declare const RESOLVE_GLOBAL = "__STACK_RUNTIME_RESOLVE__";
|
|
19
|
+
export type PinnedRuntime = {
|
|
20
|
+
/** Semver range a bundle's peerDependencies must satisfy. */
|
|
21
|
+
version: string;
|
|
22
|
+
/** URL the import map points the specifier at. */
|
|
23
|
+
url: string;
|
|
24
|
+
};
|
|
25
|
+
export declare const PINNED_RUNTIMES: {
|
|
26
|
+
readonly react: {
|
|
27
|
+
readonly version: "^19.2.4";
|
|
28
|
+
readonly url: "/_shared/react.js";
|
|
29
|
+
};
|
|
30
|
+
readonly 'react/jsx-runtime': {
|
|
31
|
+
readonly version: "^19.2.4";
|
|
32
|
+
readonly url: "/_shared/react-jsx-runtime.js";
|
|
33
|
+
};
|
|
34
|
+
readonly 'react/jsx-dev-runtime': {
|
|
35
|
+
readonly version: "^19.2.4";
|
|
36
|
+
readonly url: "/_shared/react-jsx-dev-runtime.js";
|
|
37
|
+
};
|
|
38
|
+
readonly 'react-dom': {
|
|
39
|
+
readonly version: "^19.2.4";
|
|
40
|
+
readonly url: "/_shared/react-dom.js";
|
|
41
|
+
};
|
|
42
|
+
readonly 'react-dom/client': {
|
|
43
|
+
readonly version: "^19.2.4";
|
|
44
|
+
readonly url: "/_shared/react-dom-client.js";
|
|
45
|
+
};
|
|
46
|
+
readonly zustand: {
|
|
47
|
+
readonly version: "^5.0.5";
|
|
48
|
+
readonly url: "/_shared/zustand.js";
|
|
49
|
+
};
|
|
50
|
+
readonly '@stack/store': {
|
|
51
|
+
readonly version: "*";
|
|
52
|
+
readonly url: "/_shared/stack-store.js";
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
export type RuntimeSpecifier = keyof typeof PINNED_RUNTIMES;
|
|
56
|
+
/** Old specifier → the specifier it now resolves to. */
|
|
57
|
+
export declare const SPECIFIER_ALIASES: Record<string, RuntimeSpecifier>;
|
|
58
|
+
/**
|
|
59
|
+
* Specifiers with no installed package to introspect: their export surface is
|
|
60
|
+
* declared here and pinned by a test against the object the host installs.
|
|
61
|
+
*/
|
|
62
|
+
export declare const HOST_INTERNAL_SHIMS: Partial<Record<RuntimeSpecifier, {
|
|
63
|
+
named: string[];
|
|
64
|
+
hasDefault: boolean;
|
|
65
|
+
}>>;
|
|
66
|
+
export type ImportMapPayload = {
|
|
67
|
+
version: string;
|
|
68
|
+
imports: Record<string, string>;
|
|
69
|
+
/** Specifier → the semver range the host pins it to. */
|
|
70
|
+
pins: Record<string, string>;
|
|
71
|
+
};
|
|
72
|
+
/** The `<script type="importmap">` body, and the JSON FEC CI validates against. */
|
|
73
|
+
export declare function buildImportMap(): ImportMapPayload;
|
package/package.json
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peripheries/runtime",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The host's runtime contract for federated component bundles: pinned shared specifiers, the import map, and the types of what a cell component receives.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/types/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"license": "UNLICENSED",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/peripheries-clients/peripheries-stack.git",
|
|
21
|
+
"directory": "packages/runtime"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
}
|
|
26
|
+
}
|