@anvilkit/contracts 0.1.18
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 +21 -0
- package/dist/ai-section.cjs +18 -0
- package/dist/ai-section.d.cts +244 -0
- package/dist/ai-section.d.cts.map +1 -0
- package/dist/ai-section.d.ts +244 -0
- package/dist/ai-section.d.ts.map +1 -0
- package/dist/ai-section.js +1 -0
- package/dist/ai.cjs +18 -0
- package/dist/ai.d.cts +265 -0
- package/dist/ai.d.cts.map +1 -0
- package/dist/ai.d.ts +265 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +1 -0
- package/dist/assets.cjs +18 -0
- package/dist/assets.d.cts +32 -0
- package/dist/assets.d.cts.map +1 -0
- package/dist/assets.d.ts +32 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +1 -0
- package/dist/export.cjs +18 -0
- package/dist/export.d.cts +240 -0
- package/dist/export.d.cts.map +1 -0
- package/dist/export.d.ts +240 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +1 -0
- package/dist/index.cjs +18 -0
- package/dist/index.d.cts +45 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/ir.cjs +18 -0
- package/dist/ir.d.cts +269 -0
- package/dist/ir.d.cts.map +1 -0
- package/dist/ir.d.ts +269 -0
- package/dist/ir.d.ts.map +1 -0
- package/dist/ir.js +1 -0
- package/dist/page.cjs +18 -0
- package/dist/page.d.cts +197 -0
- package/dist/page.d.cts.map +1 -0
- package/dist/page.d.ts +197 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +1 -0
- package/package.json +71 -0
package/dist/ir.d.cts
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Page Intermediate Representation (IR) — the normalized,
|
|
3
|
+
* serializable shape every Studio export format consumes.
|
|
4
|
+
*
|
|
5
|
+
* ### Why an IR layer at all?
|
|
6
|
+
*
|
|
7
|
+
* Puck's `Data` is authoring-shaped: it carries component ids, UI
|
|
8
|
+
* state, drag-and-drop metadata, and keys that only matter inside the
|
|
9
|
+
* editor. Exporters (HTML, React, JSON, …) shouldn't have to know
|
|
10
|
+
* about any of that. They take a `PageIR` and emit output.
|
|
11
|
+
*
|
|
12
|
+
* The `@anvilkit/ir` package owns `puckDataToIR()`, the
|
|
13
|
+
* transformation from `Data → PageIR`. `@anvilkit/contracts` owns
|
|
14
|
+
* **only the contract** — the types that describe what a valid IR
|
|
15
|
+
* looks like. (Canonical ownership moved here from
|
|
16
|
+
* `@anvilkit/core/types`, which now re-exports these types as a
|
|
17
|
+
* compatibility shim.)
|
|
18
|
+
*
|
|
19
|
+
* ### Design rules
|
|
20
|
+
*
|
|
21
|
+
* 1. **Types only.** This file has zero runtime code. No `const`, no
|
|
22
|
+
* `function`, no `class`. It compiles down to an empty `.js` file
|
|
23
|
+
* under `verbatimModuleSyntax: true`.
|
|
24
|
+
* 2. **Closed unions.** `PageIRAsset.kind` is a fixed union rather
|
|
25
|
+
* than `… | string`, so exporters are forced to handle every case
|
|
26
|
+
* at the type level. Extending the union is a breaking change by
|
|
27
|
+
* design.
|
|
28
|
+
* 3. **Versioned root.** `PageIR.version` is a string literal `"1"`,
|
|
29
|
+
* not a number — `"1" | "2"` avoids floating-point surprises and
|
|
30
|
+
* matches the convention used by most IR versioning schemes.
|
|
31
|
+
* 4. **Frozen for `0.1.x` alpha.** Shape changes require a contracts
|
|
32
|
+
* major bump. The version literal exists so that when a future `"2"`
|
|
33
|
+
* ships, a migration shim can discriminate the two.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link https://github.com/anvilkit/studio/blob/main/docs/tasks/core-006-types-domain.md | core-006}
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* An out-of-band resource referenced by the page — images, videos,
|
|
39
|
+
* fonts, stylesheets, inline scripts, etc.
|
|
40
|
+
*
|
|
41
|
+
* Assets are listed both at the root of {@link PageIR} (so exporters
|
|
42
|
+
* can emit a manifest or preload block in one pass) and, optionally,
|
|
43
|
+
* on individual {@link PageIRNode}s (so a node-scoped exporter can
|
|
44
|
+
* resolve its own dependencies without walking the whole tree).
|
|
45
|
+
*
|
|
46
|
+
* The same asset may appear in both places — exporters are expected
|
|
47
|
+
* to deduplicate by {@link PageIRAsset.id}.
|
|
48
|
+
*/
|
|
49
|
+
export interface PageIRAsset {
|
|
50
|
+
/**
|
|
51
|
+
* Stable, unique identifier for this asset within the IR.
|
|
52
|
+
*
|
|
53
|
+
* Typically a hash of the URL or a caller-provided slug. Exporters
|
|
54
|
+
* use this for deduplication when the same asset is referenced by
|
|
55
|
+
* multiple nodes.
|
|
56
|
+
*/
|
|
57
|
+
readonly id: string;
|
|
58
|
+
/**
|
|
59
|
+
* The asset's category.
|
|
60
|
+
*
|
|
61
|
+
* Closed union — extending this list is a breaking change to the
|
|
62
|
+
* IR contract. Use `"other"` for anything that doesn't fit the
|
|
63
|
+
* named categories rather than introducing an ad-hoc string.
|
|
64
|
+
*/
|
|
65
|
+
readonly kind: "image" | "video" | "font" | "script" | "style" | "other";
|
|
66
|
+
/**
|
|
67
|
+
* Absolute or root-relative URL pointing at the asset.
|
|
68
|
+
*
|
|
69
|
+
* Exporters may rewrite this (e.g. to a CDN or a hashed filename)
|
|
70
|
+
* during serialization — the IR shape does not constrain the
|
|
71
|
+
* scheme.
|
|
72
|
+
*/
|
|
73
|
+
readonly url: string;
|
|
74
|
+
/**
|
|
75
|
+
* Free-form metadata the producer wants to pass through to
|
|
76
|
+
* consumers (e.g. `{ width: 1600, height: 900 }` for an image).
|
|
77
|
+
*
|
|
78
|
+
* Exporters should treat unknown keys as forward-compatible — a
|
|
79
|
+
* missing key must not cause a hard failure.
|
|
80
|
+
*/
|
|
81
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Authoring-time metadata attached to a {@link PageIRNode}.
|
|
85
|
+
*
|
|
86
|
+
* Added in `@anvilkit/ir@0.22` (Phase 6 / M10) as an additive,
|
|
87
|
+
* round-trip-safe extension. Hosts populate these fields opt-in via
|
|
88
|
+
* `migratePageIR` (`@anvilkit/ir/migrations`) or by carrying them
|
|
89
|
+
* forward from a previous edit; `puckDataToIR()` itself MUST NOT
|
|
90
|
+
* synthesize `meta`, so omitting it round-trips losslessly with
|
|
91
|
+
* pre-1.1 documents.
|
|
92
|
+
*
|
|
93
|
+
* Field caps are runtime-enforced contracts (not type-level
|
|
94
|
+
* constraints) — the matching Zod schema lives in
|
|
95
|
+
* `@anvilkit/ir/migrations` and `@anvilkit/validator`'s section
|
|
96
|
+
* checker. Keeping caps off the type surface preserves the
|
|
97
|
+
* "zero runtime code" rule of this file.
|
|
98
|
+
*/
|
|
99
|
+
export interface PageIRNodeMeta {
|
|
100
|
+
/**
|
|
101
|
+
* When `true`, the editor SHOULD treat this node and its subtree
|
|
102
|
+
* as locked: surface a lock indicator and refuse mutating
|
|
103
|
+
* dispatches scoped to the subtree. Authoring concept only —
|
|
104
|
+
* exporters ignore the field.
|
|
105
|
+
*/
|
|
106
|
+
readonly locked?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Opaque host-owned identifier for the author/team that owns
|
|
109
|
+
* this node. Capped at 256 characters at runtime.
|
|
110
|
+
*/
|
|
111
|
+
readonly owner?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Host-versioning string for this node. Runtime contract: must
|
|
114
|
+
* match a semver-shaped regex (`MAJOR.MINOR.PATCH` with optional
|
|
115
|
+
* pre-release / build suffix).
|
|
116
|
+
*/
|
|
117
|
+
readonly version?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Freeform author notes scoped to this node. Capped at 512
|
|
120
|
+
* characters at runtime.
|
|
121
|
+
*/
|
|
122
|
+
readonly notes?: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A single node in the page IR tree.
|
|
126
|
+
*
|
|
127
|
+
* Structurally recursive: every node may carry a `children` array of
|
|
128
|
+
* further nodes, mirroring the component tree the author laid out in
|
|
129
|
+
* the editor. Leaf nodes omit `children` entirely rather than setting
|
|
130
|
+
* it to an empty array (the distinction is not semantically
|
|
131
|
+
* meaningful, but omitting the key keeps serialized IR snapshots
|
|
132
|
+
* smaller).
|
|
133
|
+
*
|
|
134
|
+
* ### `type` vs `id`
|
|
135
|
+
*
|
|
136
|
+
* - {@link id} is a stable per-node identifier, unique within a
|
|
137
|
+
* single {@link PageIR} instance. Used by exporters for
|
|
138
|
+
* key/anchor/href generation.
|
|
139
|
+
* - {@link type} is the component name the node was produced from
|
|
140
|
+
* (e.g. `"Hero"`, `"Button"`). Exporters map this to their own
|
|
141
|
+
* render logic.
|
|
142
|
+
*
|
|
143
|
+
* ### Why `Readonly<Record<string, unknown>>` for props?
|
|
144
|
+
*
|
|
145
|
+
* The IR has no awareness of specific component prop shapes — that's
|
|
146
|
+
* the exporter's job. Keeping props opaque keeps the type surface
|
|
147
|
+
* small and makes `PageIR` JSON-serializable without a discriminator
|
|
148
|
+
* explosion.
|
|
149
|
+
*/
|
|
150
|
+
export interface PageIRNode {
|
|
151
|
+
/**
|
|
152
|
+
* Stable per-node identifier, unique within its owning
|
|
153
|
+
* {@link PageIR}. Typically carried over from Puck's component
|
|
154
|
+
* data id so round-tripping is straightforward.
|
|
155
|
+
*/
|
|
156
|
+
readonly id: string;
|
|
157
|
+
/**
|
|
158
|
+
* The component name this node was produced from
|
|
159
|
+
* (e.g. `"Hero"`, `"Button"`). Exporters dispatch on this value
|
|
160
|
+
* to select a renderer.
|
|
161
|
+
*/
|
|
162
|
+
readonly type: string;
|
|
163
|
+
/**
|
|
164
|
+
* Serialized prop bag for this node.
|
|
165
|
+
*
|
|
166
|
+
* Opaque to the IR — exporters are responsible for interpreting
|
|
167
|
+
* the keys they care about and ignoring the rest.
|
|
168
|
+
*/
|
|
169
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
170
|
+
/**
|
|
171
|
+
* Optional parent slot/zone name this node belongs to.
|
|
172
|
+
*
|
|
173
|
+
* Top-level nodes in the root content omit this field. Nested
|
|
174
|
+
* nodes produced from a Puck slot field carry the slot field key
|
|
175
|
+
* here so `irToPuckData()` can rebuild the correct parent prop.
|
|
176
|
+
*/
|
|
177
|
+
readonly slot?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Distinguishes modern Puck slot fields from legacy `data.zones`
|
|
180
|
+
* entries when {@link slot} is present. Omitted means `"slot"`.
|
|
181
|
+
*/
|
|
182
|
+
readonly slotKind?: "slot" | "zone";
|
|
183
|
+
/**
|
|
184
|
+
* Optional child nodes. Absent on leaf nodes.
|
|
185
|
+
*/
|
|
186
|
+
readonly children?: readonly PageIRNode[];
|
|
187
|
+
/**
|
|
188
|
+
* Optional assets scoped to this node.
|
|
189
|
+
*
|
|
190
|
+
* Duplicates from {@link PageIR.assets} are allowed and expected
|
|
191
|
+
* — exporters deduplicate by {@link PageIRAsset.id}.
|
|
192
|
+
*/
|
|
193
|
+
readonly assets?: readonly PageIRAsset[];
|
|
194
|
+
/**
|
|
195
|
+
* Optional authoring-time metadata. See {@link PageIRNodeMeta}.
|
|
196
|
+
*
|
|
197
|
+
* Additive in `@anvilkit/ir@0.22` (Phase 6 / M10). Round-trip
|
|
198
|
+
* safe: when absent, every Phase 3/5 invariant (e.g. byte-equal
|
|
199
|
+
* `puckDataToIR` output across runs) is preserved. Exporters
|
|
200
|
+
* MUST NOT consume `meta`; it is an authoring contract only.
|
|
201
|
+
*/
|
|
202
|
+
readonly meta?: PageIRNodeMeta;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Page-level metadata — title, description, and timestamps the
|
|
206
|
+
* exporter may surface in `<head>`, a feed, or a manifest.
|
|
207
|
+
*
|
|
208
|
+
* All fields are optional so minimal IR snapshots can be produced
|
|
209
|
+
* without forcing the caller to synthesize values they don't have.
|
|
210
|
+
*
|
|
211
|
+
* Timestamps are ISO 8601 strings (not `Date` instances) so the IR
|
|
212
|
+
* remains JSON-serializable without a custom replacer.
|
|
213
|
+
*/
|
|
214
|
+
export interface PageIRMetadata {
|
|
215
|
+
/**
|
|
216
|
+
* Optional page title (e.g. surfaced in `<title>` and Open Graph).
|
|
217
|
+
*/
|
|
218
|
+
readonly title?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Optional page description (e.g. surfaced in
|
|
221
|
+
* `<meta name="description">`).
|
|
222
|
+
*/
|
|
223
|
+
readonly description?: string;
|
|
224
|
+
/**
|
|
225
|
+
* Optional ISO 8601 timestamp of page creation.
|
|
226
|
+
*/
|
|
227
|
+
readonly createdAt?: string;
|
|
228
|
+
/**
|
|
229
|
+
* Optional ISO 8601 timestamp of most-recent page update.
|
|
230
|
+
*/
|
|
231
|
+
readonly updatedAt?: string;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The root IR document — the single argument passed to every
|
|
235
|
+
* {@link ExportFormatDefinition.run} call.
|
|
236
|
+
*
|
|
237
|
+
* Produced by `@anvilkit/ir`'s `puckDataToIR()`. This package
|
|
238
|
+
* declares the shape; it does not implement the transformation.
|
|
239
|
+
*/
|
|
240
|
+
export interface PageIR {
|
|
241
|
+
/**
|
|
242
|
+
* Schema version of this IR document.
|
|
243
|
+
*
|
|
244
|
+
* Literal `"1"` for the initial contract. A future `"2"` would be
|
|
245
|
+
* a breaking change to IR shape and requires a migration shim in
|
|
246
|
+
* `@anvilkit/ir`. String (not number) to avoid JSON
|
|
247
|
+
* floating-point surprises and to match the convention used by
|
|
248
|
+
* most serialized IR schemas.
|
|
249
|
+
*/
|
|
250
|
+
readonly version: "1";
|
|
251
|
+
/**
|
|
252
|
+
* The root node of the page tree.
|
|
253
|
+
*
|
|
254
|
+
* Exporters walk this recursively to produce output.
|
|
255
|
+
*/
|
|
256
|
+
readonly root: PageIRNode;
|
|
257
|
+
/**
|
|
258
|
+
* Top-level asset manifest. Every asset referenced anywhere in
|
|
259
|
+
* the tree should appear here exactly once; node-scoped
|
|
260
|
+
* {@link PageIRNode.assets} entries are an optimization for
|
|
261
|
+
* exporters that process nodes independently.
|
|
262
|
+
*/
|
|
263
|
+
readonly assets: readonly PageIRAsset[];
|
|
264
|
+
/**
|
|
265
|
+
* Page-level metadata block. See {@link PageIRMetadata}.
|
|
266
|
+
*/
|
|
267
|
+
readonly metadata: PageIRMetadata;
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=ir.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.cts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;IACzE;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,UAAU;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,MAAM;IACtB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CAClC"}
|
package/dist/ir.d.ts
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Page Intermediate Representation (IR) — the normalized,
|
|
3
|
+
* serializable shape every Studio export format consumes.
|
|
4
|
+
*
|
|
5
|
+
* ### Why an IR layer at all?
|
|
6
|
+
*
|
|
7
|
+
* Puck's `Data` is authoring-shaped: it carries component ids, UI
|
|
8
|
+
* state, drag-and-drop metadata, and keys that only matter inside the
|
|
9
|
+
* editor. Exporters (HTML, React, JSON, …) shouldn't have to know
|
|
10
|
+
* about any of that. They take a `PageIR` and emit output.
|
|
11
|
+
*
|
|
12
|
+
* The `@anvilkit/ir` package owns `puckDataToIR()`, the
|
|
13
|
+
* transformation from `Data → PageIR`. `@anvilkit/contracts` owns
|
|
14
|
+
* **only the contract** — the types that describe what a valid IR
|
|
15
|
+
* looks like. (Canonical ownership moved here from
|
|
16
|
+
* `@anvilkit/core/types`, which now re-exports these types as a
|
|
17
|
+
* compatibility shim.)
|
|
18
|
+
*
|
|
19
|
+
* ### Design rules
|
|
20
|
+
*
|
|
21
|
+
* 1. **Types only.** This file has zero runtime code. No `const`, no
|
|
22
|
+
* `function`, no `class`. It compiles down to an empty `.js` file
|
|
23
|
+
* under `verbatimModuleSyntax: true`.
|
|
24
|
+
* 2. **Closed unions.** `PageIRAsset.kind` is a fixed union rather
|
|
25
|
+
* than `… | string`, so exporters are forced to handle every case
|
|
26
|
+
* at the type level. Extending the union is a breaking change by
|
|
27
|
+
* design.
|
|
28
|
+
* 3. **Versioned root.** `PageIR.version` is a string literal `"1"`,
|
|
29
|
+
* not a number — `"1" | "2"` avoids floating-point surprises and
|
|
30
|
+
* matches the convention used by most IR versioning schemes.
|
|
31
|
+
* 4. **Frozen for `0.1.x` alpha.** Shape changes require a contracts
|
|
32
|
+
* major bump. The version literal exists so that when a future `"2"`
|
|
33
|
+
* ships, a migration shim can discriminate the two.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link https://github.com/anvilkit/studio/blob/main/docs/tasks/core-006-types-domain.md | core-006}
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* An out-of-band resource referenced by the page — images, videos,
|
|
39
|
+
* fonts, stylesheets, inline scripts, etc.
|
|
40
|
+
*
|
|
41
|
+
* Assets are listed both at the root of {@link PageIR} (so exporters
|
|
42
|
+
* can emit a manifest or preload block in one pass) and, optionally,
|
|
43
|
+
* on individual {@link PageIRNode}s (so a node-scoped exporter can
|
|
44
|
+
* resolve its own dependencies without walking the whole tree).
|
|
45
|
+
*
|
|
46
|
+
* The same asset may appear in both places — exporters are expected
|
|
47
|
+
* to deduplicate by {@link PageIRAsset.id}.
|
|
48
|
+
*/
|
|
49
|
+
export interface PageIRAsset {
|
|
50
|
+
/**
|
|
51
|
+
* Stable, unique identifier for this asset within the IR.
|
|
52
|
+
*
|
|
53
|
+
* Typically a hash of the URL or a caller-provided slug. Exporters
|
|
54
|
+
* use this for deduplication when the same asset is referenced by
|
|
55
|
+
* multiple nodes.
|
|
56
|
+
*/
|
|
57
|
+
readonly id: string;
|
|
58
|
+
/**
|
|
59
|
+
* The asset's category.
|
|
60
|
+
*
|
|
61
|
+
* Closed union — extending this list is a breaking change to the
|
|
62
|
+
* IR contract. Use `"other"` for anything that doesn't fit the
|
|
63
|
+
* named categories rather than introducing an ad-hoc string.
|
|
64
|
+
*/
|
|
65
|
+
readonly kind: "image" | "video" | "font" | "script" | "style" | "other";
|
|
66
|
+
/**
|
|
67
|
+
* Absolute or root-relative URL pointing at the asset.
|
|
68
|
+
*
|
|
69
|
+
* Exporters may rewrite this (e.g. to a CDN or a hashed filename)
|
|
70
|
+
* during serialization — the IR shape does not constrain the
|
|
71
|
+
* scheme.
|
|
72
|
+
*/
|
|
73
|
+
readonly url: string;
|
|
74
|
+
/**
|
|
75
|
+
* Free-form metadata the producer wants to pass through to
|
|
76
|
+
* consumers (e.g. `{ width: 1600, height: 900 }` for an image).
|
|
77
|
+
*
|
|
78
|
+
* Exporters should treat unknown keys as forward-compatible — a
|
|
79
|
+
* missing key must not cause a hard failure.
|
|
80
|
+
*/
|
|
81
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Authoring-time metadata attached to a {@link PageIRNode}.
|
|
85
|
+
*
|
|
86
|
+
* Added in `@anvilkit/ir@0.22` (Phase 6 / M10) as an additive,
|
|
87
|
+
* round-trip-safe extension. Hosts populate these fields opt-in via
|
|
88
|
+
* `migratePageIR` (`@anvilkit/ir/migrations`) or by carrying them
|
|
89
|
+
* forward from a previous edit; `puckDataToIR()` itself MUST NOT
|
|
90
|
+
* synthesize `meta`, so omitting it round-trips losslessly with
|
|
91
|
+
* pre-1.1 documents.
|
|
92
|
+
*
|
|
93
|
+
* Field caps are runtime-enforced contracts (not type-level
|
|
94
|
+
* constraints) — the matching Zod schema lives in
|
|
95
|
+
* `@anvilkit/ir/migrations` and `@anvilkit/validator`'s section
|
|
96
|
+
* checker. Keeping caps off the type surface preserves the
|
|
97
|
+
* "zero runtime code" rule of this file.
|
|
98
|
+
*/
|
|
99
|
+
export interface PageIRNodeMeta {
|
|
100
|
+
/**
|
|
101
|
+
* When `true`, the editor SHOULD treat this node and its subtree
|
|
102
|
+
* as locked: surface a lock indicator and refuse mutating
|
|
103
|
+
* dispatches scoped to the subtree. Authoring concept only —
|
|
104
|
+
* exporters ignore the field.
|
|
105
|
+
*/
|
|
106
|
+
readonly locked?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Opaque host-owned identifier for the author/team that owns
|
|
109
|
+
* this node. Capped at 256 characters at runtime.
|
|
110
|
+
*/
|
|
111
|
+
readonly owner?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Host-versioning string for this node. Runtime contract: must
|
|
114
|
+
* match a semver-shaped regex (`MAJOR.MINOR.PATCH` with optional
|
|
115
|
+
* pre-release / build suffix).
|
|
116
|
+
*/
|
|
117
|
+
readonly version?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Freeform author notes scoped to this node. Capped at 512
|
|
120
|
+
* characters at runtime.
|
|
121
|
+
*/
|
|
122
|
+
readonly notes?: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A single node in the page IR tree.
|
|
126
|
+
*
|
|
127
|
+
* Structurally recursive: every node may carry a `children` array of
|
|
128
|
+
* further nodes, mirroring the component tree the author laid out in
|
|
129
|
+
* the editor. Leaf nodes omit `children` entirely rather than setting
|
|
130
|
+
* it to an empty array (the distinction is not semantically
|
|
131
|
+
* meaningful, but omitting the key keeps serialized IR snapshots
|
|
132
|
+
* smaller).
|
|
133
|
+
*
|
|
134
|
+
* ### `type` vs `id`
|
|
135
|
+
*
|
|
136
|
+
* - {@link id} is a stable per-node identifier, unique within a
|
|
137
|
+
* single {@link PageIR} instance. Used by exporters for
|
|
138
|
+
* key/anchor/href generation.
|
|
139
|
+
* - {@link type} is the component name the node was produced from
|
|
140
|
+
* (e.g. `"Hero"`, `"Button"`). Exporters map this to their own
|
|
141
|
+
* render logic.
|
|
142
|
+
*
|
|
143
|
+
* ### Why `Readonly<Record<string, unknown>>` for props?
|
|
144
|
+
*
|
|
145
|
+
* The IR has no awareness of specific component prop shapes — that's
|
|
146
|
+
* the exporter's job. Keeping props opaque keeps the type surface
|
|
147
|
+
* small and makes `PageIR` JSON-serializable without a discriminator
|
|
148
|
+
* explosion.
|
|
149
|
+
*/
|
|
150
|
+
export interface PageIRNode {
|
|
151
|
+
/**
|
|
152
|
+
* Stable per-node identifier, unique within its owning
|
|
153
|
+
* {@link PageIR}. Typically carried over from Puck's component
|
|
154
|
+
* data id so round-tripping is straightforward.
|
|
155
|
+
*/
|
|
156
|
+
readonly id: string;
|
|
157
|
+
/**
|
|
158
|
+
* The component name this node was produced from
|
|
159
|
+
* (e.g. `"Hero"`, `"Button"`). Exporters dispatch on this value
|
|
160
|
+
* to select a renderer.
|
|
161
|
+
*/
|
|
162
|
+
readonly type: string;
|
|
163
|
+
/**
|
|
164
|
+
* Serialized prop bag for this node.
|
|
165
|
+
*
|
|
166
|
+
* Opaque to the IR — exporters are responsible for interpreting
|
|
167
|
+
* the keys they care about and ignoring the rest.
|
|
168
|
+
*/
|
|
169
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
170
|
+
/**
|
|
171
|
+
* Optional parent slot/zone name this node belongs to.
|
|
172
|
+
*
|
|
173
|
+
* Top-level nodes in the root content omit this field. Nested
|
|
174
|
+
* nodes produced from a Puck slot field carry the slot field key
|
|
175
|
+
* here so `irToPuckData()` can rebuild the correct parent prop.
|
|
176
|
+
*/
|
|
177
|
+
readonly slot?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Distinguishes modern Puck slot fields from legacy `data.zones`
|
|
180
|
+
* entries when {@link slot} is present. Omitted means `"slot"`.
|
|
181
|
+
*/
|
|
182
|
+
readonly slotKind?: "slot" | "zone";
|
|
183
|
+
/**
|
|
184
|
+
* Optional child nodes. Absent on leaf nodes.
|
|
185
|
+
*/
|
|
186
|
+
readonly children?: readonly PageIRNode[];
|
|
187
|
+
/**
|
|
188
|
+
* Optional assets scoped to this node.
|
|
189
|
+
*
|
|
190
|
+
* Duplicates from {@link PageIR.assets} are allowed and expected
|
|
191
|
+
* — exporters deduplicate by {@link PageIRAsset.id}.
|
|
192
|
+
*/
|
|
193
|
+
readonly assets?: readonly PageIRAsset[];
|
|
194
|
+
/**
|
|
195
|
+
* Optional authoring-time metadata. See {@link PageIRNodeMeta}.
|
|
196
|
+
*
|
|
197
|
+
* Additive in `@anvilkit/ir@0.22` (Phase 6 / M10). Round-trip
|
|
198
|
+
* safe: when absent, every Phase 3/5 invariant (e.g. byte-equal
|
|
199
|
+
* `puckDataToIR` output across runs) is preserved. Exporters
|
|
200
|
+
* MUST NOT consume `meta`; it is an authoring contract only.
|
|
201
|
+
*/
|
|
202
|
+
readonly meta?: PageIRNodeMeta;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Page-level metadata — title, description, and timestamps the
|
|
206
|
+
* exporter may surface in `<head>`, a feed, or a manifest.
|
|
207
|
+
*
|
|
208
|
+
* All fields are optional so minimal IR snapshots can be produced
|
|
209
|
+
* without forcing the caller to synthesize values they don't have.
|
|
210
|
+
*
|
|
211
|
+
* Timestamps are ISO 8601 strings (not `Date` instances) so the IR
|
|
212
|
+
* remains JSON-serializable without a custom replacer.
|
|
213
|
+
*/
|
|
214
|
+
export interface PageIRMetadata {
|
|
215
|
+
/**
|
|
216
|
+
* Optional page title (e.g. surfaced in `<title>` and Open Graph).
|
|
217
|
+
*/
|
|
218
|
+
readonly title?: string;
|
|
219
|
+
/**
|
|
220
|
+
* Optional page description (e.g. surfaced in
|
|
221
|
+
* `<meta name="description">`).
|
|
222
|
+
*/
|
|
223
|
+
readonly description?: string;
|
|
224
|
+
/**
|
|
225
|
+
* Optional ISO 8601 timestamp of page creation.
|
|
226
|
+
*/
|
|
227
|
+
readonly createdAt?: string;
|
|
228
|
+
/**
|
|
229
|
+
* Optional ISO 8601 timestamp of most-recent page update.
|
|
230
|
+
*/
|
|
231
|
+
readonly updatedAt?: string;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* The root IR document — the single argument passed to every
|
|
235
|
+
* {@link ExportFormatDefinition.run} call.
|
|
236
|
+
*
|
|
237
|
+
* Produced by `@anvilkit/ir`'s `puckDataToIR()`. This package
|
|
238
|
+
* declares the shape; it does not implement the transformation.
|
|
239
|
+
*/
|
|
240
|
+
export interface PageIR {
|
|
241
|
+
/**
|
|
242
|
+
* Schema version of this IR document.
|
|
243
|
+
*
|
|
244
|
+
* Literal `"1"` for the initial contract. A future `"2"` would be
|
|
245
|
+
* a breaking change to IR shape and requires a migration shim in
|
|
246
|
+
* `@anvilkit/ir`. String (not number) to avoid JSON
|
|
247
|
+
* floating-point surprises and to match the convention used by
|
|
248
|
+
* most serialized IR schemas.
|
|
249
|
+
*/
|
|
250
|
+
readonly version: "1";
|
|
251
|
+
/**
|
|
252
|
+
* The root node of the page tree.
|
|
253
|
+
*
|
|
254
|
+
* Exporters walk this recursively to produce output.
|
|
255
|
+
*/
|
|
256
|
+
readonly root: PageIRNode;
|
|
257
|
+
/**
|
|
258
|
+
* Top-level asset manifest. Every asset referenced anywhere in
|
|
259
|
+
* the tree should appear here exactly once; node-scoped
|
|
260
|
+
* {@link PageIRNode.assets} entries are an optimization for
|
|
261
|
+
* exporters that process nodes independently.
|
|
262
|
+
*/
|
|
263
|
+
readonly assets: readonly PageIRAsset[];
|
|
264
|
+
/**
|
|
265
|
+
* Page-level metadata block. See {@link PageIRMetadata}.
|
|
266
|
+
*/
|
|
267
|
+
readonly metadata: PageIRMetadata;
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=ir.d.ts.map
|
package/dist/ir.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;IACzE;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,UAAU;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC1C;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,MAAM;IACtB;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;IACxC;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CAClC"}
|
package/dist/ir.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/page.cjs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.r = (exports1)=>{
|
|
5
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
6
|
+
value: 'Module'
|
|
7
|
+
});
|
|
8
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
9
|
+
value: true
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
})();
|
|
13
|
+
var __webpack_exports__ = {};
|
|
14
|
+
__webpack_require__.r(__webpack_exports__);
|
|
15
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
16
|
+
Object.defineProperty(exports, '__esModule', {
|
|
17
|
+
value: true
|
|
18
|
+
});
|