@nodegx/export 0.0.0-stage → 0.2.6
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/LICENSE +674 -0
- package/README.md +76 -2
- package/dist/analyze/appState.d.ts +303 -0
- package/dist/analyze/plan.d.ts +3904 -0
- package/dist/analyze/querySettings.d.ts +75 -0
- package/dist/analyze/reach.d.ts +41 -0
- package/dist/analyze/scriptUses.d.ts +29 -0
- package/dist/catalog.d.ts +129 -0
- package/dist/cli/args.d.ts +100 -0
- package/dist/cli/exitCodes.d.ts +125 -0
- package/dist/cli/run.d.ts +30 -0
- package/dist/cli.inputs.json +203 -0
- package/dist/cli.mjs +62547 -0
- package/dist/cli.mjs.map +7 -0
- package/dist/emit/animateLib.d.ts +43 -0
- package/dist/emit/component.d.ts +166 -0
- package/dist/emit/dateLib.d.ts +45 -0
- package/dist/emit/emitApp.d.ts +38 -0
- package/dist/emit/idLib.d.ts +68 -0
- package/dist/emit/kits.d.ts +91 -0
- package/dist/emit/mediaLib.d.ts +75 -0
- package/dist/emit/naming.d.ts +76 -0
- package/dist/emit/parseLib.d.ts +108 -0
- package/dist/emit/preflight.d.ts +174 -0
- package/dist/emit/readme.d.ts +51 -0
- package/dist/emit/report.d.ts +309 -0
- package/dist/emit/scaffold.d.ts +83 -0
- package/dist/emit/statesLib.d.ts +52 -0
- package/dist/emit/style.d.ts +181 -0
- package/dist/emit/utilLib.d.ts +78 -0
- package/dist/errorMessage.d.ts +28 -0
- package/dist/index.cjs +61649 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.mjs +61570 -0
- package/dist/index.mjs.map +7 -0
- package/dist/ir/types.d.ts +567 -0
- package/dist/ledger.cjs +971 -0
- package/dist/ledger.cjs.map +7 -0
- package/dist/ledger.d.ts +75 -0
- package/dist/ledger.mjs +948 -0
- package/dist/ledger.mjs.map +7 -0
- package/dist/node-catalog.json +65370 -0
- package/dist/parse/kitSource.d.ts +135 -0
- package/dist/parse/parseModules.d.ts +42 -0
- package/dist/parse/parseProject.d.ts +13 -0
- package/dist/react19/VERSION +2 -0
- package/dist/react19/react-dom.production.min.js +51 -0
- package/dist/react19/react.production.min.js +21 -0
- package/dist/scriptFiles.d.ts +30 -0
- package/dist/structurePorts.d.ts +70 -0
- package/dist/write/writeExport.d.ts +67 -0
- package/package.json +53 -4
package/README.md
CHANGED
|
@@ -1,3 +1,77 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@nodegx/export`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Turns a [NodeGX](https://github.com/The-Low-Code-Foundation/NodeGX) project on disk into a React +
|
|
4
|
+
Vite application: project files → IR → analysis → generated source. It is the same code path the
|
|
5
|
+
editor's **Export React code** command runs; there is no second implementation. It can also write the app as plain
|
|
6
|
+
HTML, CSS and JavaScript files (see "Plain files, nothing to install" below).
|
|
7
|
+
|
|
8
|
+
Everything here is a pure function over files. Nothing opens a window, and nothing needs a display
|
|
9
|
+
server — which is the point: this is the half of NodeGX that a CI job or an agent can drive.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm i @nodegx/export
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Requires Node ≥ 22.
|
|
16
|
+
|
|
17
|
+
## Use
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import { emitApp, loadCatalog, parseProject, summarizePreflight, renderPreflight } from '@nodegx/export';
|
|
21
|
+
import fs from 'node:fs';
|
|
22
|
+
import path from 'node:path';
|
|
23
|
+
|
|
24
|
+
const catalog = loadCatalog(); // ships with this package
|
|
25
|
+
const ir = parseProject('./my-project', catalog);
|
|
26
|
+
const app = emitApp(ir, catalog);
|
|
27
|
+
|
|
28
|
+
// What the export will produce, before choosing where to put it — writes nothing.
|
|
29
|
+
console.log(renderPreflight(summarizePreflight(app)));
|
|
30
|
+
|
|
31
|
+
for (const [file, contents] of Object.entries(app.files)) {
|
|
32
|
+
fs.mkdirSync(path.dirname(path.join('out', file)), { recursive: true });
|
|
33
|
+
fs.writeFileSync(path.join('out', file), contents);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`app.files` is a `path → contents` map; `app.copies` lists the files that travel byte-for-byte
|
|
38
|
+
(fonts and other `noodl_modules` assets) rather than being generated, because a `.ttf` is not a
|
|
39
|
+
string. `app.notes` and `app.report` are what the export dropped or deferred.
|
|
40
|
+
|
|
41
|
+
## Plain files, nothing to install
|
|
42
|
+
|
|
43
|
+
`--target html` writes the app as plain HTML, CSS and JavaScript: no npm, no framework, no build step. Any static
|
|
44
|
+
server serves the folder as it is.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx @nodegx/export export --target html --dry-run ./my-project # what will and will not travel; writes nothing
|
|
48
|
+
npx @nodegx/export export --target html ./my-project ./my-app-html
|
|
49
|
+
npx serve ./my-app-html # or any static server
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
An app with a backend keeps talking to the backend it was bound to. To point it at another one, write that
|
|
53
|
+
backend's address in the folder's `env.js`. `--component <name>` writes one component and what it needs into a
|
|
54
|
+
folder your own page shares, with no `index.html` and no router; exporting again replaces only the files the last
|
|
55
|
+
export wrote, and refuses if you changed one of them by hand. Needs Node 22.13 or later.
|
|
56
|
+
|
|
57
|
+
## What it does not do
|
|
58
|
+
|
|
59
|
+
- **It does not deploy.** Deploying the interpreted viewer needs the editor's live project model;
|
|
60
|
+
this package parses files.
|
|
61
|
+
- **It does not read the graph the editor rewrites on open.** The editor applies a set of patches
|
|
62
|
+
when it loads a project and this package reads the files as written. Where the two disagree, the
|
|
63
|
+
export follows the file. Closing that gap is tracked as HLS-003.
|
|
64
|
+
- **It emits an app that does not yet pass `npm run build` in every case.** See
|
|
65
|
+
[#24](https://github.com/The-Low-Code-Foundation/NodeGX/issues/24). (Measured 2026-10-21: 16 of the 17 shipped
|
|
66
|
+
templates typecheck; the one error is a known row.)
|
|
67
|
+
- **It does not yet carry every Function.** `nodegx export --dry-run` prints first, per node, what will and will not
|
|
68
|
+
translate and why; read that before anything else. A Function that keeps state on `this`, reads the clock, draws
|
|
69
|
+
randomness, schedules a timer or touches the browser travels as written when a Run wire drives it (2026-10-21); one that
|
|
70
|
+
awaits, reads `Noodl.*`, or sits in a logic component does not yet, and the preflight says so by name.
|
|
71
|
+
|
|
72
|
+
Both of those are worth knowing before putting this in a pipeline, because in a pipeline there is
|
|
73
|
+
nobody to notice.
|
|
74
|
+
|
|
75
|
+
## Licence
|
|
76
|
+
|
|
77
|
+
GPL-3.0.
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App-wide state discovery (EXP-002 step 5). Variables (Variable2 / Set Variable) and event
|
|
3
|
+
* channels (Event Sender / Event Receiver) are app-global constructs: their identity is a
|
|
4
|
+
* literal name parameter, not a wire — the interpreter holds every Variable as one property of
|
|
5
|
+
* the shared `--ndl--global-variables` record, and events travel a channel-name-keyed global
|
|
6
|
+
* bus. This pass walks the whole IR once and produces the registry the per-component planner
|
|
7
|
+
* and the stores/events emitters share.
|
|
8
|
+
*
|
|
9
|
+
* Typing is inference over statically-known writes (EXP-002-STEP5-TARGET-OUTPUT.md §1): a text
|
|
10
|
+
* input writes `string`; a payload key's type follows its senders' wires; a Variable read
|
|
11
|
+
* follows that variable's own writers. A writer whose source cannot be typed makes the whole
|
|
12
|
+
* variable `unknown` — and an `unknown` variable bound into rendered content defers rather than
|
|
13
|
+
* emitting TypeScript that does not compile. Nodes with non-literal names defer entirely: a
|
|
14
|
+
* computed variable or channel name is genuinely dynamic (EXP-003's territory).
|
|
15
|
+
*/
|
|
16
|
+
import { ComponentIR, ExportIR, NodeIR } from '../ir/types';
|
|
17
|
+
export interface VariableWriter {
|
|
18
|
+
componentPath: string;
|
|
19
|
+
nodeId: string;
|
|
20
|
+
nodeType: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
/**
|
|
23
|
+
* EXP-011 §67. Set when the writer is a `Variable` node carrying an authored `Value`: the
|
|
24
|
+
* runtime's `value` input setter runs at node creation with that parameter and schedules a
|
|
25
|
+
* store (variablenode2.ts), so the node writes the variable on every mount of its component.
|
|
26
|
+
*/
|
|
27
|
+
seed?: string | number | boolean;
|
|
28
|
+
/**
|
|
29
|
+
* EXP-011 §71. Set when the writer is an `Object` node carrying values typed into its OWN
|
|
30
|
+
* `prop-<key>` inputs: the runtime registers any `prop-*` input on demand and queues every
|
|
31
|
+
* authored parameter into the node at creation (nodescope.ts), the setter marks the key dirty
|
|
32
|
+
* and `scheduleStore` writes it into the record in the same pass (modelnode2.ts) — so the node
|
|
33
|
+
* writes these keys on every mount of its component. Parameter order, as the runtime writes them.
|
|
34
|
+
*/
|
|
35
|
+
seeds?: Array<{
|
|
36
|
+
key: string;
|
|
37
|
+
value: string | number | boolean;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export interface VariablePlan {
|
|
41
|
+
/** The authored variable name — the shared-record key. */
|
|
42
|
+
name: string;
|
|
43
|
+
/** The identifier `src/stores/variables.ts` exports. */
|
|
44
|
+
exportName: string;
|
|
45
|
+
/** 'string' when every statically-known write is string-typed; 'unknown' otherwise. */
|
|
46
|
+
tsType: 'string' | 'unknown';
|
|
47
|
+
/** The writing constructs the graph names, for the module's doc comment. */
|
|
48
|
+
writers: VariableWriter[];
|
|
49
|
+
}
|
|
50
|
+
export interface ChannelSender {
|
|
51
|
+
componentPath: string;
|
|
52
|
+
nodeId: string;
|
|
53
|
+
label?: string;
|
|
54
|
+
}
|
|
55
|
+
/** A JSON-literal type, as far as a store key's TypeScript type can be read off one. */
|
|
56
|
+
export type StoreKeyTsType = 'string' | 'number' | 'boolean' | 'unknown';
|
|
57
|
+
export interface StoreKeyPlan {
|
|
58
|
+
key: string;
|
|
59
|
+
/** From the initial-state literal when present; else inferred over the key's Set writers. */
|
|
60
|
+
tsType: StoreKeyTsType;
|
|
61
|
+
/** Present (and `required`) when a declarer's initialState carries this key. */
|
|
62
|
+
initial?: unknown;
|
|
63
|
+
required: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** A sentence about one Global Store declarer, with where it sits. */
|
|
66
|
+
export interface StoreNote {
|
|
67
|
+
componentPath: string;
|
|
68
|
+
nodeId: string;
|
|
69
|
+
text: string;
|
|
70
|
+
}
|
|
71
|
+
export interface StorePlan {
|
|
72
|
+
/** The authored store name — 'app' when every naming node used the default. */
|
|
73
|
+
name: string;
|
|
74
|
+
/** The identifier `src/stores/<exportName>.ts` exports. */
|
|
75
|
+
exportName: string;
|
|
76
|
+
/** `MoodState`. */
|
|
77
|
+
interfaceName: string;
|
|
78
|
+
/** Initial-state keys first (transcription order), then writer-discovered keys. */
|
|
79
|
+
keys: StoreKeyPlan[];
|
|
80
|
+
/** `net.noodl.GlobalStore` nodes naming this store. */
|
|
81
|
+
declarers: VariableWriter[];
|
|
82
|
+
/** `net.noodl.GlobalStore.Set` nodes writing this store. */
|
|
83
|
+
writers: VariableWriter[];
|
|
84
|
+
/**
|
|
85
|
+
* EXP-011 §78. The State History, Undo / Redo, State Snapshot and Optimistic Update nodes naming this store. Each is
|
|
86
|
+
* handed the store module itself, so a store one of them names is emitted even when no Global Store node declares it.
|
|
87
|
+
*/
|
|
88
|
+
historians?: VariableWriter[];
|
|
89
|
+
/** Set: the whole store defers (a wired or disputed persist, unparseable initial state on every declarer). */
|
|
90
|
+
deferred?: string;
|
|
91
|
+
/**
|
|
92
|
+
* EXP-021 AC4 (session 139). Present when a declarer authors Persist: the store is kept in browser storage under
|
|
93
|
+
* `noodl_store_<storageKey>` (the runtime's `STORAGE_KEY_PREFIX`), the Storage Key defaulting to the store's name.
|
|
94
|
+
*/
|
|
95
|
+
persist?: {
|
|
96
|
+
storageKey: string;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Merged initial states, ignored storageKeys — one per declarer, routed app-wide by `emitApp` (P18-S110-STORENOTES:
|
|
100
|
+
* this list had no reader, so "nothing dropped silently" did not hold for it).
|
|
101
|
+
*/
|
|
102
|
+
notes: StoreNote[];
|
|
103
|
+
/**
|
|
104
|
+
* EXP-011 §47. Present when the store is a named **Object** — an `Object` node in "Specify
|
|
105
|
+
* explicitly" mode with a literal Id, and the `Set Object Properties` nodes naming the same
|
|
106
|
+
* Id — rather than a Global Store. The two are one construct in the exported app (`store()`
|
|
107
|
+
* in `@nodegx/core` says so in its own doc comment) and two records in the runtime, where a
|
|
108
|
+
* Global Store is the Model keyed `--ndl--global-store--<name>` and an Object is the Model
|
|
109
|
+
* keyed by its Id; `objectCollisions` is where that difference is kept honest.
|
|
110
|
+
*/
|
|
111
|
+
origin?: 'object';
|
|
112
|
+
}
|
|
113
|
+
export declare const GLOBAL_STORE = "net.noodl.GlobalStore";
|
|
114
|
+
export declare const GLOBAL_STORE_SET = "net.noodl.GlobalStore.Set";
|
|
115
|
+
export declare const GLOBAL_STORE_SUBSCRIBE = "net.noodl.GlobalStore.Subscribe";
|
|
116
|
+
export declare function isGlobalStoreFamily(type: string): boolean;
|
|
117
|
+
export declare function isHistoryFamily(type: string): boolean;
|
|
118
|
+
/** `Object` — displayed "Object", stored as `Model2` (modelnode2.ts). */
|
|
119
|
+
export declare const OBJECT_TYPE = "Model2";
|
|
120
|
+
/** `Set Object Properties` (setmodelpropertiesnode.ts, over modelcrudbase.ts). */
|
|
121
|
+
export declare const SET_OBJECT_PROPERTIES_TYPE = "SetModelProperties";
|
|
122
|
+
/**
|
|
123
|
+
* EXP-011 §47. The Id an `Object` or `Set Object Properties` names **statically**, or undefined.
|
|
124
|
+
*
|
|
125
|
+
* Three facts of the runtime decide the shape: `idSource` defaults to `explicit` (an unset one
|
|
126
|
+
* is explicit — `modelcrudbase.ts` declares the default, and the §5.1 gate has read it so since
|
|
127
|
+
* Tier 1.1); in that mode the record is `Model.get(modelId)`, create-on-read, keyed by the Id
|
|
128
|
+
* verbatim; and a wired Id is a runtime value (a Model, a plain object, or a string from
|
|
129
|
+
* anywhere), which is exactly what no module can name. So: explicit or unset, an unwired
|
|
130
|
+
* `modelId`, a non-empty literal string — else undefined, and the caller says which.
|
|
131
|
+
*/
|
|
132
|
+
export declare function objectIdOf(node: NodeIR, wiredPorts: Set<string>): string | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* A `Set Object Properties`' authored property list, split as the runtime splits it. The list
|
|
135
|
+
* is load-bearing on the write side: `_pushInputValues` filters the keys it writes by this list
|
|
136
|
+
* (`validProperties`), so a wired `prop-<x>` whose `x` is not listed is silently not written.
|
|
137
|
+
*/
|
|
138
|
+
/**
|
|
139
|
+
* EXP-011 §71. The values typed into an `Object` node's OWN `prop-<key>` inputs with nothing wired
|
|
140
|
+
* over them, in parameter order — what the runtime writes into the record at node creation
|
|
141
|
+
* (nodescope.ts queues every authored parameter; modelnode2.ts `userInputSetter` ⇒ dirty ⇒
|
|
142
|
+
* `scheduleStore` ⇒ `model.set`), on every mount of the holding component. The node's Properties
|
|
143
|
+
* list gates nothing here: `registerInputIfNeeded` registers ANY `prop-*` (measured, session 94).
|
|
144
|
+
* Under a wire on the same port the literal is not here (the wire's arrivals land over it, and
|
|
145
|
+
* plan.ts refuses the node by name); a non-primitive value is not here either — plan.ts notes it.
|
|
146
|
+
* One function for both files so discovery (the key's type) and the plan (the write) agree.
|
|
147
|
+
*/
|
|
148
|
+
export declare function objectSeedsOf(node: NodeIR, wiredPorts: Set<string>): Array<{
|
|
149
|
+
key: string;
|
|
150
|
+
value: string | number | boolean;
|
|
151
|
+
}>;
|
|
152
|
+
export declare function setPropertiesOf(node: NodeIR): string[];
|
|
153
|
+
/** One translated `NewModel → CollectionInsert` chain — the write side of a named array. */
|
|
154
|
+
export interface CollectionInserterRef {
|
|
155
|
+
componentPath: string;
|
|
156
|
+
newModelId: string;
|
|
157
|
+
insertId: string;
|
|
158
|
+
/** The NewModel's authored label. */
|
|
159
|
+
label?: string;
|
|
160
|
+
}
|
|
161
|
+
export interface CollectionKeyPlan {
|
|
162
|
+
key: string;
|
|
163
|
+
/** Union over the key's statically-known insert sources; conflicting sources ⇒ 'unknown'. */
|
|
164
|
+
tsType: StoreKeyTsType;
|
|
165
|
+
}
|
|
166
|
+
export interface CollectionPlan {
|
|
167
|
+
/** The authored `collectionId` — the shared-array-table key. */
|
|
168
|
+
name: string;
|
|
169
|
+
/** The identifier `src/collections/<exportName>.ts` exports. */
|
|
170
|
+
exportName: string;
|
|
171
|
+
/** `NotesItem`. */
|
|
172
|
+
interfaceName: string;
|
|
173
|
+
/** Union of statically-known inserted property sets, first-seen order, all optional. */
|
|
174
|
+
keys: CollectionKeyPlan[];
|
|
175
|
+
/** `Collection2` nodes naming this array. */
|
|
176
|
+
readers: VariableWriter[];
|
|
177
|
+
/** Translated insert chains writing this array. */
|
|
178
|
+
inserters: CollectionInserterRef[];
|
|
179
|
+
/**
|
|
180
|
+
* Array mutators naming this array — EXP-011 Tier 1.1's `Clear Array`.
|
|
181
|
+
*
|
|
182
|
+
* Registered here rather than folded into {@link readers} because the doc comment on the
|
|
183
|
+
* emitted module is the only place an author can see who touches the array, and "named by"
|
|
184
|
+
* and "emptied by" are different facts. ⚠️ Registration is what makes the module exist: an
|
|
185
|
+
* array a `Clear Array` names and nothing else reads still needs a `src/collections/<x>.ts`
|
|
186
|
+
* for the emitted `.clear()` to have a subject.
|
|
187
|
+
*/
|
|
188
|
+
mutators: VariableWriter[];
|
|
189
|
+
notes: string[];
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* The array a Collection2/CollectionInsert names: the literal `collectionId`, undefined when
|
|
193
|
+
* absent, empty, wired or non-literal. Unlike `storeName` there is no default — an unnamed
|
|
194
|
+
* array is anonymous (per-node in the runtime), which nothing static can share.
|
|
195
|
+
*/
|
|
196
|
+
export declare function collectionNameOf(node: NodeIR, wiredPorts: Set<string>): string | undefined;
|
|
197
|
+
/** EXP-011 §55. `Create New Array` — the node whose `id` output is the only wire an Array Id port takes. */
|
|
198
|
+
export declare const COLLECTION_NEW_TYPE = "CollectionNew";
|
|
199
|
+
/**
|
|
200
|
+
* EXP-011 §55. Where a node's Array Id points: a literal name (a module, the named-array model) or a
|
|
201
|
+
* `Create New Array`'s `id` **by wire** (a handle in the minting component's state — the id is never a
|
|
202
|
+
* string in the emitted app; the wire is the name). One answer for every consumer of an Array Id —
|
|
203
|
+
* `Array`, the three mutators, the repeater feed — so the two models cannot disagree about a wire.
|
|
204
|
+
*/
|
|
205
|
+
export type ArrayTarget = {
|
|
206
|
+
kind: 'named';
|
|
207
|
+
collectionName: string;
|
|
208
|
+
} | {
|
|
209
|
+
kind: 'minted';
|
|
210
|
+
nodeId: string;
|
|
211
|
+
wireKey: string;
|
|
212
|
+
};
|
|
213
|
+
export declare function arrayTargetOf(node: NodeIR, component: ComponentIR): ArrayTarget | {
|
|
214
|
+
defer: string;
|
|
215
|
+
};
|
|
216
|
+
/** One property of a translated insert chain: an authored literal, a wire, or (absent both) omitted. */
|
|
217
|
+
export interface InsertChainProperty {
|
|
218
|
+
key: string;
|
|
219
|
+
wire?: {
|
|
220
|
+
connectionKey: string;
|
|
221
|
+
fromId: string;
|
|
222
|
+
fromProperty: string;
|
|
223
|
+
};
|
|
224
|
+
literal?: string | number | boolean;
|
|
225
|
+
}
|
|
226
|
+
export interface InsertChain {
|
|
227
|
+
/** The named array, or `''` when {@link minted} is set. */
|
|
228
|
+
collectionName: string;
|
|
229
|
+
/** EXP-011 §55. The `Create New Array` whose handle the insert writes — the chain is component-local then. */
|
|
230
|
+
minted?: string;
|
|
231
|
+
insertId: string;
|
|
232
|
+
newModelId: string;
|
|
233
|
+
/** The NewModel's `properties` list in authored order, omitted keys filtered out. */
|
|
234
|
+
properties: InsertChainProperty[];
|
|
235
|
+
/** Connection keys the chain consumes: id→modifyId, done→add, and every property wire. */
|
|
236
|
+
consumes: string[];
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* The `NewModel → CollectionInsert` chain analysis (COLLECTIONS-TARGET §2): one `.add({...})`
|
|
240
|
+
* when (a) the properties are statically sourced, (b) the array id is literal, and (c) the
|
|
241
|
+
* created object's outputs feed exactly this insert. Shared by the registry (key discovery and
|
|
242
|
+
* typing) and the per-component planner (handler compilation) so the two cannot disagree.
|
|
243
|
+
*/
|
|
244
|
+
export declare function insertChainOf(component: ComponentIR, insertNode: NodeIR, nodeById: Map<string, NodeIR>, wiredPorts: Set<string>): {
|
|
245
|
+
chain: InsertChain;
|
|
246
|
+
} | {
|
|
247
|
+
defer: string;
|
|
248
|
+
};
|
|
249
|
+
export interface ChannelPlan {
|
|
250
|
+
/** The authored channel name. */
|
|
251
|
+
name: string;
|
|
252
|
+
/** The identifier `src/events.ts` exports. */
|
|
253
|
+
exportName: string;
|
|
254
|
+
/** `CelebratePayload`, or null when no sender declares payload keys (the `T = void` channel). */
|
|
255
|
+
payloadTypeName: string | null;
|
|
256
|
+
/** Union of every matching sender's payload keys, first-seen order — exactly how the
|
|
257
|
+
* interpreter's receiver discovers its output ports. */
|
|
258
|
+
payload: Array<{
|
|
259
|
+
key: string;
|
|
260
|
+
tsType: 'string' | 'unknown';
|
|
261
|
+
}>;
|
|
262
|
+
senders: ChannelSender[];
|
|
263
|
+
}
|
|
264
|
+
export interface AppStateRegistry {
|
|
265
|
+
/** Keyed by authored name, discovery order over D1-sorted components. */
|
|
266
|
+
variables: Map<string, VariablePlan>;
|
|
267
|
+
channels: Map<string, ChannelPlan>;
|
|
268
|
+
stores: Map<string, StorePlan>;
|
|
269
|
+
collections: Map<string, CollectionPlan>;
|
|
270
|
+
/**
|
|
271
|
+
* EXP-011 §47. Object Ids that are also Global Store names. In the runtime those are two
|
|
272
|
+
* records (`--ndl--global-store--x` and `x`); in the exported app both would be `store('x')`,
|
|
273
|
+
* one registry entry — so the Object side is refused by name rather than merged into the
|
|
274
|
+
* Global Store's module, and the Global Store keeps translating as it did.
|
|
275
|
+
*/
|
|
276
|
+
objectCollisions: Set<string>;
|
|
277
|
+
}
|
|
278
|
+
export declare function collectAppState(ir: ExportIR): AppStateRegistry;
|
|
279
|
+
/** The sender's `payload` stringlist parameter, split — the payload port set, statically. */
|
|
280
|
+
export declare function payloadKeysOf(node: NodeIR): string[];
|
|
281
|
+
export declare function isTextInputType(type: string): boolean;
|
|
282
|
+
/**
|
|
283
|
+
* The store a node names: the literal `storeName`, `'app'` when absent or empty (all three
|
|
284
|
+
* runtime nodes default exactly so, and the history family's three with them), undefined when wired or
|
|
285
|
+
* non-literal — genuinely dynamic.
|
|
286
|
+
*/
|
|
287
|
+
export declare function storeNameOf(node: NodeIR, wiredPorts: Set<string>): string | undefined;
|
|
288
|
+
/** A Subscribe node's authored key list, split as the runtime splits it (blank ⇒ all keys). */
|
|
289
|
+
export declare function subscribeKeysOf(node: NodeIR): string[];
|
|
290
|
+
/**
|
|
291
|
+
* A declarer's initialState, as far as it is statically knowable: a JSON-object parameter, or
|
|
292
|
+
* JSON text that parses to a plain object (object-typed ports arrive as text when the author
|
|
293
|
+
* typed JSON — the runtime's own `coerceState` rule). A wire, a non-object, or unparseable
|
|
294
|
+
* text is 'bad'; the declarer contributes nothing and says so in the notes.
|
|
295
|
+
*/
|
|
296
|
+
export declare function initialStateOf(node: NodeIR, wiredPorts: Set<string>): {
|
|
297
|
+
kind: 'object';
|
|
298
|
+
value: Record<string, unknown>;
|
|
299
|
+
} | {
|
|
300
|
+
kind: 'absent';
|
|
301
|
+
} | {
|
|
302
|
+
kind: 'bad';
|
|
303
|
+
};
|