@mesofact/runtime 0.8.29

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 (77) hide show
  1. package/README.md +19 -0
  2. package/dist/adapters/r2.d.ts +24 -0
  3. package/dist/adapters/r2.d.ts.map +1 -0
  4. package/dist/adapters/r2.js +136 -0
  5. package/dist/adapters/r2.js.map +1 -0
  6. package/dist/adapters/sqlite.d.ts +25 -0
  7. package/dist/adapters/sqlite.d.ts.map +1 -0
  8. package/dist/adapters/sqlite.js +131 -0
  9. package/dist/adapters/sqlite.js.map +1 -0
  10. package/dist/config.d.ts +29 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +139 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/contract.d.ts +40 -0
  15. package/dist/contract.d.ts.map +1 -0
  16. package/dist/contract.js +5 -0
  17. package/dist/contract.js.map +1 -0
  18. package/dist/errors.d.ts +29 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +40 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/head.d.ts +32 -0
  23. package/dist/head.d.ts.map +1 -0
  24. package/dist/head.js +93 -0
  25. package/dist/head.js.map +1 -0
  26. package/dist/health.d.ts +14 -0
  27. package/dist/health.d.ts.map +1 -0
  28. package/dist/health.js +85 -0
  29. package/dist/health.js.map +1 -0
  30. package/dist/hooks.d.ts +28 -0
  31. package/dist/hooks.d.ts.map +1 -0
  32. package/dist/hooks.js +64 -0
  33. package/dist/hooks.js.map +1 -0
  34. package/dist/hydration.d.ts +6 -0
  35. package/dist/hydration.d.ts.map +1 -0
  36. package/dist/hydration.js +68 -0
  37. package/dist/hydration.js.map +1 -0
  38. package/dist/index.d.ts +26 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +16 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/manifest.d.ts +68 -0
  43. package/dist/manifest.d.ts.map +1 -0
  44. package/dist/manifest.js +9 -0
  45. package/dist/manifest.js.map +1 -0
  46. package/dist/routes.d.ts +67 -0
  47. package/dist/routes.d.ts.map +1 -0
  48. package/dist/routes.js +130 -0
  49. package/dist/routes.js.map +1 -0
  50. package/dist/source.d.ts +36 -0
  51. package/dist/source.d.ts.map +1 -0
  52. package/dist/source.js +52 -0
  53. package/dist/source.js.map +1 -0
  54. package/dist/track-ctx.d.ts +13 -0
  55. package/dist/track-ctx.d.ts.map +1 -0
  56. package/dist/track-ctx.js +15 -0
  57. package/dist/track-ctx.js.map +1 -0
  58. package/dist/validate.d.ts +20 -0
  59. package/dist/validate.d.ts.map +1 -0
  60. package/dist/validate.js +333 -0
  61. package/dist/validate.js.map +1 -0
  62. package/package.json +40 -0
  63. package/src/adapters/r2.ts +163 -0
  64. package/src/adapters/sqlite.ts +182 -0
  65. package/src/config.ts +213 -0
  66. package/src/contract.ts +82 -0
  67. package/src/errors.ts +52 -0
  68. package/src/head.ts +130 -0
  69. package/src/health.ts +99 -0
  70. package/src/hooks.ts +72 -0
  71. package/src/hydration.ts +72 -0
  72. package/src/index.ts +113 -0
  73. package/src/manifest.ts +104 -0
  74. package/src/routes.ts +320 -0
  75. package/src/source.ts +91 -0
  76. package/src/track-ctx.ts +29 -0
  77. package/src/validate.ts +388 -0
