feat: ditch triplit, move to postgresql + drizzle orm
This commit is contained in:
+143
-47
@@ -1,54 +1,37 @@
|
||||
import type { Entity } from '@triplit/client';
|
||||
import type schema from '#triplit/schema';
|
||||
import { nanoid } from 'nanoid';
|
||||
import * as schema from '~~/drizzle/schema';
|
||||
|
||||
type Provider = Entity<typeof schema, 'providers'>;
|
||||
type Model = Entity<typeof schema, 'models'>;
|
||||
export type Model = typeof schema.models.$inferSelect;
|
||||
export type Provider = typeof schema.providers.$inferSelect;
|
||||
|
||||
export interface ModelWithProvider extends Model {
|
||||
provider: Provider;
|
||||
}
|
||||
|
||||
export interface ProviderWithModels extends Provider {
|
||||
export type ProviderWithModels = Provider & {
|
||||
models: Model[];
|
||||
}
|
||||
};
|
||||
|
||||
export const useModels = () => {
|
||||
const nuxtApp = useNuxtApp();
|
||||
const triplit = useTriplitClient();
|
||||
export type ModelWithProvider = Model & {
|
||||
provider: Provider;
|
||||
};
|
||||
|
||||
if (!nuxtApp._modelsState) {
|
||||
nuxtApp._modelsState = {
|
||||
providers: shallowRef([]),
|
||||
isReady: ref(false)
|
||||
};
|
||||
}
|
||||
export const useModels = async () => {
|
||||
const providers = useState<ProviderWithModels[]>('models_state', () => []);
|
||||
const loaded = useState('models_loaded', () => false);
|
||||
|
||||
|
||||
const state = nuxtApp._modelsState as {
|
||||
providers: Ref<ProviderWithModels[]>;
|
||||
initPromise: Promise<void> | null;
|
||||
};
|
||||
|
||||
const init = (): Promise<void> => {
|
||||
if (state.initPromise) return state.initPromise;
|
||||
|
||||
state.initPromise = (async () => {
|
||||
const query = triplit.query('providers').Include('models');
|
||||
|
||||
const { results } = await useQuery('providers', triplit, query)
|
||||
watch(results, (newProviders) => {
|
||||
if (newProviders && newProviders.length > 0) {
|
||||
state.providers.value = newProviders as unknown as ProviderWithModels[];
|
||||
}
|
||||
}, { immediate: true, flush: 'sync' });
|
||||
})();
|
||||
|
||||
return state.initPromise;
|
||||
};
|
||||
const { refresh } = await useFetch<ProviderWithModels[]>('/api/providers', {
|
||||
key: 'models_request',
|
||||
immediate: !loaded.value,
|
||||
onRequest() {
|
||||
loaded.value = true;
|
||||
},
|
||||
onResponse({ response }) {
|
||||
if (response.ok) {
|
||||
providers.value = response._data ?? [];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const allModels = computed<ModelWithProvider[]>(() => {
|
||||
const result: ModelWithProvider[] = [];
|
||||
for (const provider of state.providers.value) {
|
||||
for (const provider of providers.value) {
|
||||
if (!provider.enabled) continue;
|
||||
for (const model of provider.models || []) {
|
||||
if (!model.enabled) continue;
|
||||
@@ -63,19 +46,132 @@ export const useModels = () => {
|
||||
};
|
||||
|
||||
const getProvider = (id: string): ProviderWithModels | undefined => {
|
||||
return state.providers.value.find((provider) => provider.id === id);
|
||||
return providers.value.find((provider) => provider.id === id);
|
||||
};
|
||||
|
||||
const getFirstAvailableModel = () => {
|
||||
return allModels.value[0] ?? null;
|
||||
};
|
||||
|
||||
const createModel = async (model: Model) => {
|
||||
model.id = nanoid();
|
||||
await $fetch(`/api/model`, {
|
||||
method: 'POST',
|
||||
body: model,
|
||||
onRequest() {
|
||||
providers.value = providers.value.map(p => ({
|
||||
...p,
|
||||
models: p.id === model.providerId ? [...p.models, model] : p.models
|
||||
}));
|
||||
},
|
||||
onResponseError() {
|
||||
providers.value = providers.value.map(p => ({
|
||||
...p,
|
||||
models: p.id === model.providerId ? p.models.filter(m => m.id !== model.id) : p.models
|
||||
}));
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const updateModel = async (id: string, updates: Partial<Model>) => {
|
||||
const model = providers.value.find(p => p.models.find(m => m.id === id));
|
||||
if (!model) return;
|
||||
|
||||
const original = model;
|
||||
|
||||
await $fetch(`/api/model/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: updates,
|
||||
onRequest() {
|
||||
providers.value = providers.value.map(p => ({
|
||||
...p,
|
||||
models: p.models.map(m =>
|
||||
m.id === id ? { ...m, ...updates } : m
|
||||
)
|
||||
}));
|
||||
},
|
||||
onRequestError() {
|
||||
providers.value = providers.value.map(p => ({
|
||||
...p,
|
||||
models: p.models.map(m =>
|
||||
m.id === id ? original : m
|
||||
)
|
||||
}) as ProviderWithModels);
|
||||
},
|
||||
onResponseError() {
|
||||
providers.value = providers.value.map(p => ({
|
||||
...p,
|
||||
models: p.models.map(m =>
|
||||
m.id === id ? original : m
|
||||
)
|
||||
}) as ProviderWithModels);
|
||||
},
|
||||
// async onResponse() {
|
||||
// await refresh();
|
||||
// }
|
||||
});
|
||||
};
|
||||
|
||||
const deleteModel = async (id: string) => {
|
||||
const model = providers.value.find(p => p.models.find(m => m.id === id));
|
||||
if (!model) return;
|
||||
|
||||
await $fetch(`/api/model/${id}`, {
|
||||
method: 'DELETE',
|
||||
onRequest() {
|
||||
providers.value = providers.value.map(p => ({
|
||||
...p,
|
||||
models: p.models.filter(m => m.id !== id)
|
||||
}));
|
||||
},
|
||||
onResponseError() {
|
||||
providers.value.push(model);
|
||||
},
|
||||
async onResponse() {
|
||||
await refresh();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const updateProvider = async (id: string, updates: Partial<Provider>) => {
|
||||
const provider = providers.value.find(p => p.id === id);
|
||||
if (!provider) return;
|
||||
|
||||
const original = provider;
|
||||
|
||||
await $fetch(`/api/provider/${id}`, {
|
||||
method: 'PATCH',
|
||||
body: updates,
|
||||
onRequest() {
|
||||
providers.value = providers.value.map(p =>
|
||||
p.id === id ? { ...p, ...updates } : p
|
||||
);
|
||||
},
|
||||
onRequestError() {
|
||||
providers.value = providers.value.map(p =>
|
||||
p.id === id ? original : p
|
||||
);
|
||||
},
|
||||
onResponseError() {
|
||||
providers.value = providers.value.map(p =>
|
||||
p.id === id ? original : p
|
||||
);
|
||||
},
|
||||
async onResponse() {
|
||||
await refresh();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init,
|
||||
providers: state.providers,
|
||||
providers,
|
||||
allModels,
|
||||
getModel,
|
||||
getProvider,
|
||||
getFirstAvailableModel
|
||||
getFirstAvailableModel,
|
||||
createModel,
|
||||
updateModel,
|
||||
updateProvider,
|
||||
deleteModel
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user