better frontend demo, dropped motion dep, qtext param is now query

This commit is contained in:
dab 2025-05-07 09:44:26 -05:00
parent 8c6f336cad
commit d263c74c9d
4 changed files with 87 additions and 56 deletions

View file

@ -1,4 +1,4 @@
import React, { StrictMode, useState } from 'react' import React, { StrictMode, useState, useMemo } from 'react'
import { createRoot } from 'react-dom/client' import { createRoot } from 'react-dom/client'
@ -6,47 +6,89 @@ import { useUnstrictEffect as useEffect } from './useUnstrictEffect'
const ApiTest = function ({ path, method, params }) { const ApiTest = function ({ path, method, params }) {
const [ submit_enabled, setSubmitEnabled ] = useState(true)
const [ result, setResult ] = useState(null) const [ result, setResult ] = useState(null)
useEffect(() => { const func_click_submit = useMemo(() => {
let endpoint_full
let body
if (method === 'GET') {
endpoint_full = path + '?' + new URLSearchParams({
p: JSON.stringify(params),
}).toString()
}
else if (method === 'POST') {
endpoint_full = path
body = JSON.stringify(params)
}
else {
throw `bad method : ${method}`
}
fetch(endpoint_full, { method, body }).then(async (resp) => {
const resp_json = await resp.json()
setResult(resp_json)
return
})
return () => { return () => {
setSubmitEnabled(false)
let endpoint_full
let body
if (method === 'GET') {
endpoint_full = path + '?' + new URLSearchParams({
p: JSON.stringify(params),
}).toString()
}
else if (method === 'POST') {
endpoint_full = path
body = JSON.stringify(params)
}
else {
throw `bad method : ${method}`
}
fetch(endpoint_full, { method, body }).then(async (resp) => {
const resp_json = await resp.json()
setResult(resp_json)
return
}).catch(console.error).finally(() => {
setSubmitEnabled(true)
return
})
return return
} }
}, []) }, [])
const jsx_btn_submit = (<button disabled={submit_enabled === false} onClick={func_click_submit}>{'do request'}</button>)
return ( return (
<div> <div>
{JSON.stringify(result)} <div style={{ fontSize: `${2.5*8}px`, fontWeight: 'bold', padding: `8px` }}>{'Input'}</div>
<div style={{ whiteSpace: 'pre-wrap' }}>
{JSON.stringify({ path, method, params }, null, 2)}
</div>
<div style={{height: `${2*8}px` }} />
{jsx_btn_submit}
<div style={{height: `${2*8}px` }} />
<div style={{ fontSize: `${2.5*8}px`, fontWeight: 'bold', padding: `8px` }}>{'Output'}</div>
<div style={{ whiteSpace: 'pre-wrap' }}>
{JSON.stringify(result, null, 2)}
</div>
</div>
)
}
const HEIGHT_PANEL_HEADER = `${8*8}px`
const DemoStash = function () {
return (
<div style={{
position: 'absolute', top: '0px', left: '0px', right: '0px', bottom: '0px',
}}>
<div style={{ height: HEIGHT_PANEL_HEADER, fontSize: `${3 * 8}px`, fontWeight: 'bold', padding: `${2*8}px` }}>{'/stash'}</div>
<div style={{ position: 'absolute', top: HEIGHT_PANEL_HEADER, left: '0px', bottom: '0px', right: '0px', overflow: 'auto' }}>
<ApiTest path={'/stash'} method={'POST'} params={{ collection_name: 'misc', documents: ['hello', 'world'], wait_for_result: true }} />
</div>
</div>
)
}
const DemoSearch = function () {
return (
<div style={{
position: 'absolute', top: '0px', left: '0px', right: '0px', bottom: '0px',
}}>
<div style={{ height: HEIGHT_PANEL_HEADER, fontSize: `${3 * 8}px`, fontWeight: 'bold', padding: `${2*8}px` }}>{'/search'}</div>
<div style={{ position: 'absolute', top: HEIGHT_PANEL_HEADER, left: '0px', bottom: '0px', right: '0px', overflow: 'auto' }}>
<ApiTest path={'/search'} method={'POST'} params={{ collection_name: 'misc', query: 'hello!', limit: 10 }} />
</div>
</div> </div>
) )
} }
const App = function () { const App = function () {
//let jsx_inner = <ApiTest path={'/stash'} method={'POST'} params={{ collection_name: 'misc', documents: ['hello', 'world'], wait_for_result: true }} />
let jsx_inner = <ApiTest path={'/search'} method={'POST'} params={{ collection_name: 'misc', qtext: 'hello!', limit: 10 }} />
return ( return (
<div style={{ height: '100%', width: '100%', overflow: 'auto', backgroundColor: '#000', color: '#FFF', fontFamily: 'monospace', fontSize: `${2*8}px`, lineHeight: `${2*8}px` }}> <div style={{ height: '100%', width: '100%', overflow: 'hidden', display: 'flex', backgroundColor: '#000', color: '#FFF', fontFamily: 'monospace', fontSize: `${2*8}px`, lineHeight: `${2*8}px` }}>
{jsx_inner} <div style={{flex: '0 0 50%', position: 'relative', border: '1px solid #EEE', boxSizing: 'border-box'}}><DemoStash /></div>
<div style={{flex: '0 0 50%', position: 'relative', border: '1px solid #EEE', boxSizing: 'border-box'}}><DemoSearch /></div>
</div> </div>
) )
} }

