@query-farm/vgi 0.24.1 → 0.25.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.
@@ -530,6 +530,9 @@ var init_storage = __esm(() => {
530
530
  });
531
531
  });
532
532
 
533
+ // src/http/fetch.ts
534
+ import { createHttpHandler, unpackStateToken } from "@query-farm/vgi-rpc";
535
+
533
536
  // src/arrow/predicates.ts
534
537
  var TypeId = {
535
538
  Null: 1,
@@ -554,24 +557,6 @@ var TypeId = {
554
557
  LargeUtf8: 20,
555
558
  Dictionary: -1
556
559
  };
557
- function isNull(t) {
558
- return t.typeId === TypeId.Null;
559
- }
560
- function isInt(t) {
561
- return t.typeId === TypeId.Int;
562
- }
563
- function isFloat(t) {
564
- return t.typeId === TypeId.Float;
565
- }
566
- function isBinary(t) {
567
- return t.typeId === TypeId.Binary || t.typeId === TypeId.LargeBinary;
568
- }
569
- function isUtf8(t) {
570
- return t.typeId === TypeId.Utf8 || t.typeId === TypeId.LargeUtf8;
571
- }
572
- function isBool(t) {
573
- return t.typeId === TypeId.Bool;
574
- }
575
560
  function isDecimal(t) {
576
561
  return t.typeId === TypeId.Decimal;
577
562
  }
@@ -2313,426 +2298,6 @@ function map2(keyField, valueField, keysSorted) {
2313
2298
  function dictionary2(valueType, indexType, ordered, id) {
2314
2299
  return dictionary(valueType, indexType, ordered, id);
2315
2300
  }
2316
- // src/types.ts
2317
- var VGI_ARG_KEY = "vgi_arg";
2318
- var VGI_ARG_NAMED = "named";
2319
- var VGI_TYPE_KEY = "vgi_type";
2320
- var VGI_TYPE_TABLE = "table";
2321
- var VGI_DOC_KEY = "vgi_doc";
2322
- var VGI_DEFAULT_KEY = "vgi_default";
2323
-
2324
- // src/http/describe-json.ts
2325
- var LANDING_SCHEMA_VERSION = 1;
2326
- var CUPOLA_BASE = "https://cupola.query-farm.services";
2327
- var STRING_TAGS = {
2328
- title: "vgi.title",
2329
- doc_md: "vgi.doc_md",
2330
- source_url: "vgi.source_url",
2331
- license: "vgi.license",
2332
- author: "vgi.author",
2333
- copyright: "vgi.copyright",
2334
- support_contact: "vgi.support_contact",
2335
- support_policy_url: "vgi.support_policy_url"
2336
- };
2337
- var KEYWORDS_TAG = "vgi.keywords";
2338
- function typeToString(type) {
2339
- if (isNull(type))
2340
- return "NULL";
2341
- if (isUtf8(type))
2342
- return "VARCHAR";
2343
- if (isBinary(type))
2344
- return "BLOB";
2345
- if (isBool(type))
2346
- return "BOOLEAN";
2347
- if (isInt(type)) {
2348
- const bw = type.bitWidth ?? 32;
2349
- return bw === 64 ? "BIGINT" : "INTEGER";
2350
- }
2351
- if (isFloat(type)) {
2352
- const precision = type.precision ?? 2;
2353
- return precision === 1 ? "FLOAT" : "DOUBLE";
2354
- }
2355
- const s = type.toString?.();
2356
- return s ?? String(type.typeId);
2357
- }
2358
- function arrowTypeString(type) {
2359
- if (isNull(type))
2360
- return "null";
2361
- if (isBool(type))
2362
- return "bool";
2363
- if (isUtf8(type))
2364
- return "string";
2365
- if (isBinary(type))
2366
- return "binary";
2367
- if (isInt(type)) {
2368
- const bw = type.bitWidth ?? 32;
2369
- const signed = type.isSigned ?? type.signed ?? true;
2370
- return `${signed ? "" : "u"}int${bw}`;
2371
- }
2372
- if (isFloat(type)) {
2373
- const precision = type.precision ?? 2;
2374
- return precision === 0 ? "halffloat" : precision === 1 ? "float" : "double";
2375
- }
2376
- const s = type.toString?.();
2377
- return (s ?? String(type.typeId)).toLowerCase();
2378
- }
2379
- function fieldMeta(field3, key) {
2380
- return field3.metadata.get(key);
2381
- }
2382
- function fieldToColumn(field3) {
2383
- const col = { name: field3.name, type: typeToString(field3.type) };
2384
- const comment = fieldMeta(field3, "comment") ?? fieldMeta(field3, VGI_DOC_KEY);
2385
- if (comment)
2386
- col.comment = comment;
2387
- return col;
2388
- }
2389
- function readSchemaSafe(bytes) {
2390
- if (!bytes || bytes.length === 0)
2391
- return null;
2392
- try {
2393
- return deserializeSchema(bytes);
2394
- } catch {
2395
- return null;
2396
- }
2397
- }
2398
- function functionDisplayType(fn) {
2399
- const t = String(fn.function_type).toUpperCase();
2400
- if (t === "SCALAR")
2401
- return "scalar";
2402
- if (t === "AGGREGATE")
2403
- return "aggregate";
2404
- if (fn.has_finalize)
2405
- return "table_in_out";
2406
- return "table";
2407
- }
2408
- function functionReturns(fn) {
2409
- const schema3 = readSchemaSafe(fn.output_schema);
2410
- if (schema3 === null || schema3.fields.length === 0)
2411
- return;
2412
- const t = String(fn.function_type).toUpperCase();
2413
- if (t === "SCALAR" || t === "AGGREGATE") {
2414
- return typeToString(schema3.fields[0].type);
2415
- }
2416
- const cols = schema3.fields.map((f) => `${f.name} ${typeToString(f.type)}`).join(", ");
2417
- return `TABLE(${cols})`;
2418
- }
2419
- function functionArgs(fn) {
2420
- const schema3 = readSchemaSafe(fn.arguments);
2421
- if (schema3 === null)
2422
- return [];
2423
- const args = [];
2424
- for (const field3 of schema3.fields) {
2425
- if (fieldMeta(field3, VGI_TYPE_KEY) === VGI_TYPE_TABLE)
2426
- continue;
2427
- const arg = { name: field3.name, type: typeToString(field3.type) };
2428
- if (fieldMeta(field3, VGI_ARG_KEY) === VGI_ARG_NAMED)
2429
- arg.named = true;
2430
- const doc = fieldMeta(field3, VGI_DOC_KEY);
2431
- if (doc)
2432
- arg.desc = doc;
2433
- const rawDefault = fieldMeta(field3, VGI_DEFAULT_KEY);
2434
- if (rawDefault !== undefined) {
2435
- try {
2436
- arg.default = JSON.stringify(JSON.parse(rawDefault));
2437
- } catch {
2438
- arg.default = rawDefault;
2439
- }
2440
- }
2441
- args.push(arg);
2442
- }
2443
- return args;
2444
- }
2445
- function macroDisplayType(m) {
2446
- return String(m.macro_type).toUpperCase() === "SCALAR" ? "scalar" : "table";
2447
- }
2448
- function macroDefaultJson(value) {
2449
- if (typeof value === "bigint")
2450
- return value.toString();
2451
- try {
2452
- return JSON.stringify(value);
2453
- } catch {
2454
- return String(value);
2455
- }
2456
- }
2457
- function macroArgs(m) {
2458
- const defaults = new Map;
2459
- const defBytes = m.parameter_default_values;
2460
- if (defBytes && defBytes.length > 0) {
2461
- try {
2462
- const batch = deserializeBatch(defBytes);
2463
- for (const field3 of batch.schema.fields) {
2464
- try {
2465
- defaults.set(field3.name, batch.getChild(field3.name)?.get(0));
2466
- } catch {}
2467
- }
2468
- } catch {}
2469
- }
2470
- const schema3 = readSchemaSafe(m.arguments_schema);
2471
- const fields = schema3 ? schema3.fields : null;
2472
- const fieldByName = new Map;
2473
- if (fields)
2474
- for (const f of fields)
2475
- fieldByName.set(f.name, f);
2476
- const names = fields ? fields.map((f) => f.name) : m.parameters;
2477
- const args = [];
2478
- for (const name of names) {
2479
- const field3 = fieldByName.get(name);
2480
- const arg = field3 !== undefined && !isNull(field3.type) ? { name, type: arrowTypeString(field3.type) } : { name, type: "ANY" };
2481
- const doc = field3 !== undefined ? fieldMeta(field3, VGI_DOC_KEY) : undefined;
2482
- if (doc)
2483
- arg.desc = doc;
2484
- if (defaults.has(name)) {
2485
- arg.named = true;
2486
- arg.default = macroDefaultJson(defaults.get(name));
2487
- }
2488
- args.push(arg);
2489
- }
2490
- return args;
2491
- }
2492
- function macroToObject(m) {
2493
- return {
2494
- name: m.name,
2495
- type: macroDisplayType(m),
2496
- doc: m.comment ?? "",
2497
- args: macroArgs(m)
2498
- };
2499
- }
2500
- async function schemaContents(iface, aod, name, kind) {
2501
- try {
2502
- if (kind === "TABLE") {
2503
- return await iface.schemaContentsTables(aod, name);
2504
- }
2505
- return await iface.schemaContentsViews(aod, name);
2506
- } catch {
2507
- return [];
2508
- }
2509
- }
2510
- async function schemaFunctions(iface, aod, name) {
2511
- const out = [];
2512
- for (const kind of ["SCALAR_FUNCTION", "TABLE_FUNCTION", "AGGREGATE_FUNCTION"]) {
2513
- try {
2514
- out.push(...await iface.schemaContentsFunctions(aod, name, kind));
2515
- } catch {}
2516
- }
2517
- return out;
2518
- }
2519
- async function schemaMacros(iface, aod, name) {
2520
- const out = [];
2521
- for (const kind of ["SCALAR_MACRO", "TABLE_MACRO"]) {
2522
- try {
2523
- out.push(...await iface.schemaContentsMacros(aod, name, kind));
2524
- } catch {}
2525
- }
2526
- return out;
2527
- }
2528
- async function buildSchemas(iface, aod) {
2529
- let schemaInfos;
2530
- try {
2531
- schemaInfos = await iface.schemas(aod);
2532
- } catch {
2533
- return { schemas: [], counts: { schemas: 0, tables: 0, views: 0, functions: 0 } };
2534
- }
2535
- const schemas = [];
2536
- const counts = { schemas: 0, tables: 0, views: 0, functions: 0 };
2537
- for (const si of schemaInfos) {
2538
- const tablesRaw = await schemaContents(iface, aod, si.name, "TABLE");
2539
- const viewsRaw = await schemaContents(iface, aod, si.name, "VIEW");
2540
- const funcsRaw = await schemaFunctions(iface, aod, si.name);
2541
- const macrosRaw = await schemaMacros(iface, aod, si.name);
2542
- const tables = tablesRaw.map((t) => {
2543
- const schema3 = readSchemaSafe(t.columns);
2544
- return { name: t.name, cols: schema3 ? schema3.fields.length : 0, comment: t.comment ?? "" };
2545
- });
2546
- const views = viewsRaw.map((v) => ({
2547
- name: v.name,
2548
- cols: Object.keys(v.column_comments ?? {}).length,
2549
- comment: v.comment ?? "",
2550
- def: v.definition
2551
- }));
2552
- const functions = funcsRaw.map((fn) => {
2553
- const obj = {
2554
- name: fn.name,
2555
- type: functionDisplayType(fn),
2556
- doc: fn.description ?? "",
2557
- args: functionArgs(fn)
2558
- };
2559
- const ret = functionReturns(fn);
2560
- if (ret)
2561
- obj.returns = ret;
2562
- return obj;
2563
- });
2564
- functions.push(...macrosRaw.map((m) => macroToObject(m)));
2565
- functions.sort((a, b) => String(a.type).localeCompare(String(b.type)) || String(a.name).localeCompare(String(b.name)));
2566
- const schemaObj = { name: si.name };
2567
- if (si.comment)
2568
- schemaObj.doc = si.comment;
2569
- schemaObj.tables = tables;
2570
- schemaObj.views = views;
2571
- schemaObj.functions = functions;
2572
- schemas.push(schemaObj);
2573
- counts.schemas += 1;
2574
- counts.tables += tables.length;
2575
- counts.views += views.length;
2576
- counts.functions += functions.length;
2577
- }
2578
- return { schemas, counts };
2579
- }
2580
- function catalogTags(result) {
2581
- const tags = result?.tags;
2582
- if (!tags)
2583
- return {};
2584
- const out = {};
2585
- for (const [key, tag] of Object.entries(STRING_TAGS)) {
2586
- const val = tags[tag];
2587
- if (val)
2588
- out[key] = val;
2589
- }
2590
- const kw = tags[KEYWORDS_TAG];
2591
- if (kw) {
2592
- try {
2593
- const parsed = JSON.parse(kw);
2594
- if (Array.isArray(parsed))
2595
- out.keywords = parsed.map((k) => String(k));
2596
- } catch {}
2597
- }
2598
- return out;
2599
- }
2600
- function decodeAttachOption(bytes) {
2601
- try {
2602
- const batch = deserializeBatch(bytes);
2603
- if (batch.numRows === 0)
2604
- return null;
2605
- const name = String(batch.getChild("name")?.get(0) ?? "");
2606
- const description = String(batch.getChild("description")?.get(0) ?? "");
2607
- const typeBytes = batch.getChild("type")?.get(0);
2608
- let type = "";
2609
- const typeSchema = readSchemaSafe(typeBytes ?? null);
2610
- if (typeSchema && typeSchema.fields.length > 0)
2611
- type = typeToString(typeSchema.fields[0].type);
2612
- let defaultStr = "";
2613
- const defBytes = batch.getChild("default_value")?.get(0);
2614
- if (defBytes) {
2615
- try {
2616
- const defBatch = deserializeBatch(defBytes);
2617
- if (defBatch.numRows > 0) {
2618
- const v = defBatch.getChild("value")?.get(0);
2619
- defaultStr = v == null ? "" : String(v);
2620
- }
2621
- } catch {}
2622
- }
2623
- return { name, type, default: defaultStr, description };
2624
- } catch {
2625
- return null;
2626
- }
2627
- }
2628
- async function attachCatalog(iface, name) {
2629
- try {
2630
- return await iface.attach(name, {}, null, null);
2631
- } catch {
2632
- return null;
2633
- }
2634
- }
2635
- async function buildCatalog(iface, name, info) {
2636
- const result = await attachCatalog(iface, name);
2637
- const attachOptions = (info?.attach_option_specs ?? []).map((b) => decodeAttachOption(b)).filter((o) => o !== null);
2638
- const dataVersions = (info?.releases ?? []).map((r) => r.summary ? { spec: r.version, label: r.summary } : { spec: r.version });
2639
- let impl = info?.implementation_version ?? null;
2640
- let dvs = info?.data_version_spec ?? null;
2641
- if (result) {
2642
- impl = result.resolved_implementation_version ?? impl;
2643
- dvs = result.resolved_data_version ?? dvs;
2644
- }
2645
- let schemas = [];
2646
- let counts = { schemas: 0, tables: 0, views: 0, functions: 0 };
2647
- if (result) {
2648
- const built = await buildSchemas(iface, result.attach_opaque_data);
2649
- schemas = built.schemas;
2650
- counts = built.counts;
2651
- }
2652
- return {
2653
- name,
2654
- implementation_version: impl,
2655
- data_version_spec: dvs,
2656
- data_versions: dataVersions,
2657
- attach_options: attachOptions,
2658
- tags: catalogTags(result),
2659
- counts,
2660
- schemas
2661
- };
2662
- }
2663
- async function catalogInfoByName(iface) {
2664
- const map3 = new Map;
2665
- if (typeof iface.catalogsInfo === "function") {
2666
- try {
2667
- const infos = await iface.catalogsInfo();
2668
- for (const info of infos)
2669
- map3.set(info.name, info);
2670
- } catch {}
2671
- }
2672
- return map3;
2673
- }
2674
- async function buildDescribeJson(iface, worker, opts = {}) {
2675
- const infos = await catalogInfoByName(iface);
2676
- let names;
2677
- try {
2678
- names = iface.catalogs();
2679
- } catch {
2680
- names = [];
2681
- }
2682
- const catalogs = [];
2683
- for (const name of names) {
2684
- catalogs.push(await buildCatalog(iface, name, infos.get(name)));
2685
- }
2686
- return {
2687
- landing_schema_version: LANDING_SCHEMA_VERSION,
2688
- worker: {
2689
- name: worker.name,
2690
- doc: worker.doc ?? "",
2691
- version: worker.version ?? "unknown",
2692
- lang: "typescript"
2693
- },
2694
- server_id: opts.serverId ?? "",
2695
- oauth: opts.oauth ?? false,
2696
- cupola_base: opts.cupolaBase ?? CUPOLA_BASE,
2697
- catalogs
2698
- };
2699
- }
2700
- async function buildColumnsJson(iface, catalog, schema3, table) {
2701
- const result = await attachCatalog(iface, catalog);
2702
- if (!result)
2703
- return null;
2704
- const aod = result.attach_opaque_data;
2705
- const tables = await schemaContents(iface, aod, schema3, "TABLE");
2706
- for (const t of tables) {
2707
- if (t.name === table) {
2708
- const arrow = readSchemaSafe(t.columns);
2709
- return { columns: (arrow?.fields ?? []).map((f) => fieldToColumn(f)) };
2710
- }
2711
- }
2712
- const views = await schemaContents(iface, aod, schema3, "VIEW");
2713
- for (const v of views) {
2714
- if (v.name === table) {
2715
- return {
2716
- columns: Object.entries(v.column_comments ?? {}).map(([name, comment]) => ({
2717
- name,
2718
- type: "",
2719
- comment
2720
- }))
2721
- };
2722
- }
2723
- }
2724
- return null;
2725
- }
2726
- function createLandingDescribe(iface, worker, opts = {}) {
2727
- return {
2728
- describe: (ctx) => buildDescribeJson(iface, worker, { ...ctx, cupolaBase: opts.cupolaBase }),
2729
- columns: (catalog, schema3, table) => buildColumnsJson(iface, catalog, schema3, table)
2730
- };
2731
- }
2732
-
2733
- // src/http/fetch.ts
2734
- import { createHttpHandler, unpackStateToken } from "@query-farm/vgi-rpc";
2735
-
2736
2301
  // src/util/bytes.ts
2737
2302
  function toUint8Array(val) {
2738
2303
  if (val instanceof Uint8Array)
@@ -6362,7 +5927,7 @@ function createVgiFetch(opts) {
6362
5927
  stateSerializer: arrowStateSerializer,
6363
5928
  corsOrigins: opts.corsOrigins,
6364
5929
  repositoryUrl: opts.repositoryUrl,
6365
- landingDescribe: opts.landingDescribe
5930
+ landingInfo: opts.landingInfo
6366
5931
  });
6367
5932
  return async (req) => handler(req);
6368
5933
  }
@@ -6436,11 +6001,7 @@ function createVgiWorkerFetch(opts) {
6436
6001
  serverId: opts.serverId ?? opts.name,
6437
6002
  corsOrigins,
6438
6003
  repositoryUrl: opts.repositoryUrl,
6439
- landingDescribe: createLandingDescribe(opts.catalogInterface, {
6440
- name: opts.name,
6441
- doc: opts.doc,
6442
- version: opts.version
6443
- })
6004
+ landingInfo: { name: opts.name, doc: opts.doc, version: opts.version }
6444
6005
  });
6445
6006
  }
6446
6007
  function serveVgiWorker(opts) {
@@ -6456,7 +6017,7 @@ function serveVgiWorker(opts) {
6456
6017
  const base = `http://localhost:${server.port}`;
6457
6018
  console.log(`${opts.name} VGI HTTP worker listening on ${base}`);
6458
6019
  console.log(` landing page ${base}/`);
6459
- console.log(` describe.json ${base}/describe.json`);
6020
+ console.log(` client bundle ${base}/vgi-client.js`);
6460
6021
  console.log(` health ${base}/health`);
6461
6022
  console.log(` attach ATTACH '${opts.name}' AS ${opts.name} (TYPE vgi, LOCATION '${base}');`);
6462
6023
  }
@@ -6472,4 +6033,4 @@ export {
6472
6033
  DEFAULT_PORT
6473
6034
  };
6474
6035
 
6475
- //# debugId=FBD13B7363E61A7B64756E2164756E21
6036
+ //# debugId=0830F7D05944ECFB64756E2164756E21