@syncropel/projections 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.
@@ -0,0 +1,315 @@
1
+ /**
2
+ * Inline markdown subset parser for SRP text-valued props.
3
+ *
4
+ * Parses the five canonical inline constructs supported in SRP text:
5
+ *
6
+ * **bold** → { kind: "bold", children: [...] }
7
+ * *italic* → { kind: "italic", children: [...] }
8
+ * `code` → { kind: "code", text: "..." }
9
+ * [label](url) → { kind: "link", url: "...", children: [...] }
10
+ * ~~strike~~ → { kind: "strike", children: [...] }
11
+ *
12
+ * Other markdown (headings, lists, blockquotes, tables, images, raw HTML)
13
+ * is NOT parsed — structural formatting uses block-level SRP nodes.
14
+ *
15
+ * This parser is runtime-agnostic — it returns an AST that a React
16
+ * renderer (or any other renderer) can walk and emit typography atoms.
17
+ */
18
+ // ---------------------------------------------------------------------------
19
+ // Public API
20
+ // ---------------------------------------------------------------------------
21
+ /**
22
+ * Parse a text string into an array of inline nodes.
23
+ *
24
+ * The subset is deliberately narrow. Unknown or unbalanced delimiters
25
+ * render as literal text (no silent drops).
26
+ */
27
+ export function parseInline(text) {
28
+ return new Parser(text).parseAll();
29
+ }
30
+ /**
31
+ * Reduce an AST back to a plain-text string (formatting stripped).
32
+ * Useful for aria-label derivation, plain-text search, and logs.
33
+ */
34
+ export function stripFormatting(nodes) {
35
+ return nodes
36
+ .map((n) => {
37
+ switch (n.kind) {
38
+ case "text":
39
+ return n.text;
40
+ case "code":
41
+ return n.text;
42
+ case "bold":
43
+ case "italic":
44
+ case "strike":
45
+ case "link":
46
+ return stripFormatting(n.children);
47
+ }
48
+ })
49
+ .join("");
50
+ }
51
+ // ---------------------------------------------------------------------------
52
+ // Parser implementation
53
+ // ---------------------------------------------------------------------------
54
+ class Parser {
55
+ src;
56
+ pos = 0;
57
+ constructor(src) {
58
+ this.src = src;
59
+ }
60
+ parseAll() {
61
+ return this.parseUntil(null);
62
+ }
63
+ /**
64
+ * Parse inline content until `stop` (a delimiter string), or end of input.
65
+ * When `stop === null`, parse to end of input.
66
+ *
67
+ * Returns the parsed nodes plus advances `this.pos` past the closing
68
+ * delimiter (or to end of input).
69
+ */
70
+ parseUntil(stop) {
71
+ const out = [];
72
+ let buf = "";
73
+ const flush = () => {
74
+ if (buf.length > 0) {
75
+ out.push({ kind: "text", text: buf });
76
+ buf = "";
77
+ }
78
+ };
79
+ while (this.pos < this.src.length) {
80
+ // Stop delimiter check
81
+ if (stop !== null && this.startsWith(stop)) {
82
+ flush();
83
+ this.pos += stop.length;
84
+ return out;
85
+ }
86
+ const ch = this.src[this.pos];
87
+ // Backslash escape — next char is literal
88
+ if (ch === "\\" && this.pos + 1 < this.src.length) {
89
+ buf += this.src[this.pos + 1];
90
+ this.pos += 2;
91
+ continue;
92
+ }
93
+ // **bold**
94
+ if (this.startsWith("**")) {
95
+ const saved = this.pos;
96
+ this.pos += 2;
97
+ const children = this.tryParseUntil("**");
98
+ if (children !== null) {
99
+ flush();
100
+ out.push({ kind: "bold", children });
101
+ continue;
102
+ }
103
+ this.pos = saved;
104
+ }
105
+ // ~~strike~~
106
+ if (this.startsWith("~~")) {
107
+ const saved = this.pos;
108
+ this.pos += 2;
109
+ const children = this.tryParseUntil("~~");
110
+ if (children !== null) {
111
+ flush();
112
+ out.push({ kind: "strike", children });
113
+ continue;
114
+ }
115
+ this.pos = saved;
116
+ }
117
+ // *italic*
118
+ if (ch === "*" && !this.startsWith("**")) {
119
+ const saved = this.pos;
120
+ this.pos += 1;
121
+ const children = this.tryParseUntil("*");
122
+ if (children !== null) {
123
+ flush();
124
+ out.push({ kind: "italic", children });
125
+ continue;
126
+ }
127
+ this.pos = saved;
128
+ }
129
+ // `code`
130
+ if (ch === "`") {
131
+ const saved = this.pos;
132
+ this.pos += 1;
133
+ const end = this.src.indexOf("`", this.pos);
134
+ if (end !== -1) {
135
+ flush();
136
+ out.push({ kind: "code", text: this.src.slice(this.pos, end) });
137
+ this.pos = end + 1;
138
+ continue;
139
+ }
140
+ this.pos = saved;
141
+ }
142
+ // [label](url)
143
+ if (ch === "[") {
144
+ const saved = this.pos;
145
+ this.pos += 1;
146
+ const labelEnd = this.findClosingBracket();
147
+ if (labelEnd !== -1 &&
148
+ labelEnd + 1 < this.src.length &&
149
+ this.src[labelEnd + 1] === "(") {
150
+ const urlStart = labelEnd + 2;
151
+ const urlEnd = this.src.indexOf(")", urlStart);
152
+ if (urlEnd !== -1) {
153
+ const labelText = this.src.slice(this.pos, labelEnd);
154
+ const url = this.src.slice(urlStart, urlEnd);
155
+ const labelChildren = parseInline(labelText);
156
+ flush();
157
+ out.push({ kind: "link", url, children: labelChildren });
158
+ this.pos = urlEnd + 1;
159
+ continue;
160
+ }
161
+ }
162
+ this.pos = saved;
163
+ }
164
+ // Literal character
165
+ buf += ch;
166
+ this.pos += 1;
167
+ }
168
+ flush();
169
+ return out;
170
+ }
171
+ /**
172
+ * Try to parse until `stop`; if the closing delimiter isn't found, back
173
+ * up and return null so the caller can treat the opening delimiter as
174
+ * literal text.
175
+ */
176
+ tryParseUntil(stop) {
177
+ const saved = this.pos;
178
+ const result = [];
179
+ let buf = "";
180
+ const flush = () => {
181
+ if (buf.length > 0) {
182
+ result.push({ kind: "text", text: buf });
183
+ buf = "";
184
+ }
185
+ };
186
+ while (this.pos < this.src.length) {
187
+ if (this.startsWith(stop)) {
188
+ flush();
189
+ this.pos += stop.length;
190
+ return result;
191
+ }
192
+ // Recurse for nested constructs
193
+ const ch = this.src[this.pos];
194
+ if (ch === "\\" && this.pos + 1 < this.src.length) {
195
+ buf += this.src[this.pos + 1];
196
+ this.pos += 2;
197
+ continue;
198
+ }
199
+ // Nested parsers — reuse main parser's recognition for any
200
+ // construct that can legally nest (bold in link labels, link
201
+ // in bold, etc.)
202
+ if (this.startsWith("**") && stop !== "**" ||
203
+ this.startsWith("~~") && stop !== "~~" ||
204
+ (ch === "*" && stop !== "*" && !this.startsWith("**")) ||
205
+ (ch === "`" && stop !== "`") ||
206
+ (ch === "[" && stop !== "]")) {
207
+ const priorPos = this.pos;
208
+ const nested = this.parseOneConstruct();
209
+ if (nested !== null) {
210
+ flush();
211
+ result.push(nested);
212
+ continue;
213
+ }
214
+ // parseOneConstruct backed up on failure; fall through
215
+ this.pos = priorPos;
216
+ }
217
+ buf += ch;
218
+ this.pos += 1;
219
+ }
220
+ // End of input without finding `stop` — parse failed
221
+ this.pos = saved;
222
+ return null;
223
+ }
224
+ /**
225
+ * Parse one construct starting at this.pos, return the node or null.
226
+ * Used by nested parsers inside tryParseUntil.
227
+ */
228
+ parseOneConstruct() {
229
+ const ch = this.src[this.pos];
230
+ if (this.startsWith("**")) {
231
+ const saved = this.pos;
232
+ this.pos += 2;
233
+ const children = this.tryParseUntil("**");
234
+ if (children !== null)
235
+ return { kind: "bold", children };
236
+ this.pos = saved;
237
+ return null;
238
+ }
239
+ if (this.startsWith("~~")) {
240
+ const saved = this.pos;
241
+ this.pos += 2;
242
+ const children = this.tryParseUntil("~~");
243
+ if (children !== null)
244
+ return { kind: "strike", children };
245
+ this.pos = saved;
246
+ return null;
247
+ }
248
+ if (ch === "*") {
249
+ const saved = this.pos;
250
+ this.pos += 1;
251
+ const children = this.tryParseUntil("*");
252
+ if (children !== null)
253
+ return { kind: "italic", children };
254
+ this.pos = saved;
255
+ return null;
256
+ }
257
+ if (ch === "`") {
258
+ const saved = this.pos;
259
+ this.pos += 1;
260
+ const end = this.src.indexOf("`", this.pos);
261
+ if (end !== -1) {
262
+ const text = this.src.slice(this.pos, end);
263
+ this.pos = end + 1;
264
+ return { kind: "code", text };
265
+ }
266
+ this.pos = saved;
267
+ return null;
268
+ }
269
+ if (ch === "[") {
270
+ const saved = this.pos;
271
+ this.pos += 1;
272
+ const labelEnd = this.findClosingBracket();
273
+ if (labelEnd !== -1 &&
274
+ labelEnd + 1 < this.src.length &&
275
+ this.src[labelEnd + 1] === "(") {
276
+ const urlStart = labelEnd + 2;
277
+ const urlEnd = this.src.indexOf(")", urlStart);
278
+ if (urlEnd !== -1) {
279
+ const labelText = this.src.slice(this.pos, labelEnd);
280
+ const url = this.src.slice(urlStart, urlEnd);
281
+ const labelChildren = parseInline(labelText);
282
+ this.pos = urlEnd + 1;
283
+ return { kind: "link", url, children: labelChildren };
284
+ }
285
+ }
286
+ this.pos = saved;
287
+ return null;
288
+ }
289
+ return null;
290
+ }
291
+ startsWith(s) {
292
+ return this.src.startsWith(s, this.pos);
293
+ }
294
+ findClosingBracket() {
295
+ let depth = 1;
296
+ let i = this.pos;
297
+ while (i < this.src.length) {
298
+ const c = this.src[i];
299
+ if (c === "\\" && i + 1 < this.src.length) {
300
+ i += 2;
301
+ continue;
302
+ }
303
+ if (c === "[")
304
+ depth++;
305
+ if (c === "]") {
306
+ depth--;
307
+ if (depth === 0)
308
+ return i;
309
+ }
310
+ i++;
311
+ }
312
+ return -1;
313
+ }
314
+ }
315
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Inline markdown subset parser for SRP text-valued props.\n *\n * Parses the five canonical inline constructs supported in SRP text:\n *\n * **bold** → { kind: \"bold\", children: [...] }\n * *italic* → { kind: \"italic\", children: [...] }\n * `code` → { kind: \"code\", text: \"...\" }\n * [label](url) → { kind: \"link\", url: \"...\", children: [...] }\n * ~~strike~~ → { kind: \"strike\", children: [...] }\n *\n * Other markdown (headings, lists, blockquotes, tables, images, raw HTML)\n * is NOT parsed — structural formatting uses block-level SRP nodes.\n *\n * This parser is runtime-agnostic — it returns an AST that a React\n * renderer (or any other renderer) can walk and emit typography atoms.\n */\n\n// ---------------------------------------------------------------------------\n// AST\n// ---------------------------------------------------------------------------\n\nexport type InlineNode =\n | { kind: \"text\"; text: string }\n | { kind: \"bold\"; children: InlineNode[] }\n | { kind: \"italic\"; children: InlineNode[] }\n | { kind: \"code\"; text: string }\n | { kind: \"link\"; url: string; children: InlineNode[] }\n | { kind: \"strike\"; children: InlineNode[] };\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a text string into an array of inline nodes.\n *\n * The subset is deliberately narrow. Unknown or unbalanced delimiters\n * render as literal text (no silent drops).\n */\nexport function parseInline(text: string): InlineNode[] {\n return new Parser(text).parseAll();\n}\n\n/**\n * Reduce an AST back to a plain-text string (formatting stripped).\n * Useful for aria-label derivation, plain-text search, and logs.\n */\nexport function stripFormatting(nodes: InlineNode[]): string {\n return nodes\n .map((n) => {\n switch (n.kind) {\n case \"text\":\n return n.text;\n case \"code\":\n return n.text;\n case \"bold\":\n case \"italic\":\n case \"strike\":\n case \"link\":\n return stripFormatting(n.children);\n }\n })\n .join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Parser implementation\n// ---------------------------------------------------------------------------\n\nclass Parser {\n private readonly src: string;\n private pos = 0;\n\n constructor(src: string) {\n this.src = src;\n }\n\n parseAll(): InlineNode[] {\n return this.parseUntil(null);\n }\n\n /**\n * Parse inline content until `stop` (a delimiter string), or end of input.\n * When `stop === null`, parse to end of input.\n *\n * Returns the parsed nodes plus advances `this.pos` past the closing\n * delimiter (or to end of input).\n */\n private parseUntil(stop: string | null): InlineNode[] {\n const out: InlineNode[] = [];\n let buf = \"\";\n\n const flush = () => {\n if (buf.length > 0) {\n out.push({ kind: \"text\", text: buf });\n buf = \"\";\n }\n };\n\n while (this.pos < this.src.length) {\n // Stop delimiter check\n if (stop !== null && this.startsWith(stop)) {\n flush();\n this.pos += stop.length;\n return out;\n }\n\n const ch = this.src[this.pos]!;\n\n // Backslash escape — next char is literal\n if (ch === \"\\\\\" && this.pos + 1 < this.src.length) {\n buf += this.src[this.pos + 1];\n this.pos += 2;\n continue;\n }\n\n // **bold**\n if (this.startsWith(\"**\")) {\n const saved = this.pos;\n this.pos += 2;\n const children = this.tryParseUntil(\"**\");\n if (children !== null) {\n flush();\n out.push({ kind: \"bold\", children });\n continue;\n }\n this.pos = saved;\n }\n\n // ~~strike~~\n if (this.startsWith(\"~~\")) {\n const saved = this.pos;\n this.pos += 2;\n const children = this.tryParseUntil(\"~~\");\n if (children !== null) {\n flush();\n out.push({ kind: \"strike\", children });\n continue;\n }\n this.pos = saved;\n }\n\n // *italic*\n if (ch === \"*\" && !this.startsWith(\"**\")) {\n const saved = this.pos;\n this.pos += 1;\n const children = this.tryParseUntil(\"*\");\n if (children !== null) {\n flush();\n out.push({ kind: \"italic\", children });\n continue;\n }\n this.pos = saved;\n }\n\n // `code`\n if (ch === \"`\") {\n const saved = this.pos;\n this.pos += 1;\n const end = this.src.indexOf(\"`\", this.pos);\n if (end !== -1) {\n flush();\n out.push({ kind: \"code\", text: this.src.slice(this.pos, end) });\n this.pos = end + 1;\n continue;\n }\n this.pos = saved;\n }\n\n // [label](url)\n if (ch === \"[\") {\n const saved = this.pos;\n this.pos += 1;\n const labelEnd = this.findClosingBracket();\n if (\n labelEnd !== -1 &&\n labelEnd + 1 < this.src.length &&\n this.src[labelEnd + 1] === \"(\"\n ) {\n const urlStart = labelEnd + 2;\n const urlEnd = this.src.indexOf(\")\", urlStart);\n if (urlEnd !== -1) {\n const labelText = this.src.slice(this.pos, labelEnd);\n const url = this.src.slice(urlStart, urlEnd);\n const labelChildren = parseInline(labelText);\n flush();\n out.push({ kind: \"link\", url, children: labelChildren });\n this.pos = urlEnd + 1;\n continue;\n }\n }\n this.pos = saved;\n }\n\n // Literal character\n buf += ch;\n this.pos += 1;\n }\n\n flush();\n return out;\n }\n\n /**\n * Try to parse until `stop`; if the closing delimiter isn't found, back\n * up and return null so the caller can treat the opening delimiter as\n * literal text.\n */\n private tryParseUntil(stop: string): InlineNode[] | null {\n const saved = this.pos;\n const result: InlineNode[] = [];\n let buf = \"\";\n\n const flush = () => {\n if (buf.length > 0) {\n result.push({ kind: \"text\", text: buf });\n buf = \"\";\n }\n };\n\n while (this.pos < this.src.length) {\n if (this.startsWith(stop)) {\n flush();\n this.pos += stop.length;\n return result;\n }\n\n // Recurse for nested constructs\n const ch = this.src[this.pos]!;\n\n if (ch === \"\\\\\" && this.pos + 1 < this.src.length) {\n buf += this.src[this.pos + 1];\n this.pos += 2;\n continue;\n }\n\n // Nested parsers — reuse main parser's recognition for any\n // construct that can legally nest (bold in link labels, link\n // in bold, etc.)\n if (\n this.startsWith(\"**\") && stop !== \"**\" ||\n this.startsWith(\"~~\") && stop !== \"~~\" ||\n (ch === \"*\" && stop !== \"*\" && !this.startsWith(\"**\")) ||\n (ch === \"`\" && stop !== \"`\") ||\n (ch === \"[\" && stop !== \"]\")\n ) {\n const priorPos = this.pos;\n const nested = this.parseOneConstruct();\n if (nested !== null) {\n flush();\n result.push(nested);\n continue;\n }\n // parseOneConstruct backed up on failure; fall through\n this.pos = priorPos;\n }\n\n buf += ch;\n this.pos += 1;\n }\n\n // End of input without finding `stop` — parse failed\n this.pos = saved;\n return null;\n }\n\n /**\n * Parse one construct starting at this.pos, return the node or null.\n * Used by nested parsers inside tryParseUntil.\n */\n private parseOneConstruct(): InlineNode | null {\n const ch = this.src[this.pos];\n\n if (this.startsWith(\"**\")) {\n const saved = this.pos;\n this.pos += 2;\n const children = this.tryParseUntil(\"**\");\n if (children !== null) return { kind: \"bold\", children };\n this.pos = saved;\n return null;\n }\n\n if (this.startsWith(\"~~\")) {\n const saved = this.pos;\n this.pos += 2;\n const children = this.tryParseUntil(\"~~\");\n if (children !== null) return { kind: \"strike\", children };\n this.pos = saved;\n return null;\n }\n\n if (ch === \"*\") {\n const saved = this.pos;\n this.pos += 1;\n const children = this.tryParseUntil(\"*\");\n if (children !== null) return { kind: \"italic\", children };\n this.pos = saved;\n return null;\n }\n\n if (ch === \"`\") {\n const saved = this.pos;\n this.pos += 1;\n const end = this.src.indexOf(\"`\", this.pos);\n if (end !== -1) {\n const text = this.src.slice(this.pos, end);\n this.pos = end + 1;\n return { kind: \"code\", text };\n }\n this.pos = saved;\n return null;\n }\n\n if (ch === \"[\") {\n const saved = this.pos;\n this.pos += 1;\n const labelEnd = this.findClosingBracket();\n if (\n labelEnd !== -1 &&\n labelEnd + 1 < this.src.length &&\n this.src[labelEnd + 1] === \"(\"\n ) {\n const urlStart = labelEnd + 2;\n const urlEnd = this.src.indexOf(\")\", urlStart);\n if (urlEnd !== -1) {\n const labelText = this.src.slice(this.pos, labelEnd);\n const url = this.src.slice(urlStart, urlEnd);\n const labelChildren = parseInline(labelText);\n this.pos = urlEnd + 1;\n return { kind: \"link\", url, children: labelChildren };\n }\n }\n this.pos = saved;\n return null;\n }\n\n return null;\n }\n\n private startsWith(s: string): boolean {\n return this.src.startsWith(s, this.pos);\n }\n\n private findClosingBracket(): number {\n let depth = 1;\n let i = this.pos;\n while (i < this.src.length) {\n const c = this.src[i];\n if (c === \"\\\\\" && i + 1 < this.src.length) {\n i += 2;\n continue;\n }\n if (c === \"[\") depth++;\n if (c === \"]\") {\n depth--;\n if (depth === 0) return i;\n }\n i++;\n }\n return -1;\n }\n}\n"]}
@@ -0,0 +1,258 @@
1
+ /**
2
+ * SRP v0.1 — TypeScript schema types.
3
+ *
4
+ * The Syncropel Rendering Protocol is a narrow JSON schema of block-level
5
+ * primitives for declarative UI documents. See the spec and examples at
6
+ * https://syncropel.com.
7
+ */
8
+ /**
9
+ * An SRP v0.1 document — the top-level envelope a Tier-1 extension emits.
10
+ */
11
+ export interface SRPDocument {
12
+ srp: "0.1";
13
+ meta?: SRPMeta;
14
+ root: SRPNode;
15
+ }
16
+ export interface SRPMeta {
17
+ name?: string;
18
+ version?: string;
19
+ description?: string;
20
+ publisher?: string;
21
+ }
22
+ export type SRPNode = ColumnNode | RowNode | GridNode | CardNode | DividerNode | RecordLineNode | RecordLineListNode | ChipNode | HeadingNode | TextNode | StatNode | KeyValueNode | ButtonNode | IconButtonNode | CopyButtonNode | SelectNode | EmptyStateNode | ErrorStateNode | SkeletonNode;
23
+ /**
24
+ * The 19 canonical node-type discriminator strings.
25
+ */
26
+ export declare const NODE_TYPES: readonly ["column", "row", "grid", "card", "divider", "record-line", "record-line-list", "chip", "heading", "text", "stat", "key-value", "button", "icon-button", "copy-button", "select", "empty-state", "error-state", "skeleton"];
27
+ export type NodeType = (typeof NODE_TYPES)[number];
28
+ interface NodeBase {
29
+ when?: string;
30
+ bind?: Record<string, unknown>;
31
+ actions?: Record<string, ActionDesc>;
32
+ }
33
+ export type Gap = "none" | "xs" | "sm" | "md" | "lg" | "xl";
34
+ export type Padding = "none" | "xs" | "sm" | "md" | "lg";
35
+ export type DividerSpacing = "none" | "xs" | "sm" | "md" | "lg";
36
+ export type Cols = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
37
+ export type ColumnAlign = "start" | "center" | "end" | "stretch";
38
+ export type RowAlign = "start" | "center" | "end" | "stretch" | "baseline";
39
+ export type Justify = "start" | "center" | "end" | "between" | "around" | "evenly";
40
+ export type RecordLineVariant = "feed" | "compact" | "detail" | "search" | "thread";
41
+ export type ChipTone = "default" | "info" | "warn" | "error";
42
+ export type TextSize = "xs" | "sm" | "md" | "lg";
43
+ export type TextWeight = "normal" | "medium" | "semibold";
44
+ export type TextTone = "primary" | "secondary" | "muted" | "success" | "warning" | "danger";
45
+ export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger";
46
+ export type ButtonSize = "xs" | "sm" | "md";
47
+ export type SkeletonShape = "rect" | "circle" | "text";
48
+ /**
49
+ * Glyph kinds — the closed enumeration of semantic symbols the palette renders.
50
+ * Covers act types, domain objects, thread states, and the AITL marker.
51
+ */
52
+ export type GlyphKind = "INTEND" | "DO" | "KNOW" | "LEARN" | "GET" | "PUT" | "CALL" | "MAP" | "AITL" | "thread" | "fork" | "record-parent" | "namespace" | "actor" | "file" | "pattern" | "page" | "view" | "state-open" | "state-active" | "state-converged" | "state-closed" | "state-abandoned";
53
+ export interface ActionDesc {
54
+ intent: string;
55
+ payload?: Record<string, unknown>;
56
+ }
57
+ /**
58
+ * VQL (Value Query Language) — the query shape a Syncropel server resolves
59
+ * against its record store. Used by `record-line-list` nodes that bind to
60
+ * a live query rather than a static list of record ids.
61
+ *
62
+ * The shape is deliberately open (index signature) — additional fields
63
+ * are protocol extensions the server understands.
64
+ */
65
+ export interface VQLQuery {
66
+ act?: string;
67
+ actor?: string;
68
+ thread?: string;
69
+ kind?: string;
70
+ since?: number;
71
+ limit?: number;
72
+ [k: string]: unknown;
73
+ }
74
+ export interface ColumnNode extends NodeBase {
75
+ type: "column";
76
+ props?: {
77
+ gap?: Gap;
78
+ align?: ColumnAlign;
79
+ justify?: Justify;
80
+ };
81
+ children?: SRPNode[];
82
+ }
83
+ export interface RowNode extends NodeBase {
84
+ type: "row";
85
+ props?: {
86
+ gap?: Gap;
87
+ align?: RowAlign;
88
+ justify?: Justify;
89
+ wrap?: boolean;
90
+ };
91
+ children?: SRPNode[];
92
+ }
93
+ export interface GridNode extends NodeBase {
94
+ type: "grid";
95
+ props: {
96
+ cols: Cols;
97
+ gap?: Gap;
98
+ rowGap?: Gap;
99
+ colGap?: Gap;
100
+ };
101
+ children?: SRPNode[];
102
+ }
103
+ export interface CardNode extends NodeBase {
104
+ type: "card";
105
+ props?: {
106
+ padding?: Padding;
107
+ interactive?: boolean;
108
+ };
109
+ children?: SRPNode[];
110
+ }
111
+ export interface DividerNode extends NodeBase {
112
+ type: "divider";
113
+ props?: {
114
+ orientation?: "horizontal" | "vertical";
115
+ spacing?: DividerSpacing;
116
+ };
117
+ }
118
+ export interface RecordLineNode extends NodeBase {
119
+ type: "record-line";
120
+ props: {
121
+ variant: RecordLineVariant;
122
+ };
123
+ bind: {
124
+ record: string;
125
+ };
126
+ }
127
+ export interface RecordLineListNode extends NodeBase {
128
+ type: "record-line-list";
129
+ props: {
130
+ variant: RecordLineVariant;
131
+ max?: number;
132
+ empty?: string;
133
+ };
134
+ bind: {
135
+ query: VQLQuery;
136
+ } | {
137
+ items: string[];
138
+ };
139
+ }
140
+ export interface ChipNode extends NodeBase {
141
+ type: "chip";
142
+ props: {
143
+ label: string;
144
+ tone?: ChipTone;
145
+ glyph?: GlyphKind;
146
+ };
147
+ }
148
+ export interface HeadingNode extends NodeBase {
149
+ type: "heading";
150
+ props: {
151
+ level: 1 | 2 | 3 | 4 | 5 | 6;
152
+ text: string;
153
+ };
154
+ }
155
+ export interface TextNode extends NodeBase {
156
+ type: "text";
157
+ props: {
158
+ text: string;
159
+ size?: TextSize;
160
+ weight?: TextWeight;
161
+ tone?: TextTone;
162
+ inline?: boolean;
163
+ };
164
+ }
165
+ export interface StatNode extends NodeBase {
166
+ type: "stat";
167
+ props: {
168
+ label: string;
169
+ value: string | number;
170
+ delta?: string | number;
171
+ deltaTone?: "auto" | "neutral";
172
+ };
173
+ }
174
+ export interface KeyValueNode extends NodeBase {
175
+ type: "key-value";
176
+ props: {
177
+ label: string;
178
+ value: string;
179
+ };
180
+ }
181
+ export interface ButtonNode extends NodeBase {
182
+ type: "button";
183
+ props: {
184
+ label: string;
185
+ variant?: ButtonVariant;
186
+ size?: ButtonSize;
187
+ disabled?: boolean;
188
+ loading?: boolean;
189
+ };
190
+ actions?: {
191
+ onClick?: ActionDesc;
192
+ };
193
+ }
194
+ export interface IconButtonNode extends NodeBase {
195
+ type: "icon-button";
196
+ props: {
197
+ glyph: GlyphKind;
198
+ ariaLabel: string;
199
+ variant?: ButtonVariant;
200
+ size?: ButtonSize;
201
+ disabled?: boolean;
202
+ loading?: boolean;
203
+ };
204
+ actions?: {
205
+ onClick?: ActionDesc;
206
+ };
207
+ }
208
+ export interface CopyButtonNode extends NodeBase {
209
+ type: "copy-button";
210
+ props: {
211
+ value: string;
212
+ label?: string;
213
+ };
214
+ }
215
+ export interface SelectNode extends NodeBase {
216
+ type: "select";
217
+ props: {
218
+ options: {
219
+ label: string;
220
+ value: string;
221
+ }[];
222
+ };
223
+ bind: {
224
+ value: string;
225
+ };
226
+ actions?: {
227
+ onChange?: ActionDesc;
228
+ };
229
+ }
230
+ export interface EmptyStateNode extends NodeBase {
231
+ type: "empty-state";
232
+ props: {
233
+ message: string;
234
+ action?: {
235
+ label: string;
236
+ intent: string;
237
+ };
238
+ };
239
+ }
240
+ export interface ErrorStateNode extends NodeBase {
241
+ type: "error-state";
242
+ props: {
243
+ message: string;
244
+ retry?: {
245
+ intent: string;
246
+ };
247
+ };
248
+ }
249
+ export interface SkeletonNode extends NodeBase {
250
+ type: "skeleton";
251
+ props?: {
252
+ shape?: SkeletonShape;
253
+ width?: string | number | "full";
254
+ height?: string | number;
255
+ };
256
+ }
257
+ export {};
258
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * SRP v0.1 — TypeScript schema types.
3
+ *
4
+ * The Syncropel Rendering Protocol is a narrow JSON schema of block-level
5
+ * primitives for declarative UI documents. See the spec and examples at
6
+ * https://syncropel.com.
7
+ */
8
+ /**
9
+ * The 19 canonical node-type discriminator strings.
10
+ */
11
+ export const NODE_TYPES = [
12
+ "column",
13
+ "row",
14
+ "grid",
15
+ "card",
16
+ "divider",
17
+ "record-line",
18
+ "record-line-list",
19
+ "chip",
20
+ "heading",
21
+ "text",
22
+ "stat",
23
+ "key-value",
24
+ "button",
25
+ "icon-button",
26
+ "copy-button",
27
+ "select",
28
+ "empty-state",
29
+ "error-state",
30
+ "skeleton",
31
+ ];
32
+ //# sourceMappingURL=schema.js.map