View file

@ -3,27 +3,16 @@
"workspaces": { "workspaces": {
"": { "": {
"dependencies": { "dependencies": {
"motion": "^12.9.7",
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
}, },
}, },
}, },
"packages": { "packages": {
"framer-motion": ["framer-motion@12.9.7", "", { "dependencies": { "motion-dom": "^12.9.6", "motion-utils": "^12.9.4", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Eo5TYU6sEPPy82GDx32PJm++G+AkBCrzxtEQOWLnpQX896Q3LFrsYhMZ5YO5ct4wL7wyHU6hqlrpYXeexKAevg=="],
"motion": ["motion@12.9.7", "", { "dependencies": { "framer-motion": "^12.9.7", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Vh5NJxec7lZ4iNZXEhdweJpKwP2gjgevL/4Dx+dfMc7ABPMnLJaBUkz91TG/ZONhz/GUAy0Mw3Xd5rYtnxNRmw=="],
"motion-dom": ["motion-dom@12.9.6", "", { "dependencies": { "motion-utils": "^12.9.4" } }, "sha512-IK9pm5zU8BIp3FCoUGF3T7AHVLVOlXxlwco/bIbcnpBtyYb2gDQhdOzUh2KSDJVjYl1MZ9vdq8tnFTTahX2lfg=="],
"motion-utils": ["motion-utils@12.9.4", "", {}, "sha512-BW3I65zeM76CMsfh3kHid9ansEJk9Qvl+K5cu4DVHKGsI52n76OJ4z2CUJUV+Mn3uEP9k1JJA3tClG0ggSrRcg=="],
"react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="], "react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
"react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="], "react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="],
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
} }
} }

View file

@ -1,6 +1,5 @@
{ {
"dependencies": { "dependencies": {
"motion": "^12.9.7",
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0" "react-dom": "^19.1.0"
} }

View file

@ -47,7 +47,7 @@ const get_siteroot_html = function () {return `
const get_siteroot_js = async () => { const get_siteroot_js = async () => {
const { stdout } = await execFile("/home/user/bun-linux-x64/bun", ["build", "index.js"], { cwd: '/home/user/mount/bunapp', encoding : 'utf8' }) const { stdout } = await execFile('/home/user/bun-linux-x64/bun', ['build', 'index.js'], { cwd: '/home/user/mount/bunapp', encoding : 'utf8' })
const str_output = stdout.trim() const str_output = stdout.trim()
return str_output return str_output
} }
@ -78,20 +78,21 @@ const async_get_embeddings_for_model = async (model_key, documents) => {
const async_get_request_body = (req) => { const async_get_request_body = (req) => {
return new Promise((resolve) => { return new Promise((resolve) => {
const lst_chunks = [] const lst_chunks = []
req.on("data", function (chunk) { req.on('data', function (chunk) {
lst_chunks.push(chunk) lst_chunks.push(chunk)
}) return
req.on("end", function () { })
const all_bytes = [] req.on('end', function () {
for (let chunk of lst_chunks) { const all_bytes = []
for (let int_byte of chunk) { for (let chunk of lst_chunks) {
all_bytes.push(int_byte) for (let int_byte of chunk) {
all_bytes.push(int_byte)
}
} }
} resolve(new Uint8Array(all_bytes))
resolve(new Uint8Array(all_bytes)) return
return })
})
return return
}) })
} }
@ -198,9 +199,9 @@ const ensure_collection_loaded = async (internal_collectionname) => {
const get_searchresults_from_params = async (j_params) => { const get_searchresults_from_params = async (j_params) => {
const { qtext, collection_name, limit } = j_params const { query, collection_name, limit } = j_params
const async_getresult = async (model_key) => { const async_getresult = async (model_key) => {
const embed_result = await async_get_embeddings_for_model(model_key, [ qtext ]) const embed_result = await async_get_embeddings_for_model(model_key, [ query ])
const vector = embed_result[0].embedding[0] const vector = embed_result[0].embedding[0]
const internal_collectionname = get_modelkey_from_original(collection_name, model_key) const internal_collectionname = get_modelkey_from_original(collection_name, model_key)
await ensure_collection_loaded(internal_collectionname) await ensure_collection_loaded(internal_collectionname)