@@ -0,0 +1,333 @@
1
+ // Manifest validator — structural shape + semantic rules. Used by the build
2
+ // (fail before bad HTML hits R2) and mirrored in `crates/mesofact/src/validate.rs`
3
+ // for the proxy. Shared fixtures live at `tests/fixtures/manifests/`.
4
+ //
5
+ // Semantic rules:
6
+ // R1. Mode 1 (static) + `source_reads` referencing a non-`global` source
7
+ // is rejected. Mode 1 builds can't enumerate per-user/per-project keys.
8
+ // R2. Mode 1 + `requires` containing "user" is rejected. The build can't
9
+ // know who the user is.
10
+ //
11
+ // See `.yah/docs/architecture/mesofact.md` §"Render axis × source axis".
12
+ import { MANIFEST_VERSION } from "./manifest.js";
13
+ import { HOOK_NAMES, isHookName } from "./hooks.js";
14
+ const MODES = new Set(["static", "ssr", "spa"]);
15
+ const REQUIRES = new Set(["user", "project", "region"]);
16
+ const RESOLVED_PLACEMENTS = new Set(["host", "edge"]);
17
+ function isObject(x) {
18
+ return typeof x === "object" && x !== null && !Array.isArray(x);
19
+ }
20
+ function shape(path, message) {
21
+ return { kind: "shape", path, message };
22
+ }
23
+ function checkRoute(idx, raw, errs) {
24
+ const base = `routes[${idx}]`;
25
+ if (!isObject(raw)) {
26
+ errs.push(shape(base, "expected object"));
27
+ return null;
28
+ }
29
+ const out = {};
30
+ if (typeof raw.route !== "string")
31
+ errs.push(shape(`${base}.route`, "expected string"));
32
+ else
33
+ out.route = raw.route;
34
+ if (typeof raw.mode !== "string" || !MODES.has(raw.mode)) {
35
+ errs.push(shape(`${base}.mode`, "expected 'static' | 'ssr' | 'spa'"));
36
+ }
37
+ else {
38
+ out.mode = raw.mode;
39
+ }
40
+ if (typeof raw.render_entrypoint !== "string") {
41
+ errs.push(shape(`${base}.render_entrypoint`, "expected string"));
42
+ }
43
+ else {
44
+ out.render_entrypoint = raw.render_entrypoint;
45
+ }
46
+ if (raw.requires !== undefined) {
47
+ if (!Array.isArray(raw.requires) || raw.requires.some((r) => typeof r !== "string" || !REQUIRES.has(r))) {
48
+ errs.push(shape(`${base}.requires`, "expected ('user' | 'project' | 'region')[]"));
49
+ }
50
+ else {
51
+ out.requires = raw.requires;
52
+ }
53
+ }
54
+ if (raw.source_reads !== undefined) {
55
+ if (!Array.isArray(raw.source_reads) || raw.source_reads.some((s) => typeof s !== "string")) {
56
+ errs.push(shape(`${base}.source_reads`, "expected string[]"));
57
+ }
58
+ else {
59
+ out.source_reads = raw.source_reads;
60
+ }
61
+ }
62
+ if (raw.data_inputs !== undefined) {
63
+ if (!Array.isArray(raw.data_inputs) || raw.data_inputs.some((s) => typeof s !== "string")) {
64
+ errs.push(shape(`${base}.data_inputs`, "expected string[]"));
65
+ }
66
+ else {
67
+ out.data_inputs = raw.data_inputs;
68
+ }
69
+ }
70
+ if (!isObject(raw.cache_policy) || typeof raw.cache_policy.ttl !== "number") {
71
+ errs.push(shape(`${base}.cache_policy`, "expected { ttl: number, ... }"));
72
+ }
73
+ else {
74
+ out.cache_policy = raw.cache_policy;
75
+ }
76
+ if (raw.concurrency !== undefined) {
77
+ if (typeof raw.concurrency !== "number") {
78
+ errs.push(shape(`${base}.concurrency`, "expected number"));
79
+ }
80
+ else {
81
+ out.concurrency = raw.concurrency;
82
+ }
83
+ }
84
+ if (raw.hydration !== undefined) {
85
+ const h = raw.hydration;
86
+ if (!isObject(h) || typeof h.script !== "string" || !Array.isArray(h.code_split)) {
87
+ errs.push(shape(`${base}.hydration`, "expected { script: string, code_split: string[] }"));
88
+ }
89
+ else {
90
+ out.hydration = h;
91
+ }
92
+ }
93
+ if (raw.prerender !== undefined) {
94
+ if (!isObject(raw.prerender)) {
95
+ errs.push(shape(`${base}.prerender`, "expected object"));
96
+ }
97
+ else {
98
+ out.prerender = raw.prerender;
99
+ }
100
+ }
101
+ if (raw.placement !== undefined) {
102
+ if (typeof raw.placement !== "string" || !RESOLVED_PLACEMENTS.has(raw.placement)) {
103
+ // The build resolves `"auto"` to a concrete value before emission, so
104
+ // the manifest only ever carries `"host"` or `"edge"`.
105
+ errs.push(shape(`${base}.placement`, "expected 'host' | 'edge'"));
106
+ }
107
+ else if (out.mode !== undefined && out.mode !== "ssr") {
108
+ errs.push(shape(`${base}.placement`, "placement is only valid on mode:'ssr'"));
109
+ }
110
+ else {
111
+ out.placement = raw.placement;
112
+ }
113
+ }
114
+ if (raw.resilience !== undefined) {
115
+ const res = checkResilience(base, raw.resilience, out.mode, errs);
116
+ if (res)
117
+ out.resilience = res;
118
+ }
119
+ if (errs.length && errs.some((e) => e.path.startsWith(base)))
120
+ return null;
121
+ return out;
122
+ }
123
+ const RETRY_ON_VALUES = new Set(["connection", "5xx", "any"]);
124
+ // Structural check for the W181 resilience block as carried in the manifest.
125
+ // `defineRoutes` already enforced the semantic rules (ssr-only, queue
126
+ // reserved, backoff length); this pass keeps a hand-written manifest honest
127
+ // and — like data_inputs before it (R014) — prevents the field from being
128
+ // silently stripped when the validator rebuilds the route object.
129
+ function checkResilience(base, raw, mode, errs) {
130
+ const path = `${base}.resilience`;
131
+ if (!isObject(raw)) {
132
+ errs.push(shape(path, "expected object"));
133
+ return null;
134
+ }
135
+ if (mode !== undefined && mode !== "ssr") {
136
+ errs.push(shape(path, "resilience is only valid on mode:'ssr'"));
137
+ return null;
138
+ }
139
+ if (raw.queue !== undefined) {
140
+ errs.push(shape(`${path}.queue`, "queue policy is reserved for v2 (W181) and must not be emitted"));
141
+ return null;
142
+ }
143
+ if (raw.timeout_ms !== undefined && typeof raw.timeout_ms !== "number") {
144
+ errs.push(shape(`${path}.timeout_ms`, "expected number"));
145
+ return null;
146
+ }
147
+ if (raw.retry !== undefined) {
148
+ const retry = raw.retry;
149
+ if (!isObject(retry) ||
150
+ typeof retry.attempts !== "number" ||
151
+ !Array.isArray(retry.backoff_ms) ||
152
+ retry.backoff_ms.some((b) => typeof b !== "number") ||
153
+ retry.backoff_ms.length !== retry.attempts - 1) {
154
+ errs.push(shape(`${path}.retry`, "expected { attempts: number, backoff_ms: number[attempts - 1], ... }"));
155
+ return null;
156
+ }
157
+ if (retry.retry_on !== undefined && (typeof retry.retry_on !== "string" || !RETRY_ON_VALUES.has(retry.retry_on))) {
158
+ errs.push(shape(`${path}.retry.retry_on`, "expected 'connection' | '5xx' | 'any'"));
159
+ return null;
160
+ }
161
+ if (retry.budget_ms !== undefined && typeof retry.budget_ms !== "number") {
162
+ errs.push(shape(`${path}.retry.budget_ms`, "expected number"));
163
+ return null;
164
+ }
165
+ }
166
+ return raw;
167
+ }
168
+ function checkStaticAsset(idx, raw, errs) {
169
+ const base = `static_assets[${idx}]`;
170
+ if (!isObject(raw)) {
171
+ errs.push(shape(base, "expected object"));
172
+ return null;
173
+ }
174
+ if (typeof raw.key !== "string" ||
175
+ typeof raw.content_hash !== "string" ||
176
+ typeof raw.content_type !== "string" ||
177
+ typeof raw.immutable !== "boolean") {
178
+ errs.push(shape(base, "expected { key, content_hash, content_type, immutable }"));
179
+ return null;
180
+ }
181
+ return {
182
+ key: raw.key,
183
+ content_hash: raw.content_hash,
184
+ content_type: raw.content_type,
185
+ immutable: raw.immutable,
186
+ };
187
+ }
188
+ function checkErrorRoutes(raw, errs) {
189
+ if (raw === undefined)
190
+ return undefined;
191
+ if (!isObject(raw)) {
192
+ errs.push(shape("error_routes", "expected object"));
193
+ return undefined;
194
+ }
195
+ const out = {};
196
+ if (raw["404"] !== undefined) {
197
+ if (typeof raw["404"] !== "string")
198
+ errs.push(shape("error_routes.404", "expected string"));
199
+ else
200
+ out["404"] = raw["404"];
201
+ }
202
+ if (raw["5xx"] !== undefined) {
203
+ if (typeof raw["5xx"] !== "string")
204
+ errs.push(shape("error_routes.5xx", "expected string"));
205
+ else
206
+ out["5xx"] = raw["5xx"];
207
+ }
208
+ return out;
209
+ }
210
+ // Mode 2 hooks (R756-F6). The name set is closed — only the engine invokes a
211
+ // hook, so an unrecognised name in a manifest is a build that emitted
212
+ // something nothing will ever call, not a forward-compatible extension.
213
+ function checkHooks(raw, errs) {
214
+ if (raw === undefined)
215
+ return undefined;
216
+ if (!isObject(raw)) {
217
+ errs.push(shape("hooks", "expected object"));
218
+ return undefined;
219
+ }
220
+ const out = {};
221
+ for (const [name, value] of Object.entries(raw)) {
222
+ if (!isHookName(name)) {
223
+ errs.push({
224
+ kind: "unknown_hook",
225
+ path: `hooks.${name}`,
226
+ message: `unknown hook '${name}' (known: ${HOOK_NAMES.join(", ")})`,
227
+ });
228
+ continue;
229
+ }
230
+ if (!isObject(value) || typeof value.entrypoint !== "string") {
231
+ errs.push(shape(`hooks.${name}`, "expected { entrypoint: string }"));
232
+ continue;
233
+ }
234
+ out[name] = { entrypoint: value.entrypoint };
235
+ }
236
+ return out;
237
+ }
238
+ function checkRules(manifest, catalog, errs) {
239
+ manifest.routes.forEach((route, idx) => {
240
+ if (route.mode !== "static")
241
+ return;
242
+ if (route.source_reads) {
243
+ for (const name of route.source_reads) {
244
+ const entry = catalog[name];
245
+ if (!entry) {
246
+ errs.push({
247
+ kind: "shape",
248
+ path: `routes[${idx}].source_reads`,
249
+ message: `route ${route.route}: source '${name}' not declared in catalog`,
250
+ });
251
+ continue;
252
+ }
253
+ if (entry.scope !== "global") {
254
+ errs.push({
255
+ kind: "mode1_scoped_source",
256
+ path: `routes[${idx}].source_reads`,
257
+ message: `route ${route.route}: Mode 1 cannot read from non-'global' source '${name}' (scope='${entry.scope}')`,
258
+ });
259
+ }
260
+ }
261
+ }
262
+ if (route.requires?.includes("user")) {
263
+ errs.push({
264
+ kind: "mode1_requires_user",
265
+ path: `routes[${idx}].requires`,
266
+ message: `route ${route.route}: Mode 1 cannot require 'user' (the build can't enumerate users)`,
267
+ });
268
+ }
269
+ });
270
+ }
271
+ export function validate(input, catalog = {}) {
272
+ const errs = [];
273
+ if (!isObject(input)) {
274
+ return { ok: false, errors: [shape("$", "expected object")] };
275
+ }
276
+ if (input.version !== MANIFEST_VERSION) {
277
+ errs.push({
278
+ kind: "unsupported_version",
279
+ path: "version",
280
+ message: `unsupported manifest version '${String(input.version)}' (expected '${MANIFEST_VERSION}')`,
281
+ });
282
+ }
283
+ if (typeof input.build_id !== "string")
284
+ errs.push(shape("build_id", "expected string"));
285
+ if (!Array.isArray(input.routes)) {
286
+ errs.push(shape("routes", "expected array"));
287
+ return { ok: false, errors: errs };
288
+ }
289
+ const routes = [];
290
+ input.routes.forEach((r, i) => {
291
+ const route = checkRoute(i, r, errs);
292
+ if (route)
293
+ routes.push(route);
294
+ });
295
+ const staticAssetsRaw = input.static_assets ?? [];
296
+ if (!Array.isArray(staticAssetsRaw)) {
297
+ errs.push(shape("static_assets", "expected array"));
298
+ return { ok: false, errors: errs };
299
+ }
300
+ const staticAssets = [];
301
+ staticAssetsRaw.forEach((a, i) => {
302
+ const asset = checkStaticAsset(i, a, errs);
303
+ if (asset)
304
+ staticAssets.push(asset);
305
+ });
306
+ const errorRoutes = checkErrorRoutes(input.error_routes, errs);
307
+ let ssrPrefixes;
308
+ if (input.ssr_prefixes !== undefined) {
309
+ if (!Array.isArray(input.ssr_prefixes) || input.ssr_prefixes.some((s) => typeof s !== "string")) {
310
+ errs.push(shape("ssr_prefixes", "expected string[]"));
311
+ }
312
+ else {
313
+ ssrPrefixes = input.ssr_prefixes;
314
+ }
315
+ }
316
+ const hooks = checkHooks(input.hooks, errs);
317
+ if (errs.length)
318
+ return { ok: false, errors: errs };
319
+ const manifest = {
320
+ version: input.version,
321
+ build_id: input.build_id,
322
+ routes,
323
+ static_assets: staticAssets,
324
+ ...(errorRoutes ? { error_routes: errorRoutes } : {}),
325
+ ...(ssrPrefixes !== undefined ? { ssr_prefixes: ssrPrefixes } : {}),
326
+ ...(hooks !== undefined ? { hooks } : {}),
327
+ };
328
+ checkRules(manifest, catalog, errs);
329
+ if (errs.length)
330
+ return { ok: false, errors: errs };
331
+ return { ok: true, manifest };
332
+ }
333
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,mFAAmF;AACnF,sEAAsE;AACtE,EAAE;AACF,kBAAkB;AAClB,2EAA2E;AAC3E,8EAA8E;AAC9E,2EAA2E;AAC3E,8BAA8B;AAC9B,EAAE;AACF,yEAAyE;AASzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA2BpD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;AACxD,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEtD,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,KAAK,CAAC,IAAY,EAAE,OAAe;IAC1C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,GAAY,EAAE,IAAuB;IACpE,MAAM,IAAI,GAAG,UAAU,GAAG,GAAG,CAAC;IAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC;;QACnF,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IAE3B,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,OAAO,EAAE,mCAAmC,CAAC,CAAC,CAAC;IACxE,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAA6B,CAAC;IAC/C,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,iBAAiB,KAAK,QAAQ,EAAE,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,oBAAoB,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC;IAChD,CAAC;IAED,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACxG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,WAAW,EAAE,4CAA4C,CAAC,CAAC,CAAC;QACrF,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAqC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YAC5F,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,YAAiC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YAC1F,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,WAAgC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,GAAG,CAAC,YAAY,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5E,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,eAAe,EAAE,+BAA+B,CAAC,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,YAA6C,CAAC;IACvE,CAAC;IAED,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC7D,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;QACpC,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,YAAY,EAAE,mDAAmD,CAAC,CAAC,CAAC;QAC7F,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,SAAS,GAAG,CAA+B,CAAC;QAClD,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,YAAY,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,SAAuC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACjF,sEAAsE;YACtE,uDAAuD;YACvD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,YAAY,EAAE,0BAA0B,CAAC,CAAC,CAAC;QACpE,CAAC;aAAM,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,YAAY,EAAE,uCAAuC,CAAC,CAAC,CAAC;QACjF,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,SAAuC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClE,IAAI,GAAG;YAAE,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;IAChC,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1E,OAAO,GAAoB,CAAC;AAC9B,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAE9D,6EAA6E;AAC7E,sEAAsE;AACtE,4EAA4E;AAC5E,0EAA0E;AAC1E,kEAAkE;AAClE,SAAS,eAAe,CACtB,IAAY,EACZ,GAAY,EACZ,IAAuC,EACvC,IAAuB;IAEvB,MAAM,IAAI,GAAG,GAAG,IAAI,aAAa,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,wCAAwC,CAAC,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,QAAQ,EAAE,gEAAgE,CAAC,CAAC,CAAC;QACpG,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACvE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,aAAa,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QACxB,IACE,CAAC,QAAQ,CAAC,KAAK,CAAC;YAChB,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;YAClC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;YAChC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACnD,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,QAAQ,GAAG,CAAC,EAC9C,CAAC;YACD,IAAI,CAAC,IAAI,CACP,KAAK,CAAC,GAAG,IAAI,QAAQ,EAAE,sEAAsE,CAAC,CAC/F,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YACjH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,iBAAiB,EAAE,uCAAuC,CAAC,CAAC,CAAC;YACpF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,GAAkC,CAAC;AAC5C,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,GAAY,EAAE,IAAuB;IAC1E,MAAM,IAAI,GAAG,iBAAiB,GAAG,GAAG,CAAC;IACrC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IACE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ;QAC3B,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ;QACpC,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ;QACpC,OAAO,GAAG,CAAC,SAAS,KAAK,SAAS,EAClC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,yDAAyD,CAAC,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAY,EAAE,IAAuB;IAC7D,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACpD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,CAAC;;YACvF,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC,CAAC;;YACvF,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6EAA6E;AAC7E,sEAAsE;AACtE,wEAAwE;AACxE,SAAS,UAAU,CAAC,GAAY,EAAE,IAAuB;IACvD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC7C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAA2C,EAAE,CAAC;IACvD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,SAAS,IAAI,EAAE;gBACrB,OAAO,EAAE,iBAAiB,IAAI,aAAa,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;aACpE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YAC7D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,EAAE,iCAAiC,CAAC,CAAC,CAAC;YACrE,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO,GAAoB,CAAC;AAC9B,CAAC;AAED,SAAS,UAAU,CAAC,QAAkB,EAAE,OAAsB,EAAE,IAAuB;IACrF,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACrC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO;QAEpC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,IAAI,CAAC,IAAI,CAAC;wBACR,IAAI,EAAE,OAAO;wBACb,IAAI,EAAE,UAAU,GAAG,gBAAgB;wBACnC,OAAO,EAAE,SAAS,KAAK,CAAC,KAAK,aAAa,IAAI,2BAA2B;qBAC1E,CAAC,CAAC;oBACH,SAAS;gBACX,CAAC;gBACD,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC7B,IAAI,CAAC,IAAI,CAAC;wBACR,IAAI,EAAE,qBAAqB;wBAC3B,IAAI,EAAE,UAAU,GAAG,gBAAgB;wBACnC,OAAO,EAAE,SAAS,KAAK,CAAC,KAAK,kDAAkD,IAAI,aAAa,KAAK,CAAC,KAAK,IAAI;qBAChH,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC;gBACR,IAAI,EAAE,qBAAqB;gBAC3B,IAAI,EAAE,UAAU,GAAG,YAAY;gBAC/B,OAAO,EAAE,SAAS,KAAK,CAAC,KAAK,kEAAkE;aAChG,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc,EAAE,UAAyB,EAAE;IAClE,MAAM,IAAI,GAAsB,EAAE,CAAC;IAEnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,gBAAgB,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,qBAAqB;YAC3B,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,iCAAiC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,gBAAgB,IAAI;SACpG,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAExF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC7C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACrC,IAAI,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,MAAM,eAAe,GAAG,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACpD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,YAAY,GAA0B,EAAE,CAAC;IAC/C,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,KAAK;YAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAE/D,IAAI,WAA0C,CAAC;IAC/C,IAAI,KAAK,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;YAChG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,KAAK,CAAC,YAAiC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAEpD,MAAM,QAAQ,GAAa;QACzB,OAAO,EAAE,KAAK,CAAC,OAA8B;QAC7C,QAAQ,EAAE,KAAK,CAAC,QAAkB;QAClC,MAAM;QACN,aAAa,EAAE,YAAY;QAC3B,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAC;IAEF,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAEpC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@mesofact/runtime",
3
+ "version": "0.8.29",
4
+ "description": "Render contract types and adapter API for mesofact (RenderRequest, RenderResult, Source, error taxonomy)",
5
+ "license": "MIT OR Apache-2.0",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./hydration": {
18
+ "types": "./dist/hydration.d.ts",
19
+ "import": "./dist/hydration.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "src"
25
+ ],
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "typecheck": "tsc --noEmit",
29
+ "test": "bun test",
30
+ "clean": "rm -rf dist"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.0.0",
34
+ "typescript": "^5.8.3"
35
+ },
36
+ "dependencies": {
37
+ "aws4fetch": "^1.0.20",
38
+ "smol-toml": "^1.6.1"
39
+ }
40
+ }
@@ -0,0 +1,163 @@
1
+ // `r2` adapter — read-only BlobSource over Cloudflare R2 (or any S3-compatible
2
+ // endpoint). Signs requests with SigV4 via `aws4fetch`, emits `r2:<bucket>:<key>`
3
+ // tags into the ambient trackCtx, honors per-call `.noTrack()` / `.timeout(ms)`.
4
+ //
5
+ // See `.yah/docs/architecture/mesofact.md` §"Adapter API surface" + §"Adapter
6
+ // read-set provenance".
7
+
8
+ import { AwsClient } from "aws4fetch";
9
+ import { BaseSource, type BlobSource, type ListOpts, type R2Object } from "../source.js";
10
+ import { SourceQueryError, SourceTimeoutError, SourceUnavailableError } from "../errors.js";
11
+
12
+ const DEFAULT_TIMEOUT_MS = 2000;
13
+
14
+ export type R2Config = {
15
+ // Logical source name from `mesofact.config.toml` (e.g. "assets"). Used as
16
+ // the registry key and surfaced in errors.
17
+ name: string;
18
+ // R2 bucket — also the `r2:<bucket>:...` tag prefix, per the design's tag
19
+ // taxonomy.
20
+ bucket: string;
21
+ // Endpoint root. For Cloudflare R2 this is
22
+ // `https://<account_id>.r2.cloudflarestorage.com`. No trailing slash.
23
+ endpoint: string;
24
+ accessKeyId: string;
25
+ secretAccessKey: string;
26
+ // Test seam — swap `fetch` to inject a stub. Defaults to `globalThis.fetch`,
27
+ // which aws4fetch already uses internally; passing a custom fn lets tests
28
+ // observe the signed request without hitting the network.
29
+ httpFetch?: typeof fetch;
30
+ };
31
+
32
+ export class R2Adapter extends BaseSource implements BlobSource {
33
+ readonly bucket: string;
34
+ private readonly client: AwsClient;
35
+ private readonly endpoint: string;
36
+ private readonly httpFetch: typeof fetch;
37
+
38
+ constructor(config: R2Config) {
39
+ super(config.name);
40
+ this.bucket = config.bucket;
41
+ this.endpoint = config.endpoint.replace(/\/$/, "");
42
+ this.client = new AwsClient({
43
+ accessKeyId: config.accessKeyId,
44
+ secretAccessKey: config.secretAccessKey,
45
+ service: "s3",
46
+ region: "auto",
47
+ });
48
+ // aws4fetch always uses globalThis.fetch internally; we sign manually and
49
+ // dispatch through `httpFetch` so tests can swap it without touching the
50
+ // global. Calling `globalThis.fetch.bind(globalThis)` preserves the
51
+ // expected receiver for fetch implementations that check it.
52
+ this.httpFetch = config.httpFetch ?? globalThis.fetch.bind(globalThis);
53
+ }
54
+
55
+ async fetch(key: string): Promise<Uint8Array | null> {
56
+ const { track, timeout_ms } = this.consumeOverrides(DEFAULT_TIMEOUT_MS);
57
+ this.emitTag(`r2:${this.bucket}:${key}`, track);
58
+ const url = `${this.endpoint}/${this.bucket}/${encodeKey(key)}`;
59
+ const res = await this.send(url, { method: "GET" }, timeout_ms);
60
+ if (res.status === 404) return null;
61
+ if (!res.ok) {
62
+ throw new SourceQueryError(this.name, `r2 GET ${key} → HTTP ${res.status}`);
63
+ }
64
+ const buf = await res.arrayBuffer();
65
+ return new Uint8Array(buf);
66
+ }
67
+
68
+ async list(prefix: string, opts: ListOpts = {}): Promise<R2Object[]> {
69
+ const { track, timeout_ms } = this.consumeOverrides(DEFAULT_TIMEOUT_MS);
70
+ this.emitTag(`r2:${this.bucket}:${prefix}*`, track);
71
+ const params = new URLSearchParams({ "list-type": "2", prefix });
72
+ if (opts.limit !== undefined) params.set("max-keys", String(opts.limit));
73
+ if (opts.cursor) params.set("continuation-token", opts.cursor);
74
+ if (opts.delimiter) params.set("delimiter", opts.delimiter);
75
+ const url = `${this.endpoint}/${this.bucket}?${params.toString()}`;
76
+ const res = await this.send(url, { method: "GET" }, timeout_ms);
77
+ if (!res.ok) {
78
+ throw new SourceQueryError(this.name, `r2 LIST ${prefix} → HTTP ${res.status}`);
79
+ }
80
+ return parseListV2(await res.text());
81
+ }
82
+
83
+ private async send(url: string, init: RequestInit, timeout_ms: number): Promise<Response> {
84
+ const signed = await this.client.sign(url, init);
85
+ return this.race(() => this.httpFetch(signed), timeout_ms);
86
+ }
87
+
88
+ private async race(call: () => Promise<Response>, timeout_ms: number): Promise<Response> {
89
+ let timer: ReturnType<typeof setTimeout> | undefined;
90
+ try {
91
+ return await Promise.race<Response>([
92
+ call().catch((err) => {
93
+ throw new SourceUnavailableError(this.name, { cause: err });
94
+ }),
95
+ new Promise<Response>((_, reject) => {
96
+ timer = setTimeout(() => reject(new SourceTimeoutError(this.name, timeout_ms)), timeout_ms);
97
+ }),
98
+ ]);
99
+ } finally {
100
+ if (timer) clearTimeout(timer);
101
+ }
102
+ }
103
+ }
104
+
105
+ // `encodeURIComponent` re-encodes `/`, which we want to preserve so S3 sees
106
+ // path-style keys correctly. Other reserved chars stay percent-encoded.
107
+ function encodeKey(key: string): string {
108
+ return key
109
+ .split("/")
110
+ .map((segment) => encodeURIComponent(segment))
111
+ .join("/");
112
+ }
113
+
114
+ // Minimal ListBucketResult v2 parser. S3's XML is a fixed shape; a regex over
115
+ // the `<Contents>` blocks is faster and dep-free than pulling in a full XML
116
+ // parser, and the only fields the contract exposes are key/size/last_modified/
117
+ // etag (per `R2Object`).
118
+ function parseListV2(xml: string): R2Object[] {
119
+ const out: R2Object[] = [];
120
+ for (const match of xml.matchAll(/<Contents>([\s\S]*?)<\/Contents>/g)) {
121
+ const inner = match[1]!;
122
+ const key = pick(inner, "Key");
123
+ const sizeStr = pick(inner, "Size");
124
+ const last_modified = pick(inner, "LastModified");
125
+ const etagRaw = pick(inner, "ETag");
126
+ if (key === undefined || sizeStr === undefined || last_modified === undefined) continue;
127
+ out.push({
128
+ key,
129
+ size: Number.parseInt(sizeStr, 10),
130
+ last_modified,
131
+ ...(etagRaw ? { etag: etagRaw.replace(/^"|"$/g, "") } : {}),
132
+ });
133
+ }
134
+ return out;
135
+ }
136
+
137
+ function pick(haystack: string, tag: string): string | undefined {
138
+ const m = haystack.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`));
139
+ return m?.[1];
140
+ }
141
+
142
+ // Per-process registry. Configuration in T4 loads `mesofact.config.toml` and
143
+ // calls `registerR2()` for each `[sources.*]` of `kind = "r2"`. Render code
144
+ // looks up by name via `r2(name)`.
145
+ const registry = new Map<string, R2Adapter>();
146
+
147
+ export function registerR2(adapter: R2Adapter): void {
148
+ registry.set(adapter.name, adapter);
149
+ }
150
+
151
+ export function clearR2Registry(): void {
152
+ registry.clear();
153
+ }
154
+
155
+ export function r2(name: string): BlobSource {
156
+ const adapter = registry.get(name);
157
+ if (!adapter) {
158
+ throw new Error(
159
+ `r2 source not registered: ${name} (declare it in mesofact.config.toml under [sources.${name}])`,
160
+ );
161
+ }
162
+ return adapter;
163
+ }