mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-12 08:05:44 +00:00
perf: lazy-load heavy deps (graphql, openapi-parser, sha256) (#8145)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
co-authored by
Claude Opus 4.6
parent
3daf79efad
commit
fcafc3b133
@@ -32,10 +32,10 @@
|
||||
</ToggleButtonGroup>
|
||||
{/if}
|
||||
{#if dbSchema.lang === 'graphql'}
|
||||
{#await import('$lib/components/GraphqlSchemaViewer.svelte')}
|
||||
{#await Promise.all([import('$lib/components/GraphqlSchemaViewer.svelte'), formatGraphqlSchema(dbSchema.schema)])}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default code={formatGraphqlSchema(dbSchema.schema)} class="h-full" />
|
||||
{:then [Module, code]}
|
||||
<Module.default {code} class="h-full" />
|
||||
{/await}
|
||||
{:else}
|
||||
<ObjectViewer json={formatSchema(dbSchema)} pureViewer collapseLevel={1} />
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
import { type Preview } from '$lib/gen'
|
||||
import type { DBSchema, GraphqlSchema, SQLSchema } from '$lib/stores'
|
||||
|
||||
import { stringifySchema } from '$lib/components/copilot/lib'
|
||||
import { stringifyGraphqlSchema, stringifySchema } from '$lib/components/copilot/lib'
|
||||
import type { DbType } from '$lib/components/dbTypes'
|
||||
import { getDatabaseArg } from '$lib/components/dbOps'
|
||||
|
||||
@@ -416,7 +416,7 @@ export async function getDbSchemas(
|
||||
workspace,
|
||||
requestBody: {
|
||||
language: sqlScript.lang as Preview['language'],
|
||||
content: sqlScript.code,
|
||||
content: typeof sqlScript.code === 'function' ? await sqlScript.code() : sqlScript.code,
|
||||
tag: options.customTag,
|
||||
args: {
|
||||
[sqlScript.argName]: resourcePath.startsWith('datatable://')
|
||||
@@ -458,7 +458,10 @@ export async function getDbSchemas(
|
||||
lang: 'graphql' as GraphqlSchema['lang'],
|
||||
schema: result
|
||||
}
|
||||
return { ...(dbSchema as any), stringified: stringifySchema(dbSchema as any) }
|
||||
return {
|
||||
...(dbSchema as any),
|
||||
stringified: await stringifyGraphqlSchema(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import type { ScriptLang } from '$lib/gen'
|
||||
import type { SQLSchema } from '$lib/stores'
|
||||
import {
|
||||
buildClientSchema,
|
||||
getIntrospectionQuery,
|
||||
printSchema,
|
||||
type IntrospectionQuery
|
||||
} from 'graphql'
|
||||
import type { IntrospectionQuery } from 'graphql'
|
||||
|
||||
import type { DbType } from '$lib/components/dbTypes'
|
||||
|
||||
@@ -64,7 +59,7 @@ export function resourceTypeToLang(rt: string) {
|
||||
const legacyScripts: Record<
|
||||
string,
|
||||
{
|
||||
code: string
|
||||
code: string | (() => Promise<string>)
|
||||
lang: string
|
||||
processingFn?: (any: any) => SQLSchema['schema']
|
||||
argName: string
|
||||
@@ -146,7 +141,7 @@ const legacyScripts: Record<
|
||||
argName: 'database'
|
||||
},
|
||||
graphql: {
|
||||
code: getIntrospectionQuery(),
|
||||
code: () => import('graphql').then((m) => m.getIntrospectionQuery()),
|
||||
lang: 'graphql',
|
||||
argName: 'api'
|
||||
},
|
||||
@@ -305,7 +300,8 @@ export function formatSchema(dbSchema: {
|
||||
}
|
||||
}
|
||||
|
||||
export function formatGraphqlSchema(schema: IntrospectionQuery): string {
|
||||
export async function formatGraphqlSchema(schema: IntrospectionQuery): Promise<string> {
|
||||
const { buildClientSchema, printSchema } = await import('graphql')
|
||||
return printSchema(buildClientSchema(schema))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Sha256 } from '@aws-crypto/sha256-js'
|
||||
import { getCountInput } from '../components/display/dbtable/queries/count'
|
||||
import { getDeleteInput } from '../components/display/dbtable/queries/delete'
|
||||
import { getInsertInput } from '../components/display/dbtable/queries/insert'
|
||||
@@ -236,6 +235,7 @@ async function hash(message) {
|
||||
return hashHex
|
||||
} catch {
|
||||
//subtle not available, trying pure js
|
||||
const { Sha256 } = await import('@aws-crypto/sha256-js')
|
||||
const hash = new Sha256()
|
||||
hash.update(message ?? '')
|
||||
const result = Array.from(await hash.digest())
|
||||
|
||||
@@ -1,37 +1,35 @@
|
||||
import type { StaticAppInput } from "../inputType"
|
||||
import { Sha256 } from '@aws-crypto/sha256-js'
|
||||
import type { StaticAppInput } from '../inputType'
|
||||
|
||||
export function collectStaticFields(
|
||||
fields: Record<string, StaticAppInput>
|
||||
) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(fields ?? {})
|
||||
.filter(([k, v]) => v.type == 'static')
|
||||
.map(([k, v]) => {
|
||||
return [k, v['value']]
|
||||
})
|
||||
)
|
||||
export function collectStaticFields(fields: Record<string, StaticAppInput>) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(fields ?? {})
|
||||
.filter(([k, v]) => v.type == 'static')
|
||||
.map(([k, v]) => {
|
||||
return [k, v['value']]
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export type TriggerableV2 = {
|
||||
static_inputs: Record<string, any>
|
||||
one_of_inputs?: Record<string, any[] | undefined>
|
||||
allow_user_resources?: string[]
|
||||
static_inputs: Record<string, any>
|
||||
one_of_inputs?: Record<string, any[] | undefined>
|
||||
allow_user_resources?: string[]
|
||||
}
|
||||
|
||||
export async function hash(message) {
|
||||
try {
|
||||
const msgUint8 = new TextEncoder().encode(message) // encode as (utf-8) Uint8Array
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8) // hash the message
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array
|
||||
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
|
||||
return hashHex
|
||||
} catch {
|
||||
//subtle not available, trying pure js
|
||||
const hash = new Sha256()
|
||||
hash.update(message ?? '')
|
||||
const result = Array.from(await hash.digest())
|
||||
const hex = result.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
|
||||
return hex
|
||||
}
|
||||
}
|
||||
try {
|
||||
const msgUint8 = new TextEncoder().encode(message) // encode as (utf-8) Uint8Array
|
||||
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8) // hash the message
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array
|
||||
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
|
||||
return hashHex
|
||||
} catch {
|
||||
//subtle not available, trying pure js
|
||||
const { Sha256 } = await import('@aws-crypto/sha256-js')
|
||||
const hash = new Sha256()
|
||||
hash.update(message ?? '')
|
||||
const result = Array.from(await hash.digest())
|
||||
const hex = result.map((b) => b.toString(16).padStart(2, '0')).join('') // convert bytes to hex string
|
||||
return hex
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,13 +64,10 @@
|
||||
{:else if contextElement.type === 'db'}
|
||||
<div class="p-2 max-w-96 max-h-[300px] text-xs overflow-auto">
|
||||
{#if contextElement.schema && contextElement.schema.lang === 'graphql'}
|
||||
{#await import('$lib/components/GraphqlSchemaViewer.svelte')}
|
||||
{#await Promise.all([import('$lib/components/GraphqlSchemaViewer.svelte'), formatGraphqlSchema(contextElement.schema.schema)])}
|
||||
<Loader2 class="animate-spin" />
|
||||
{:then Module}
|
||||
<Module.default
|
||||
code={formatGraphqlSchema(contextElement.schema.schema)}
|
||||
class="h-full"
|
||||
/>
|
||||
{:then [Module, code]}
|
||||
<Module.default {code} class="h-full" />
|
||||
{/await}
|
||||
{:else if contextElement.schema}
|
||||
<ObjectViewer json={formatSchema(contextElement.schema)} pureViewer collapseLevel={1} />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AIProvider, AIProviderModel } from '$lib/gen'
|
||||
import { workspaceStore, type DBSchema, type GraphqlSchema, type SQLSchema } from '$lib/stores'
|
||||
import { buildClientSchema, printSchema } from 'graphql'
|
||||
import { workspaceStore, type DBSchema, type SQLSchema } from '$lib/stores'
|
||||
import type { IntrospectionQuery } from 'graphql'
|
||||
import OpenAI from 'openai'
|
||||
import type {
|
||||
ChatCompletionChunk,
|
||||
@@ -587,43 +587,40 @@ export function addThousandsSeparator(n: number) {
|
||||
return n.toFixed().replace(/\B(?=(\d{3})+(?!\d))/g, "'")
|
||||
}
|
||||
|
||||
export function stringifySchema(
|
||||
dbSchema: Omit<SQLSchema, 'stringified'> | Omit<GraphqlSchema, 'stringified'>
|
||||
) {
|
||||
export function stringifySchema(dbSchema: Omit<SQLSchema, 'stringified'>): string {
|
||||
const { schema, lang } = dbSchema
|
||||
if (lang === 'graphql') {
|
||||
let graphqlSchema = printSchema(buildClientSchema(schema))
|
||||
return graphqlSchema
|
||||
} else {
|
||||
let smallerSchema: {
|
||||
[schemaKey: string]: {
|
||||
[tableKey: string]: Array<[string, string, boolean, string?]>
|
||||
}
|
||||
} = {}
|
||||
for (const schemaKey in schema) {
|
||||
smallerSchema[schemaKey] = {}
|
||||
for (const tableKey in schema[schemaKey]) {
|
||||
smallerSchema[schemaKey][tableKey] = []
|
||||
for (const colKey in schema[schemaKey][tableKey]) {
|
||||
const col = schema[schemaKey][tableKey][colKey]
|
||||
const p: [string, string, boolean, string?] = [colKey, col.type, col.required]
|
||||
if (col.default) {
|
||||
p.push(col.default)
|
||||
}
|
||||
smallerSchema[schemaKey][tableKey].push(p)
|
||||
let smallerSchema: {
|
||||
[schemaKey: string]: {
|
||||
[tableKey: string]: Array<[string, string, boolean, string?]>
|
||||
}
|
||||
} = {}
|
||||
for (const schemaKey in schema) {
|
||||
smallerSchema[schemaKey] = {}
|
||||
for (const tableKey in schema[schemaKey]) {
|
||||
smallerSchema[schemaKey][tableKey] = []
|
||||
for (const colKey in schema[schemaKey][tableKey]) {
|
||||
const col = schema[schemaKey][tableKey][colKey]
|
||||
const p: [string, string, boolean, string?] = [colKey, col.type, col.required]
|
||||
if (col.default) {
|
||||
p.push(col.default)
|
||||
}
|
||||
smallerSchema[schemaKey][tableKey].push(p)
|
||||
}
|
||||
}
|
||||
|
||||
let finalSchema: typeof smallerSchema | (typeof smallerSchema)['schemaKey'] = smallerSchema
|
||||
if (dbSchema.publicOnly) {
|
||||
finalSchema =
|
||||
smallerSchema.public || smallerSchema.PUBLIC || smallerSchema.dbo || smallerSchema
|
||||
} else if (lang === 'mysql' && Object.keys(smallerSchema).length === 1) {
|
||||
finalSchema = smallerSchema[Object.keys(smallerSchema)[0]]
|
||||
}
|
||||
return JSON.stringify(finalSchema)
|
||||
}
|
||||
|
||||
let finalSchema: typeof smallerSchema | (typeof smallerSchema)['schemaKey'] = smallerSchema
|
||||
if (dbSchema.publicOnly) {
|
||||
finalSchema = smallerSchema.public || smallerSchema.PUBLIC || smallerSchema.dbo || smallerSchema
|
||||
} else if (lang === 'mysql' && Object.keys(smallerSchema).length === 1) {
|
||||
finalSchema = smallerSchema[Object.keys(smallerSchema)[0]]
|
||||
}
|
||||
return JSON.stringify(finalSchema)
|
||||
}
|
||||
|
||||
export async function stringifyGraphqlSchema(schema: unknown): Promise<string> {
|
||||
const { buildClientSchema, printSchema } = await import('graphql')
|
||||
return printSchema(buildClientSchema(schema as IntrospectionQuery))
|
||||
}
|
||||
|
||||
function addDBSChema(scriptOptions: CopilotOptions, prompt: string) {
|
||||
|
||||
@@ -17,8 +17,6 @@ export { sendUserToast }
|
||||
import type { AnyMeltElement } from '@melt-ui/svelte'
|
||||
import type { TriggerKind } from './components/triggers'
|
||||
import { stateSnapshot } from './svelte5Utils.svelte'
|
||||
import { validate, dereference } from '@scalar/openapi-parser'
|
||||
|
||||
export namespace OpenApi {
|
||||
export enum OpenApiVersion {
|
||||
V2,
|
||||
@@ -59,6 +57,7 @@ export namespace OpenApi {
|
||||
* @throws Will throw an error if the specification is invalid or cannot be parsed.
|
||||
*/
|
||||
export async function parse(api: string): Promise<[OpenAPI.Document, OpenApiVersion]> {
|
||||
const { validate, dereference } = await import('@scalar/openapi-parser')
|
||||
const { valid, errors } = await validate(api)
|
||||
|
||||
if (!valid) {
|
||||
|
||||
Reference in New Issue
Block a user