@malloy-publisher/server 0.0.231 → 0.0.232
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.docker.md +4 -0
- package/dist/app/api-doc.yaml +74 -3
- package/dist/app/assets/{EnvironmentPage-wa_EPkwK.js → EnvironmentPage-DXEaZIPx.js} +1 -1
- package/dist/app/assets/{HomePage-jnCrupQp.js → HomePage-kofsqpZt.js} +1 -1
- package/dist/app/assets/{LightMode-DYbwNULZ.js → LightMode-CNhIlIlJ.js} +1 -1
- package/dist/app/assets/{MainPage-CuJLrPNI.js → MainPage-Bgqo8jCy.js} +1 -1
- package/dist/app/assets/{MaterializationsPage-D_67x2ee.js → MaterializationsPage-CgBlgGz2.js} +1 -1
- package/dist/app/assets/{ModelPage-D5JtAWqR.js → ModelPage-B0TjoDtf.js} +1 -1
- package/dist/app/assets/{PackagePage-BRwtqUSG.js → PackagePage-BL8vnFj1.js} +1 -1
- package/dist/app/assets/{RouteError-CBNNrnSD.js → RouteError-BzPby0X2.js} +1 -1
- package/dist/app/assets/{ThemeEditorPage-CTCeBneA.js → ThemeEditorPage-CTEP_9r3.js} +1 -1
- package/dist/app/assets/{WorkbookPage-SN6f1RBm.js → WorkbookPage-BwM3BmKw.js} +1 -1
- package/dist/app/assets/{core-Dp3q5Ieu.es-CD5FvM2s.js → core-CK68iv6w.es-CpRxXBt7.js} +1 -1
- package/dist/app/assets/{index-C_tJstcx.js → index-B33zGctF.js} +15 -15
- package/dist/app/assets/{index-DU4r7GdU.js → index-BabP-V-S.js} +346 -321
- package/dist/app/assets/{index-B3Nn8Vm2.js → index-BkiWKaAF.js} +266 -265
- package/dist/app/assets/{index-BLCx1EdC.js → index-CmkW1MiE.js} +1 -1
- package/dist/app/assets/{index-CfmBVB6M.js → index-tXJXwdyj.js} +1 -1
- package/dist/app/index.html +1 -1
- package/dist/instrumentation.mjs +2 -0
- package/dist/package_load_worker.mjs +11 -1
- package/dist/server.mjs +3186 -433
- package/package.json +12 -12
- package/scripts/bake-duckdb-extensions.js +4 -1
- package/src/config.spec.ts +39 -0
- package/src/config.ts +135 -0
- package/src/controller/materialization.controller.spec.ts +62 -0
- package/src/controller/materialization.controller.ts +15 -0
- package/src/controller/package.controller.spec.ts +6 -0
- package/src/controller/package.controller.ts +7 -2
- package/src/errors.ts +19 -0
- package/src/logger.spec.ts +18 -1
- package/src/logger.ts +3 -1
- package/src/materialization_metrics.spec.ts +89 -4
- package/src/materialization_metrics.ts +155 -5
- package/src/mcp/skills/skills_bundle.json +1 -1
- package/src/mcp/tools/embedding_index.spec.ts +1236 -0
- package/src/mcp/tools/embedding_index.ts +808 -0
- package/src/mcp/tools/get_context_eval.ts +194 -45
- package/src/mcp/tools/get_context_tool.spec.ts +295 -2
- package/src/mcp/tools/get_context_tool.ts +159 -10
- package/src/pg_helpers.spec.ts +201 -0
- package/src/pg_helpers.ts +44 -5
- package/src/server.ts +24 -0
- package/src/service/build_plan.spec.ts +128 -2
- package/src/service/build_plan.ts +239 -17
- package/src/service/connection.ts +263 -7
- package/src/service/connection_config.spec.ts +48 -0
- package/src/service/connection_config.ts +21 -8
- package/src/service/connection_federation.spec.ts +184 -0
- package/src/service/embedding_provider.spec.ts +329 -0
- package/src/service/embedding_provider.ts +236 -0
- package/src/service/environment.ts +274 -12
- package/src/service/environment_store.spec.ts +678 -3
- package/src/service/environment_store.ts +449 -33
- package/src/service/environment_store_clone.spec.ts +350 -0
- package/src/service/manifest_loader.spec.ts +68 -13
- package/src/service/manifest_loader.ts +67 -19
- package/src/service/materialization_build_session.spec.ts +435 -0
- package/src/service/materialization_build_session.ts +681 -0
- package/src/service/materialization_eligibility.spec.ts +158 -0
- package/src/service/materialization_eligibility.ts +305 -0
- package/src/service/materialization_serve_transform.spec.ts +1003 -0
- package/src/service/materialization_serve_transform.ts +779 -0
- package/src/service/materialization_service.spec.ts +774 -7
- package/src/service/materialization_service.ts +1107 -42
- package/src/service/materialization_test_fixtures.ts +7 -0
- package/src/service/model.spec.ts +207 -0
- package/src/service/model.ts +540 -52
- package/src/service/model_storage_serve.spec.ts +193 -0
- package/src/service/model_storage_serve_joins.spec.ts +193 -0
- package/src/service/package.spec.ts +196 -0
- package/src/service/package.ts +385 -17
- package/src/service/persistence_policy.spec.ts +109 -0
- package/src/storage/duckdb/schema.ts +37 -0
- package/tests/fixtures/xlsx/database.xlsx +0 -0
- package/tests/integration/first_boot/readiness_line.integration.spec.ts +177 -0
- package/tests/integration/materialization/manifest_binding.integration.spec.ts +104 -0
- package/tests/integration/mcp/mcp_get_context_semantic.integration.spec.ts +235 -0
|
@@ -19,6 +19,40 @@ export type MaterializationMode = "auto" | "orchestrated";
|
|
|
19
19
|
export type MaterializationOutcome = "success" | "failed" | "cancelled";
|
|
20
20
|
/** Manifest bind outcome: timeout is split out from generic failure on purpose. */
|
|
21
21
|
export type ManifestBindOutcome = "success" | "failure" | "timeout";
|
|
22
|
+
/**
|
|
23
|
+
* Which engine a source build / table drop ran against: the source's own
|
|
24
|
+
* warehouse (colocated, in-warehouse CTAS) or a DuckDB/DuckLake `storage=`
|
|
25
|
+
* destination (federated passthrough CTAS). The two have very different latency
|
|
26
|
+
* and failure profiles, so build/drop metrics are labeled with it rather than
|
|
27
|
+
* pooling the two into one series.
|
|
28
|
+
*/
|
|
29
|
+
export type StorageBuildEngine = "storage" | "in_warehouse";
|
|
30
|
+
/** Why a source was refused materialization into a storage destination. */
|
|
31
|
+
export type EligibilityRefusalReason =
|
|
32
|
+
| "free_parameter"
|
|
33
|
+
| "given"
|
|
34
|
+
| "authorize"
|
|
35
|
+
| "not_duckdb_portable"
|
|
36
|
+
| "public_surface_unknown";
|
|
37
|
+
/**
|
|
38
|
+
* How a chained `storage=` source (one that reads a storage-materialized
|
|
39
|
+
* upstream) was built: `parent_reuse` = built by reading the upstream's stored
|
|
40
|
+
* lake table ("stack on the parent" — reuses the parent's work and is
|
|
41
|
+
* consistent-by-construction); `inline_fallback` = stacking was ineligible/failed
|
|
42
|
+
* so the upstream was recomputed from raw against the warehouse (non-strict);
|
|
43
|
+
* `strict_refused` = stacking was ineligible under `strictUpstreams`, so
|
|
44
|
+
* the build failed loudly rather than silently recomputing. This is the headline
|
|
45
|
+
* signal for how far the parent-reuse path gets us in practice.
|
|
46
|
+
*/
|
|
47
|
+
export type ChainedStorageBuildOutcome =
|
|
48
|
+
| "parent_reuse"
|
|
49
|
+
| "inline_fallback"
|
|
50
|
+
| "strict_refused"
|
|
51
|
+
// The parent-reuse attempt failed on infrastructure (attach, CTAS, the
|
|
52
|
+
// destination being unreachable) rather than on shape. Distinct from
|
|
53
|
+
// `inline_fallback` because it is an outage, not a modelling limit: the build
|
|
54
|
+
// fails rather than recomputing from raw against the same destination.
|
|
55
|
+
| "infra_failure";
|
|
22
56
|
|
|
23
57
|
const resetHooks: (() => void)[] = [];
|
|
24
58
|
|
|
@@ -99,6 +133,39 @@ const scheduledFireCounter = lazyCounter(
|
|
|
99
133
|
"Standalone-scheduler attempts to fire a package's materialization.schedule. " +
|
|
100
134
|
"Label: outcome ('fired'|'conflict'|'error').",
|
|
101
135
|
);
|
|
136
|
+
const storageServeRoutingCounter = lazyCounter(
|
|
137
|
+
"publisher_storage_serve_routing_total",
|
|
138
|
+
"storage= serve routing decisions. Label: outcome ('storage'|'live_fallback'|'runtime_live_fallback').",
|
|
139
|
+
);
|
|
140
|
+
const storageBuildFailureCounter = lazyCounter(
|
|
141
|
+
"publisher_storage_build_failures_total",
|
|
142
|
+
"storage= build failures (federation/passthrough/attach/CTAS), distinct from " +
|
|
143
|
+
"in-warehouse build failures. Label: destination (connection name).",
|
|
144
|
+
);
|
|
145
|
+
const eligibilityRefusedCounter = lazyCounter(
|
|
146
|
+
"publisher_materialization_eligibility_refused_total",
|
|
147
|
+
"storage= materialization-eligibility refusals. Label: reason " +
|
|
148
|
+
"('free_parameter'|'given'|'authorize'|'not_duckdb_portable'|" +
|
|
149
|
+
"'public_surface_unknown').",
|
|
150
|
+
);
|
|
151
|
+
const serveShapeTierDropCounter = lazyCounter(
|
|
152
|
+
"publisher_storage_serve_shape_tier_drop_total",
|
|
153
|
+
"storage serve-shape compile escalations: a refinement tier failed to " +
|
|
154
|
+
"compile and the riskiest category was dropped. Label: tier (the failed " +
|
|
155
|
+
"tier index, 0=full).",
|
|
156
|
+
);
|
|
157
|
+
const serveShapeTypeFallbackCounter = lazyCounter(
|
|
158
|
+
"publisher_storage_serve_shape_type_fallback_total",
|
|
159
|
+
"Captured DuckDB column types mapped to json in the serve shape (type " +
|
|
160
|
+
"fidelity loss). Label: kind ('array'|'unrecognized').",
|
|
161
|
+
);
|
|
162
|
+
const chainedStorageBuildCounter = lazyCounter(
|
|
163
|
+
"publisher_storage_chained_build_total",
|
|
164
|
+
"Chained storage= source builds (a source reading a storage-materialized " +
|
|
165
|
+
"upstream). Label: outcome ('parent_reuse'|'inline_fallback'|" +
|
|
166
|
+
"'strict_refused'). The parent_reuse share is the headline signal for how " +
|
|
167
|
+
"far the stack-on-the-parent path gets us vs recompute-from-raw.",
|
|
168
|
+
);
|
|
102
169
|
|
|
103
170
|
/**
|
|
104
171
|
* Record a standalone-scheduler fire attempt. `fired` = a SCHEDULER run started;
|
|
@@ -180,14 +247,97 @@ export function recordManifestBindDegraded(): void {
|
|
|
180
247
|
manifestBindDegradedCounter().add(1);
|
|
181
248
|
}
|
|
182
249
|
|
|
183
|
-
/**
|
|
184
|
-
|
|
185
|
-
|
|
250
|
+
/**
|
|
251
|
+
* Record the wall-clock duration of building one persist source's table,
|
|
252
|
+
* labeled by engine so the DuckDB passthrough path and the in-warehouse CTAS
|
|
253
|
+
* path (very different latency profiles) don't pool into one series.
|
|
254
|
+
*/
|
|
255
|
+
export function recordSourceBuildDuration(
|
|
256
|
+
durationMs: number,
|
|
257
|
+
engine: StorageBuildEngine,
|
|
258
|
+
): void {
|
|
259
|
+
sourceBuildDuration().record(durationMs, { engine });
|
|
186
260
|
}
|
|
187
261
|
|
|
188
262
|
/** Record a best-effort physical-table drop on materialization delete. */
|
|
189
|
-
export function recordDropTables(
|
|
190
|
-
|
|
263
|
+
export function recordDropTables(
|
|
264
|
+
outcome: "success" | "failure",
|
|
265
|
+
engine: StorageBuildEngine,
|
|
266
|
+
): void {
|
|
267
|
+
dropTablesCounter().add(1, { outcome, engine });
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Record a `storage=` build failure (federation / passthrough / attach / CTAS),
|
|
272
|
+
* counted separately from in-warehouse build failures because the storage path
|
|
273
|
+
* has its own failure modes and destination axis.
|
|
274
|
+
*/
|
|
275
|
+
export function recordStorageBuildFailure(destination: string): void {
|
|
276
|
+
storageBuildFailureCounter().add(1, { destination });
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Record a materialization-eligibility refusal (a source that can't be safely
|
|
281
|
+
* materialized into a storage destination). The `given` reason is a security
|
|
282
|
+
* refusal (a frozen given-filtered table would leak rows across tenants); worth
|
|
283
|
+
* tracking how often authors attempt it.
|
|
284
|
+
*/
|
|
285
|
+
export function recordEligibilityRefused(
|
|
286
|
+
reason: EligibilityRefusalReason,
|
|
287
|
+
): void {
|
|
288
|
+
eligibilityRefusedCounter().add(1, { reason });
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Record a serve-shape compile escalation: the refinement tier at `failedTier`
|
|
293
|
+
* did not compile, so the riskiest category was dropped and the shape retried.
|
|
294
|
+
* A systematically-dropping source tells authors which refinements aren't
|
|
295
|
+
* servable from storage.
|
|
296
|
+
*/
|
|
297
|
+
export function recordServeShapeTierDrop(failedTier: number): void {
|
|
298
|
+
serveShapeTierDropCounter().add(1, { tier: String(failedTier) });
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Record a captured DuckDB column type that could not map onto a Malloy basic
|
|
303
|
+
* type and was carried as json in the serve shape — a type-fidelity loss
|
|
304
|
+
* specific to the storage tier. `array` = a collection/array type; `unrecognized`
|
|
305
|
+
* = an unknown/nested/struct/enum/blob type.
|
|
306
|
+
*/
|
|
307
|
+
export function recordServeShapeTypeFallback(
|
|
308
|
+
kind: "array" | "unrecognized",
|
|
309
|
+
): void {
|
|
310
|
+
serveShapeTypeFallbackCounter().add(1, { kind });
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Record a `storage=` serve-routing decision: `storage` = the query was served
|
|
315
|
+
* from the materialized table via the virtual-source transform; `live_fallback`
|
|
316
|
+
* = the transform was ineligible for this query (a refinement it can't
|
|
317
|
+
* reproduce, an unbound source, mode not `on`) so it was served live;
|
|
318
|
+
* `runtime_live_fallback` = the query DID route to storage and the store then
|
|
319
|
+
* failed underneath it, and every binding's `freshnessFallback=live` allowed it
|
|
320
|
+
* to degrade. That last one is the operationally interesting label: it means the
|
|
321
|
+
* tier is broken while queries still succeed, which is invisible in the hit rate
|
|
322
|
+
* alone. This hit rate is the headline KPI of the storage tier — otherwise the
|
|
323
|
+
* fallback side is only a DEBUG log.
|
|
324
|
+
*/
|
|
325
|
+
export function recordStorageServeRouting(
|
|
326
|
+
outcome: "storage" | "live_fallback" | "runtime_live_fallback",
|
|
327
|
+
): void {
|
|
328
|
+
storageServeRoutingCounter().add(1, { outcome });
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Record how a chained `storage=` source was built (see
|
|
333
|
+
* {@link ChainedStorageBuildOutcome}). Only fired for a source that actually
|
|
334
|
+
* reads a storage-materialized upstream — a single-source build emits nothing
|
|
335
|
+
* here. The parent_reuse : inline_fallback ratio is the spike's key learning.
|
|
336
|
+
*/
|
|
337
|
+
export function recordChainedStorageBuild(
|
|
338
|
+
outcome: ChainedStorageBuildOutcome,
|
|
339
|
+
): void {
|
|
340
|
+
chainedStorageBuildCounter().add(1, { outcome });
|
|
191
341
|
}
|
|
192
342
|
|
|
193
343
|
/** Visible for tests. Drops cached instruments so a fresh MeterProvider can capture emissions. */
|