@ketvietlab/ketjs 0.1.1

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.
Files changed (283) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/dist/agent/capabilities.d.ts +62 -0
  4. package/dist/agent/capabilities.d.ts.map +1 -0
  5. package/dist/agent/capabilities.js +89 -0
  6. package/dist/agent/capabilities.js.map +1 -0
  7. package/dist/agent/permissions.d.ts +56 -0
  8. package/dist/agent/permissions.d.ts.map +1 -0
  9. package/dist/agent/permissions.js +209 -0
  10. package/dist/agent/permissions.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +698 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/codegen/dts.d.ts +3 -0
  16. package/dist/codegen/dts.d.ts.map +1 -0
  17. package/dist/codegen/dts.js +94 -0
  18. package/dist/codegen/dts.js.map +1 -0
  19. package/dist/data/adapter.d.ts +4 -0
  20. package/dist/data/adapter.d.ts.map +1 -0
  21. package/dist/data/adapter.js +18 -0
  22. package/dist/data/adapter.js.map +1 -0
  23. package/dist/data/changeset.d.ts +49 -0
  24. package/dist/data/changeset.d.ts.map +1 -0
  25. package/dist/data/changeset.js +206 -0
  26. package/dist/data/changeset.js.map +1 -0
  27. package/dist/data/expr.d.ts +59 -0
  28. package/dist/data/expr.d.ts.map +1 -0
  29. package/dist/data/expr.js +61 -0
  30. package/dist/data/expr.js.map +1 -0
  31. package/dist/data/fleet.d.ts +28 -0
  32. package/dist/data/fleet.d.ts.map +1 -0
  33. package/dist/data/fleet.js +82 -0
  34. package/dist/data/fleet.js.map +1 -0
  35. package/dist/data/list-search.d.ts +93 -0
  36. package/dist/data/list-search.d.ts.map +1 -0
  37. package/dist/data/list-search.js +268 -0
  38. package/dist/data/list-search.js.map +1 -0
  39. package/dist/data/migrate.d.ts +75 -0
  40. package/dist/data/migrate.d.ts.map +1 -0
  41. package/dist/data/migrate.js +136 -0
  42. package/dist/data/migrate.js.map +1 -0
  43. package/dist/data/pool.d.ts +20 -0
  44. package/dist/data/pool.d.ts.map +1 -0
  45. package/dist/data/pool.js +92 -0
  46. package/dist/data/pool.js.map +1 -0
  47. package/dist/data/query.d.ts +111 -0
  48. package/dist/data/query.d.ts.map +1 -0
  49. package/dist/data/query.js +268 -0
  50. package/dist/data/query.js.map +1 -0
  51. package/dist/data/sqlite.d.ts +3 -0
  52. package/dist/data/sqlite.d.ts.map +1 -0
  53. package/dist/data/sqlite.js +107 -0
  54. package/dist/data/sqlite.js.map +1 -0
  55. package/dist/data/time.d.ts +9 -0
  56. package/dist/data/time.d.ts.map +1 -0
  57. package/dist/data/time.js +107 -0
  58. package/dist/data/time.js.map +1 -0
  59. package/dist/index.d.ts +79 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +51 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/kernel/apps.d.ts +43 -0
  64. package/dist/kernel/apps.d.ts.map +1 -0
  65. package/dist/kernel/apps.js +234 -0
  66. package/dist/kernel/apps.js.map +1 -0
  67. package/dist/kernel/compose.d.ts +6 -0
  68. package/dist/kernel/compose.d.ts.map +1 -0
  69. package/dist/kernel/compose.js +976 -0
  70. package/dist/kernel/compose.js.map +1 -0
  71. package/dist/kernel/define.d.ts +9 -0
  72. package/dist/kernel/define.d.ts.map +1 -0
  73. package/dist/kernel/define.js +140 -0
  74. package/dist/kernel/define.js.map +1 -0
  75. package/dist/kernel/diff.d.ts +11 -0
  76. package/dist/kernel/diff.d.ts.map +1 -0
  77. package/dist/kernel/diff.js +106 -0
  78. package/dist/kernel/diff.js.map +1 -0
  79. package/dist/kernel/errors.d.ts +17 -0
  80. package/dist/kernel/errors.d.ts.map +1 -0
  81. package/dist/kernel/errors.js +43 -0
  82. package/dist/kernel/errors.js.map +1 -0
  83. package/dist/kernel/graph.d.ts +3 -0
  84. package/dist/kernel/graph.d.ts.map +1 -0
  85. package/dist/kernel/graph.js +56 -0
  86. package/dist/kernel/graph.js.map +1 -0
  87. package/dist/kernel/i18n.d.ts +43 -0
  88. package/dist/kernel/i18n.d.ts.map +1 -0
  89. package/dist/kernel/i18n.js +79 -0
  90. package/dist/kernel/i18n.js.map +1 -0
  91. package/dist/kernel/index.d.ts +7 -0
  92. package/dist/kernel/index.d.ts.map +1 -0
  93. package/dist/kernel/index.js +7 -0
  94. package/dist/kernel/index.js.map +1 -0
  95. package/dist/kernel/layout.d.ts +17 -0
  96. package/dist/kernel/layout.d.ts.map +1 -0
  97. package/dist/kernel/layout.js +77 -0
  98. package/dist/kernel/layout.js.map +1 -0
  99. package/dist/kernel/menu.d.ts +27 -0
  100. package/dist/kernel/menu.d.ts.map +1 -0
  101. package/dist/kernel/menu.js +65 -0
  102. package/dist/kernel/menu.js.map +1 -0
  103. package/dist/kernel/modules.d.ts +31 -0
  104. package/dist/kernel/modules.d.ts.map +1 -0
  105. package/dist/kernel/modules.js +322 -0
  106. package/dist/kernel/modules.js.map +1 -0
  107. package/dist/kernel/routes.d.ts +24 -0
  108. package/dist/kernel/routes.d.ts.map +1 -0
  109. package/dist/kernel/routes.js +98 -0
  110. package/dist/kernel/routes.js.map +1 -0
  111. package/dist/kernel/types.d.ts +8 -0
  112. package/dist/kernel/types.d.ts.map +1 -0
  113. package/dist/kernel/types.js +67 -0
  114. package/dist/kernel/types.js.map +1 -0
  115. package/dist/kernel/workspace.d.ts +62 -0
  116. package/dist/kernel/workspace.d.ts.map +1 -0
  117. package/dist/kernel/workspace.js +156 -0
  118. package/dist/kernel/workspace.js.map +1 -0
  119. package/dist/scaffold/index.d.ts +2 -0
  120. package/dist/scaffold/index.d.ts.map +1 -0
  121. package/dist/scaffold/index.js +49 -0
  122. package/dist/scaffold/index.js.map +1 -0
  123. package/dist/scaffold/templates/app.test.ts.tmpl +17 -0
  124. package/dist/scaffold/templates/biome.json.tmpl +30 -0
  125. package/dist/scaffold/templates/dev.mjs.tmpl +16 -0
  126. package/dist/scaffold/templates/gitignore.tmpl +24 -0
  127. package/dist/scaffold/templates/ket.workspace.ts.tmpl +18 -0
  128. package/dist/scaffold/templates/module.ts.tmpl +27 -0
  129. package/dist/scaffold/templates/package.json.tmpl +25 -0
  130. package/dist/scaffold/templates/tsconfig.json.tmpl +15 -0
  131. package/dist/server/boot.d.ts +173 -0
  132. package/dist/server/boot.d.ts.map +1 -0
  133. package/dist/server/boot.js +659 -0
  134. package/dist/server/boot.js.map +1 -0
  135. package/dist/server/config.d.ts +48 -0
  136. package/dist/server/config.d.ts.map +1 -0
  137. package/dist/server/config.js +82 -0
  138. package/dist/server/config.js.map +1 -0
  139. package/dist/server/ctx.d.ts +13 -0
  140. package/dist/server/ctx.d.ts.map +1 -0
  141. package/dist/server/ctx.js +496 -0
  142. package/dist/server/ctx.js.map +1 -0
  143. package/dist/server/fn.d.ts +34 -0
  144. package/dist/server/fn.d.ts.map +1 -0
  145. package/dist/server/fn.js +170 -0
  146. package/dist/server/fn.js.map +1 -0
  147. package/dist/server/http.d.ts +79 -0
  148. package/dist/server/http.d.ts.map +1 -0
  149. package/dist/server/http.js +459 -0
  150. package/dist/server/http.js.map +1 -0
  151. package/dist/server/idem.d.ts +31 -0
  152. package/dist/server/idem.d.ts.map +1 -0
  153. package/dist/server/idem.js +68 -0
  154. package/dist/server/idem.js.map +1 -0
  155. package/dist/server/jobs.d.ts +5 -0
  156. package/dist/server/jobs.d.ts.map +1 -0
  157. package/dist/server/jobs.js +24 -0
  158. package/dist/server/jobs.js.map +1 -0
  159. package/dist/server/multipart.d.ts +18 -0
  160. package/dist/server/multipart.d.ts.map +1 -0
  161. package/dist/server/multipart.js +183 -0
  162. package/dist/server/multipart.js.map +1 -0
  163. package/dist/server/project.d.ts +9 -0
  164. package/dist/server/project.d.ts.map +1 -0
  165. package/dist/server/project.js +67 -0
  166. package/dist/server/project.js.map +1 -0
  167. package/dist/server/queue.d.ts +80 -0
  168. package/dist/server/queue.d.ts.map +1 -0
  169. package/dist/server/queue.js +494 -0
  170. package/dist/server/queue.js.map +1 -0
  171. package/dist/server/respond.d.ts +91 -0
  172. package/dist/server/respond.d.ts.map +1 -0
  173. package/dist/server/respond.js +99 -0
  174. package/dist/server/respond.js.map +1 -0
  175. package/dist/server/runtime.d.ts +14 -0
  176. package/dist/server/runtime.d.ts.map +1 -0
  177. package/dist/server/runtime.js +25 -0
  178. package/dist/server/runtime.js.map +1 -0
  179. package/dist/server/session.d.ts +55 -0
  180. package/dist/server/session.d.ts.map +1 -0
  181. package/dist/server/session.js +172 -0
  182. package/dist/server/session.js.map +1 -0
  183. package/dist/server/sessionstore.d.ts +54 -0
  184. package/dist/server/sessionstore.d.ts.map +1 -0
  185. package/dist/server/sessionstore.js +232 -0
  186. package/dist/server/sessionstore.js.map +1 -0
  187. package/dist/server/storage/index.d.ts +11 -0
  188. package/dist/server/storage/index.d.ts.map +1 -0
  189. package/dist/server/storage/index.js +31 -0
  190. package/dist/server/storage/index.js.map +1 -0
  191. package/dist/server/storage/local.d.ts +5 -0
  192. package/dist/server/storage/local.d.ts.map +1 -0
  193. package/dist/server/storage/local.js +165 -0
  194. package/dist/server/storage/local.js.map +1 -0
  195. package/dist/server/storage/s3.d.ts +11 -0
  196. package/dist/server/storage/s3.d.ts.map +1 -0
  197. package/dist/server/storage/s3.js +133 -0
  198. package/dist/server/storage/s3.js.map +1 -0
  199. package/dist/server/storage/sigv4.d.ts +23 -0
  200. package/dist/server/storage/sigv4.d.ts.map +1 -0
  201. package/dist/server/storage/sigv4.js +79 -0
  202. package/dist/server/storage/sigv4.js.map +1 -0
  203. package/dist/server/storage/types.d.ts +37 -0
  204. package/dist/server/storage/types.d.ts.map +1 -0
  205. package/dist/server/storage/types.js +82 -0
  206. package/dist/server/storage/types.js.map +1 -0
  207. package/dist/server/stream.d.ts +43 -0
  208. package/dist/server/stream.d.ts.map +1 -0
  209. package/dist/server/stream.js +117 -0
  210. package/dist/server/stream.js.map +1 -0
  211. package/dist/server/streamstore.d.ts +29 -0
  212. package/dist/server/streamstore.d.ts.map +1 -0
  213. package/dist/server/streamstore.js +140 -0
  214. package/dist/server/streamstore.js.map +1 -0
  215. package/dist/server/tenants.d.ts +108 -0
  216. package/dist/server/tenants.d.ts.map +1 -0
  217. package/dist/server/tenants.js +172 -0
  218. package/dist/server/tenants.js.map +1 -0
  219. package/dist/server/transport/index.d.ts +5 -0
  220. package/dist/server/transport/index.d.ts.map +1 -0
  221. package/dist/server/transport/index.js +3 -0
  222. package/dist/server/transport/index.js.map +1 -0
  223. package/dist/server/transport/memory.d.ts +14 -0
  224. package/dist/server/transport/memory.d.ts.map +1 -0
  225. package/dist/server/transport/memory.js +36 -0
  226. package/dist/server/transport/memory.js.map +1 -0
  227. package/dist/server/transport/types.d.ts +44 -0
  228. package/dist/server/transport/types.d.ts.map +1 -0
  229. package/dist/server/transport/types.js +79 -0
  230. package/dist/server/transport/types.js.map +1 -0
  231. package/dist/server/worker.d.ts +33 -0
  232. package/dist/server/worker.d.ts.map +1 -0
  233. package/dist/server/worker.js +428 -0
  234. package/dist/server/worker.js.map +1 -0
  235. package/dist/testing.d.ts +146 -0
  236. package/dist/testing.d.ts.map +1 -0
  237. package/dist/testing.js +406 -0
  238. package/dist/testing.js.map +1 -0
  239. package/dist/theme/contracts.d.ts +4 -0
  240. package/dist/theme/contracts.d.ts.map +1 -0
  241. package/dist/theme/contracts.js +87 -0
  242. package/dist/theme/contracts.js.map +1 -0
  243. package/dist/theme/index.d.ts +8 -0
  244. package/dist/theme/index.d.ts.map +1 -0
  245. package/dist/theme/index.js +7 -0
  246. package/dist/theme/index.js.map +1 -0
  247. package/dist/theme/joints.d.ts +19 -0
  248. package/dist/theme/joints.d.ts.map +1 -0
  249. package/dist/theme/joints.js +126 -0
  250. package/dist/theme/joints.js.map +1 -0
  251. package/dist/theme/ktl/compile.d.ts +26 -0
  252. package/dist/theme/ktl/compile.d.ts.map +1 -0
  253. package/dist/theme/ktl/compile.js +226 -0
  254. package/dist/theme/ktl/compile.js.map +1 -0
  255. package/dist/theme/ktl/lexer.d.ts +20 -0
  256. package/dist/theme/ktl/lexer.d.ts.map +1 -0
  257. package/dist/theme/ktl/lexer.js +56 -0
  258. package/dist/theme/ktl/lexer.js.map +1 -0
  259. package/dist/theme/ktl/parser.d.ts +64 -0
  260. package/dist/theme/ktl/parser.d.ts.map +1 -0
  261. package/dist/theme/ktl/parser.js +220 -0
  262. package/dist/theme/ktl/parser.js.map +1 -0
  263. package/dist/theme/render.d.ts +19 -0
  264. package/dist/theme/render.d.ts.map +1 -0
  265. package/dist/theme/render.js +246 -0
  266. package/dist/theme/render.js.map +1 -0
  267. package/dist/theme/templates.d.ts +2 -0
  268. package/dist/theme/templates.d.ts.map +1 -0
  269. package/dist/theme/templates.js +40 -0
  270. package/dist/theme/templates.js.map +1 -0
  271. package/dist/theme/tokens.d.ts +4 -0
  272. package/dist/theme/tokens.d.ts.map +1 -0
  273. package/dist/theme/tokens.js +15 -0
  274. package/dist/theme/tokens.js.map +1 -0
  275. package/dist/theme/viewmodel.d.ts +6 -0
  276. package/dist/theme/viewmodel.d.ts.map +1 -0
  277. package/dist/theme/viewmodel.js +40 -0
  278. package/dist/theme/viewmodel.js.map +1 -0
  279. package/dist/types.d.ts +614 -0
  280. package/dist/types.d.ts.map +1 -0
  281. package/dist/types.js +3 -0
  282. package/dist/types.js.map +1 -0
  283. package/package.json +60 -0
@@ -0,0 +1,220 @@
1
+ import { lex, KtlSyntaxError } from './lexer.js';
2
+ const IDENT = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
3
+ // Property names that could reach the prototype chain are rejected at parse time,
4
+ // so a malicious theme cannot even express the traversal.
5
+ const FORBIDDEN = new Set(['__proto__', 'constructor', 'prototype', '__defineGetter__', '__defineSetter__']);
6
+ export function parseExpr(src, line) {
7
+ const s = src.trim();
8
+ if (s.startsWith('not '))
9
+ return { k: 'not', src: parseExpr(s.slice(4), line) };
10
+ for (const op of ['==', '!=', '>=', '<=', '>', '<']) {
11
+ const at = splitTop(s, op);
12
+ if (at >= 0)
13
+ return {
14
+ k: 'cmp',
15
+ op,
16
+ left: parseExpr(s.slice(0, at), line),
17
+ right: parseExpr(s.slice(at + op.length), line),
18
+ };
19
+ }
20
+ const pipe = splitTop(s, '|');
21
+ if (pipe >= 0) {
22
+ const head = parseExpr(s.slice(0, pipe), line);
23
+ const rest = s.slice(pipe + 1).trim();
24
+ const colon = rest.indexOf(':');
25
+ const name = (colon === -1 ? rest : rest.slice(0, colon)).trim();
26
+ if (!IDENT.test(name))
27
+ throw new KtlSyntaxError(`invalid filter name "${name}" at line ${line}`, line);
28
+ const arg = colon === -1 ? null : parseExpr(rest.slice(colon + 1), line);
29
+ return { k: 'filter', src: head, name, arg };
30
+ }
31
+ if ((s.startsWith("'") && s.endsWith("'")) || (s.startsWith('"') && s.endsWith('"')))
32
+ return { k: 'lit', value: s.slice(1, -1) };
33
+ if (/^-?\d+(\.\d+)?$/.test(s))
34
+ return { k: 'lit', value: Number(s) };
35
+ if (s === 'true')
36
+ return { k: 'lit', value: true };
37
+ if (s === 'false')
38
+ return { k: 'lit', value: false };
39
+ const parts = s.split('.').map((p) => p.trim());
40
+ for (const p of parts) {
41
+ if (!IDENT.test(p))
42
+ throw new KtlSyntaxError(`invalid path segment "${p}" at line ${line}`, line);
43
+ if (FORBIDDEN.has(p))
44
+ throw new KtlSyntaxError(`forbidden property "${p}" at line ${line}`, line);
45
+ }
46
+ return { k: 'path', parts };
47
+ }
48
+ // find an operator that is not inside quotes
49
+ function splitTop(s, op) {
50
+ let q = null;
51
+ for (let i = 0; i < s.length; i++) {
52
+ const c = s[i];
53
+ if (q) {
54
+ if (c === q)
55
+ q = null;
56
+ continue;
57
+ }
58
+ if (c === "'" || c === '"') {
59
+ q = c;
60
+ continue;
61
+ }
62
+ if (s.startsWith(op, i)) {
63
+ if (op === '>' || op === '<') {
64
+ if (s[i + 1] === '=')
65
+ continue;
66
+ }
67
+ if (op === '|' && (s[i + 1] === '|' || s[i - 1] === '|'))
68
+ continue;
69
+ return i;
70
+ }
71
+ }
72
+ return -1;
73
+ }
74
+ // Every top-level part, for an argument list. splitTop finds the first operator;
75
+ // this one keeps going, which is what a comma-separated list needs.
76
+ function splitParts(s, sep) {
77
+ const out = [];
78
+ let q = null;
79
+ let start = 0;
80
+ for (let i = 0; i < s.length; i++) {
81
+ const c = s[i];
82
+ if (q) {
83
+ if (c === q)
84
+ q = null;
85
+ continue;
86
+ }
87
+ if (c === "'" || c === '"') {
88
+ q = c;
89
+ continue;
90
+ }
91
+ if (c === sep) {
92
+ out.push(s.slice(start, i));
93
+ start = i + 1;
94
+ }
95
+ }
96
+ out.push(s.slice(start));
97
+ return out.map((p) => p.trim()).filter(Boolean);
98
+ }
99
+ export function parse(src) {
100
+ const tokens = lex(src);
101
+ let i = 0;
102
+ const parseBlock = (stopAt) => {
103
+ const nodes = [];
104
+ while (i < tokens.length) {
105
+ const t = tokens[i];
106
+ if (t.type === 'text') {
107
+ nodes.push({ k: 'text', value: t.value });
108
+ i++;
109
+ continue;
110
+ }
111
+ if (t.type === 'expr') {
112
+ const raw = t.value.startsWith('raw ');
113
+ nodes.push({ k: 'out', expr: parseExpr(raw ? t.value.slice(4) : t.value, t.line), raw, line: t.line });
114
+ i++;
115
+ continue;
116
+ }
117
+ const words = t.value.split(/\s+/);
118
+ const head = words[0];
119
+ if (stopAt.includes(head))
120
+ return { nodes, stopped: head, line: t.line };
121
+ if (head === 'if') {
122
+ i++;
123
+ const thenPart = parseBlock(['else', 'endif']);
124
+ let elsePart = [];
125
+ if (thenPart.stopped === 'else') {
126
+ i++;
127
+ const e = parseBlock(['endif']);
128
+ elsePart = e.nodes;
129
+ }
130
+ i++;
131
+ nodes.push({
132
+ k: 'if',
133
+ cond: parseExpr(t.value.slice(2), t.line),
134
+ then: thenPart.nodes,
135
+ else: elsePart,
136
+ line: t.line,
137
+ });
138
+ continue;
139
+ }
140
+ if (head === 'for') {
141
+ const m = /^for\s+([a-zA-Z_][a-zA-Z0-9_]*)\s+in\s+(.+)$/.exec(t.value);
142
+ if (!m)
143
+ throw new KtlSyntaxError(`bad for-loop at line ${t.line}: {% ${t.value} %}`, t.line);
144
+ i++;
145
+ const body = parseBlock(['endfor']);
146
+ i++;
147
+ nodes.push({
148
+ k: 'for',
149
+ name: m[1],
150
+ src: parseExpr(m[2], t.line),
151
+ body: body.nodes,
152
+ line: t.line,
153
+ });
154
+ continue;
155
+ }
156
+ if (head === 'joint') {
157
+ const m = /^joint\s+["']([^"']+)["']$/.exec(t.value);
158
+ if (!m)
159
+ throw new KtlSyntaxError(`bad joint tag at line ${t.line}`, t.line);
160
+ nodes.push({ k: 'joint', joint: m[1], line: t.line });
161
+ i++;
162
+ continue;
163
+ }
164
+ // {% render 'card', item: product, compact: true %}
165
+ //
166
+ // The rendered template gets ONLY what is passed, never the caller's scope.
167
+ // Shopify made the same choice and it is the reason a partial there can be
168
+ // read on its own: with inheritance you cannot tell what a template needs
169
+ // without finding every caller. Ket has a stronger reason too — a theme is a
170
+ // stranger's code, and a partial that silently sees the whole page scope is
171
+ // a partial that leaks whatever the page happened to be carrying.
172
+ if (head === 'render') {
173
+ const m = /^render\s+["']([^"']+)["']\s*(?:,\s*(.+))?$/.exec(t.value);
174
+ if (!m)
175
+ throw new KtlSyntaxError(`bad render tag at line ${t.line}: {% ${t.value} %}`, t.line);
176
+ const args = {};
177
+ if (m[2]) {
178
+ for (const pair of splitParts(m[2], ',')) {
179
+ const at = pair.indexOf(':');
180
+ if (at === -1)
181
+ throw new KtlSyntaxError(`render argument needs "name: value" at line ${t.line}`, t.line);
182
+ const key = pair.slice(0, at).trim();
183
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key))
184
+ throw new KtlSyntaxError(`bad render argument "${key}" at line ${t.line}`, t.line);
185
+ args[key] = parseExpr(pair.slice(at + 1).trim(), t.line);
186
+ }
187
+ }
188
+ nodes.push({ k: 'render', template: m[1], args, line: t.line });
189
+ i++;
190
+ continue;
191
+ }
192
+ if (head === 'sections') {
193
+ nodes.push({ k: 'sections', line: t.line });
194
+ i++;
195
+ continue;
196
+ }
197
+ if (head === 'island') {
198
+ const m = /^island\s+["']([^"']+)["']$/.exec(t.value);
199
+ if (!m)
200
+ throw new KtlSyntaxError(`bad island tag at line ${t.line}`, t.line);
201
+ nodes.push({ k: 'island', name: m[1], line: t.line });
202
+ i++;
203
+ continue;
204
+ }
205
+ if (head === 'region') {
206
+ const m = /^region\s+["']([^"']+)["']$/.exec(t.value);
207
+ if (!m)
208
+ throw new KtlSyntaxError(`bad region tag at line ${t.line}`, t.line);
209
+ nodes.push({ k: 'region', name: m[1], line: t.line });
210
+ i++;
211
+ continue;
212
+ }
213
+ throw new KtlSyntaxError(`unknown tag "{% ${t.value} %}" at line ${t.line}`, t.line);
214
+ }
215
+ return { nodes, stopped: '', line: 0 };
216
+ };
217
+ const out = parseBlock([]);
218
+ return out.nodes;
219
+ }
220
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../../../../packages/ketjs/src/theme/ktl/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Compiled, Filter, Scope } from './ktl/compile.ts';
2
+ import type { IslandRegistry } from '@ketvietlab/ketjs-view';
3
+ import type { KetModule, Manifest } from '../types.ts';
4
+ export type ThemeRuntime = {
5
+ renderRegion(name: string, scope: Scope): string;
6
+ templates: Record<string, Compiled>;
7
+ islands: IslandRegistry;
8
+ clients: Record<string, {
9
+ src: string;
10
+ export: string;
11
+ }>;
12
+ };
13
+ export declare function createTheme(manifest: Manifest, modules: KetModule[], opts?: {
14
+ filters?: Record<string, Filter>;
15
+ translate?: (key: string, params?: Record<string, unknown>) => string;
16
+ /** Select one theme when the deployment ships several. Non-theme module templates remain available. */
17
+ theme?: string;
18
+ }): ThemeRuntime;
19
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/theme/render.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEtD,MAAM,MAAM,YAAY,GAAG;IACzB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAAA;IAChD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IACnC,OAAO,EAAE,cAAc,CAAA;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACzD,CAAA;AAED,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,SAAS,EAAE,EACpB,IAAI,GAAE;IACJ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IACrE,uGAAuG;IACvG,KAAK,CAAC,EAAE,MAAM,CAAA;CACV,GACL,YAAY,CA8Od"}
@@ -0,0 +1,246 @@
1
+ // Rendering a page through a theme: templates are KTL, joints are filled by
2
+ // whatever modules published fills for them, and the scope is a sealed set of drops.
3
+ import { compileKtl } from './ktl/compile.js';
4
+ import { renderIsland } from '@ketvietlab/ketjs-view';
5
+ import { sealScope } from './viewmodel.js';
6
+ import { contractProps } from './contracts.js';
7
+ import { KetError } from '../kernel/errors.js';
8
+ export function createTheme(manifest, modules, opts = {}) {
9
+ // A theme is written against what the DEPLOYMENT ships, not against what a
10
+ // particular database has switched on. So the strict check belongs to the full
11
+ // manifest — where a typo is a build error — while a restricted manifest, which
12
+ // is a runtime view, degrades to rendering nothing. Uninstalling an app must not
13
+ // take the whole theme down with it.
14
+ const atRuntime = manifest.disabledModules !== undefined;
15
+ const off = new Set(manifest.disabledModules ?? []);
16
+ const disabledSections = new Set(manifest.disabledSections ?? []);
17
+ // Islands come from modules; the theme only names them.
18
+ const islands = {};
19
+ for (const m of modules) {
20
+ if (off.has(m.name))
21
+ continue;
22
+ for (const [name, def] of Object.entries(m.islands))
23
+ islands[name] = def.view;
24
+ }
25
+ const clients = Object.fromEntries(Object.entries(manifest.islands)
26
+ .filter(([, island]) => island.client !== undefined)
27
+ .map(([name, island]) => [name, island.client]));
28
+ const sources = {};
29
+ for (const m of modules) {
30
+ if (off.has(m.name))
31
+ continue; // a removed theme contributes no templates
32
+ if (m.kind === 'theme' && opts.theme && m.name !== opts.theme)
33
+ continue;
34
+ for (const [name, src] of Object.entries(m.templates))
35
+ sources[name] = src;
36
+ }
37
+ const fillSources = {};
38
+ for (const fill of manifest.fills) {
39
+ const owner = manifest.modules[fill.by];
40
+ if (owner?.kind === 'theme' && opts.theme && fill.by !== opts.theme)
41
+ continue;
42
+ (fillSources[fill.joint] ??= []).push(fill);
43
+ }
44
+ const templates = {};
45
+ const fills = {};
46
+ const jointStack = [];
47
+ const renderJoint = (joint, scope) => {
48
+ const definition = manifest.joints[joint];
49
+ if (!definition) {
50
+ throw new KetError({
51
+ code: 'E_TEMPLATE_UNKNOWN_JOINT',
52
+ message: `renders joint "${joint}", which no installed module publishes`,
53
+ });
54
+ }
55
+ if (definition.omittedBy.length)
56
+ return '';
57
+ if (jointStack.includes(joint)) {
58
+ throw new KetError({
59
+ code: 'E_JOINT_CYCLE',
60
+ message: `joint recursion: ${[...jointStack, joint].join(' -> ')}`,
61
+ hint: 'a fill may render another joint, but never itself through any chain',
62
+ });
63
+ }
64
+ if (jointStack.length >= 16) {
65
+ throw new KetError({ code: 'E_JOINT_TOO_DEEP', message: 'joint rendering exceeds 16 levels' });
66
+ }
67
+ jointStack.push(joint);
68
+ try {
69
+ const props = contractProps(manifest, 'joint', joint, definition.props, scope);
70
+ return (fills[joint] ?? []).map((compiled) => compiled.render(props)).join('');
71
+ }
72
+ finally {
73
+ jointStack.pop();
74
+ }
75
+ };
76
+ /**
77
+ * A page's body is its layout: an ordered list of placements, each rendered by
78
+ * the template named after its section type. The theme decides how a section
79
+ * looks; the data decides which sections there are and in what order.
80
+ */
81
+ const renderSectionsAt = (scope) => {
82
+ const layout = scope['sections'];
83
+ if (!Array.isArray(layout))
84
+ return '';
85
+ const out = [];
86
+ for (const raw of layout) {
87
+ const placement = raw;
88
+ if (!placement?.type)
89
+ continue;
90
+ if (!manifest.sections[placement.type]) {
91
+ // A page saved while an app was installed still names its sections after it
92
+ // is removed. Skip those; re-installing brings them back with their data.
93
+ if (atRuntime && disabledSections.has(placement.type))
94
+ continue;
95
+ if (atRuntime) {
96
+ // Named by no app this deployment has ever shipped: leave a mark rather
97
+ // than pretend the page was always this length.
98
+ out.push(`<!-- ket: unknown section "${placement.type}" -->`);
99
+ continue;
100
+ }
101
+ throw new KetError({
102
+ code: 'E_UNKNOWN_SECTION',
103
+ message: `the page places section "${placement.type}", which no installed module provides`,
104
+ hint: `available sections: ${Object.keys(manifest.sections).join(', ') || '(none)'}`,
105
+ });
106
+ }
107
+ out.push(renderRegion(placement.type, { ...(placement.settings ?? {}), page: scope['page'] }));
108
+ }
109
+ return out.join('');
110
+ };
111
+ const renderIslandAt = (name, scope) => {
112
+ const factory = islands[name];
113
+ const definition = manifest.islands[name];
114
+ if (!factory || !definition) {
115
+ if (atRuntime)
116
+ return '';
117
+ throw new KetError({
118
+ code: 'E_UNKNOWN_ISLAND',
119
+ message: `a template places island "${name}", which no installed module provides`,
120
+ hint: `available islands: ${Object.keys(islands).join(', ') || '(none)'}`,
121
+ });
122
+ }
123
+ return renderIsland(name, factory, contractProps(manifest, 'island', name, definition.props, scope), {
124
+ key: definition.key,
125
+ });
126
+ };
127
+ const renderRegion = (name, scope) => {
128
+ const t = templates[name];
129
+ if (!t) {
130
+ throw new KetError({
131
+ code: 'E_REGION_NOT_RENDERABLE',
132
+ message: `region "${name}" has no template`,
133
+ hint: `available regions: ${Object.keys(templates).join(', ') || '(none)'}`,
134
+ });
135
+ }
136
+ return t.render(sealScope(scope));
137
+ };
138
+ /**
139
+ * {% render %}. The depth cap exists because a template naming itself is a
140
+ * stack overflow, and a stack overflow in a stranger's theme is a 500 with no
141
+ * explanation. The error says which template and where instead.
142
+ */
143
+ const MAX_RENDER_DEPTH = 16;
144
+ let depth = 0;
145
+ const renderTemplate = (name, scope, from) => {
146
+ const t = templates[name];
147
+ if (!t) {
148
+ throw new KetError({
149
+ code: 'E_TEMPLATE_NOT_FOUND',
150
+ message: `${from} renders "${name}", which no installed module provides`,
151
+ hint: `available templates: ${Object.keys(templates).sort().join(', ') || '(none)'}`,
152
+ });
153
+ }
154
+ if (depth >= MAX_RENDER_DEPTH) {
155
+ throw new KetError({
156
+ code: 'E_RENDER_TOO_DEEP',
157
+ message: `${from} renders "${name}" more than ${MAX_RENDER_DEPTH} levels deep`,
158
+ hint: 'a template that renders itself, directly or through another, will not terminate',
159
+ });
160
+ }
161
+ depth++;
162
+ try {
163
+ return t.render(scope);
164
+ }
165
+ finally {
166
+ depth--;
167
+ }
168
+ };
169
+ const wiring = {
170
+ renderJoint,
171
+ renderRegion,
172
+ renderIsland: renderIslandAt,
173
+ renderSections: renderSectionsAt,
174
+ renderTemplate,
175
+ };
176
+ for (const [joint, sourcesForJoint] of Object.entries(fillSources)) {
177
+ fills[joint] = sourcesForJoint.map((fill, i) => {
178
+ const compiled = compileKtl(fill.template, { ...opts, name: `${joint}#${i}`, ...wiring });
179
+ const module = manifest.modules[fill.by];
180
+ for (const used of compiled.jointsUsed) {
181
+ const target = manifest.joints[used];
182
+ if (!target) {
183
+ throw new KetError({
184
+ code: 'E_FILL_UNKNOWN_JOINT',
185
+ module: fill.by,
186
+ message: `fill for "${joint}" renders unknown joint "${used}"`,
187
+ });
188
+ }
189
+ if (target.owner !== fill.by && !module?.depends?.includes(target.owner)) {
190
+ throw new KetError({
191
+ code: 'E_FILL_NOT_DEPENDED',
192
+ module: fill.by,
193
+ message: `fill for "${joint}" renders "${used}" without depending on "${target.owner}"`,
194
+ });
195
+ }
196
+ }
197
+ for (const used of compiled.islandsUsed) {
198
+ const target = manifest.islands[used];
199
+ if (!target) {
200
+ throw new KetError({
201
+ code: 'E_FILL_UNKNOWN_ISLAND',
202
+ module: fill.by,
203
+ message: `fill for "${joint}" places unknown island "${used}"`,
204
+ });
205
+ }
206
+ if (target.by !== fill.by && !module?.depends?.includes(target.by)) {
207
+ throw new KetError({
208
+ code: 'E_FILL_NOT_DEPENDED',
209
+ module: fill.by,
210
+ message: `fill for "${joint}" places "${used}" without depending on "${target.by}"`,
211
+ });
212
+ }
213
+ }
214
+ return compiled;
215
+ });
216
+ }
217
+ for (const [name, src] of Object.entries(sources)) {
218
+ templates[name] = compileKtl(src, { ...opts, name, ...wiring });
219
+ }
220
+ // A theme that points at a joint nobody publishes is a build error, not a blank spot.
221
+ for (const [name, t] of Object.entries(templates)) {
222
+ for (const j of t.jointsUsed) {
223
+ if (!manifest.joints[j]) {
224
+ throw new KetError({
225
+ code: 'E_TEMPLATE_UNKNOWN_JOINT',
226
+ message: `template "${name}" renders joint "${j}", which no installed module publishes`,
227
+ hint: `published joints: ${Object.keys(manifest.joints).join(', ') || '(none)'}`,
228
+ });
229
+ }
230
+ }
231
+ }
232
+ // Placing an island nobody provides is a build error, exactly like a missing joint.
233
+ for (const [name, t] of Object.entries(templates)) {
234
+ for (const island of atRuntime ? [] : t.islandsUsed) {
235
+ if (!manifest.islands[island]) {
236
+ throw new KetError({
237
+ code: 'E_TEMPLATE_UNKNOWN_ISLAND',
238
+ message: `template "${name}" places island "${island}", which no installed module provides`,
239
+ hint: `provided islands: ${Object.keys(manifest.islands).join(', ') || '(none)'}`,
240
+ });
241
+ }
242
+ }
243
+ }
244
+ return { renderRegion, templates, islands, clients };
245
+ }
246
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/theme/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function loadTemplates(dir: URL | string): Record<string, string>;
2
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/theme/templates.ts"],"names":[],"mappings":"AAiBA,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBvE"}
@@ -0,0 +1,40 @@
1
+ // Templates as files.
2
+ //
3
+ // They used to be string literals inside .ts, which cost a theme author every tool
4
+ // they have: no highlighting, no formatter, no way for an error to name a place. It
5
+ // also made the fourth pillar untrue in practice — Shopify and WordPress hand a
6
+ // theme author *files*, and someone who must open TypeScript to change markup is
7
+ // not a theme author any more.
8
+ //
9
+ // The file name is the template name: `website.hero.ktl` provides `website.hero`,
10
+ // which keeps one source of truth and makes an error message locatable without
11
+ // carrying a second map around.
12
+ import { readdirSync, readFileSync } from 'node:fs';
13
+ import { KetError } from '../kernel/errors.js';
14
+ const EXT = '.ktl';
15
+ export function loadTemplates(dir) {
16
+ const base = typeof dir === 'string' ? new URL(`file://${dir}`) : dir;
17
+ let names;
18
+ try {
19
+ names = readdirSync(base).filter((n) => n.endsWith(EXT));
20
+ }
21
+ catch {
22
+ throw new KetError({
23
+ code: 'E_TEMPLATE_DIR_MISSING',
24
+ message: `no template directory at ${base.pathname}`,
25
+ hint: 'loadTemplates takes a directory of .ktl files, usually new URL("./templates/", import.meta.url)',
26
+ });
27
+ }
28
+ if (!names.length) {
29
+ throw new KetError({
30
+ code: 'E_NO_TEMPLATES',
31
+ message: `${base.pathname} contains no ${EXT} files`,
32
+ hint: 'a theme with no templates renders nothing; delete the call or add a template',
33
+ });
34
+ }
35
+ const out = {};
36
+ for (const file of names.sort())
37
+ out[file.slice(0, -EXT.length)] = readFileSync(new URL(file, base), 'utf8');
38
+ return out;
39
+ }
40
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/theme/templates.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,EAAE;AACF,mFAAmF;AACnF,oFAAoF;AACpF,gFAAgF;AAChF,iFAAiF;AACjF,+BAA+B;AAC/B,EAAE;AACF,kFAAkF;AAClF,+EAA+E;AAC/E,gCAAgC;AAEhC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE9C,MAAM,GAAG,GAAG,MAAM,CAAA;AAElB,MAAM,UAAU,aAAa,CAAC,GAAiB;IAC7C,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IACrE,IAAI,KAAe,CAAA;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC;YACjB,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EAAE,4BAA4B,IAAI,CAAC,QAAQ,EAAE;YACpD,IAAI,EAAE,iGAAiG;SACxG,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,QAAQ,CAAC;YACjB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,gBAAgB,GAAG,QAAQ;YACpD,IAAI,EAAE,8EAA8E;SACrF,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,GAAG,GAA2B,EAAE,CAAA;IACtC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE;QAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAA;IAC5G,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const LAYER_ORDER: readonly ['ket.reset', 'ket.theme', 'ket.app', 'ket.user'];
2
+ export declare function tokensToCss(tokens: Record<string, string>, layer?: (typeof LAYER_ORDER)[number]): string;
3
+ export declare function scopedCss(section: string, css: string): string;
4
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/theme/tokens.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW,YAAI,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAU,CAAA;AAErF,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,KAAK,GAAE,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAe,GAChD,MAAM,CAKR;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9D"}
@@ -0,0 +1,15 @@
1
+ // Theme tokens become CSS custom properties inside an explicit cascade layer, so
2
+ // override order is a declared contract rather than a specificity accident:
3
+ // ket.reset < ket.theme < ket.app < ket.user
4
+ // Native CSS only — no preprocessor, no CSS-in-JS, nothing to install.
5
+ export const LAYER_ORDER = ['ket.reset', 'ket.theme', 'ket.app', 'ket.user'];
6
+ export function tokensToCss(tokens, layer = 'ket.theme') {
7
+ const decls = Object.entries(tokens)
8
+ .map(([k, v]) => ` --ket-${k.replace(/[^a-zA-Z0-9-]/g, '-')}: ${v};`)
9
+ .join('\n');
10
+ return `@layer ${LAYER_ORDER.join(', ')};\n\n@layer ${layer} {\n :root {\n${decls}\n }\n}\n`;
11
+ }
12
+ export function scopedCss(section, css) {
13
+ return `@layer ket.theme {\n @scope ([data-ket-section="${section}"]) {\n${css}\n }\n}\n`;
14
+ }
15
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../../../../packages/ketjs/src/theme/tokens.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,4EAA4E;AAC5E,+CAA+C;AAC/C,uEAAuE;AAEvE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAU,CAAA;AAErF,MAAM,UAAU,WAAW,CACzB,MAA8B,EAC9B,KAAK,GAAiC,WAAW;IAEjD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;SACrE,IAAI,CAAC,IAAI,CAAC,CAAA;IACb,OAAO,UAAU,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,KAAK,kBAAkB,KAAK,YAAY,CAAA;AAChG,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,GAAW;IACpD,OAAO,oDAAoD,OAAO,UAAU,GAAG,YAAY,CAAA;AAC7F,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Manifest, Row } from '../types.ts';
2
+ export type Drop = Record<string, unknown>;
3
+ export declare function makeDrop(manifest: Manifest, viewKey: string, row: Row): Drop;
4
+ export declare function makeDrops(manifest: Manifest, viewKey: string, rows: Row[]): Drop[];
5
+ export declare function sealScope(scope: Record<string, unknown>): Record<string, unknown>;
6
+ //# sourceMappingURL=viewmodel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewmodel.d.ts","sourceRoot":"","sources":["../../../../../packages/ketjs/src/theme/viewmodel.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEhD,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAE1C,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAY5E;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,CAElF;AAID,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAajF"}