asasvirtuais 0.1.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.
Files changed (86) hide show
  1. package/README.md +78 -0
  2. package/actions/draw.ts +110 -0
  3. package/components/OAuthCard.tsx +346 -0
  4. package/components/icons.tsx +11 -0
  5. package/components/markdown.tsx +18 -0
  6. package/components/stack/list.tsx +21 -0
  7. package/components/stack/menu.tsx +40 -0
  8. package/components/stack/nav.tsx +39 -0
  9. package/components/table/fixed.tsx +59 -0
  10. package/components/table/key-value.tsx +19 -0
  11. package/components/ui/color-mode.tsx +108 -0
  12. package/components/ui/provider.tsx +15 -0
  13. package/components/ui/toaster.tsx +43 -0
  14. package/components/ui/tooltip.tsx +46 -0
  15. package/hooks/useBoolean.tsx +11 -0
  16. package/hooks/useForwardAs.tsx +29 -0
  17. package/hooks/useHash copy.tsx +27 -0
  18. package/hooks/useHash.tsx +27 -0
  19. package/hooks/useIsMobile.tsx +6 -0
  20. package/hooks/useOAuthTokens.ts +97 -0
  21. package/hooks/useOpenRouterModels.ts +80 -0
  22. package/lib/auth0.ts +11 -0
  23. package/lib/blob.ts +3 -0
  24. package/lib/client-token-storage.ts +216 -0
  25. package/lib/oauth-tokens.ts +85 -0
  26. package/lib/react/context.tsx +20 -0
  27. package/lib/react/index.ts +1 -0
  28. package/lib/tools.ts +375 -0
  29. package/next-env.d.ts +5 -0
  30. package/next.config.ts +23 -0
  31. package/package.json +72 -0
  32. package/packages/blob.ts +97 -0
  33. package/packages/chat/components/chat/feed/index.tsx +76 -0
  34. package/packages/chat/components/chat/feed/story.tsx +18 -0
  35. package/packages/chat/components/chat/index.tsx +16 -0
  36. package/packages/chat/components/chat/story.tsx +74 -0
  37. package/packages/chat/components/debug/index.tsx +54 -0
  38. package/packages/chat/components/header/index.tsx +14 -0
  39. package/packages/chat/components/header/menu/index.tsx +63 -0
  40. package/packages/chat/components/header/story.tsx +33 -0
  41. package/packages/chat/components/header/title/index.tsx +35 -0
  42. package/packages/chat/components/index.ts +13 -0
  43. package/packages/chat/components/input/index.tsx +17 -0
  44. package/packages/chat/components/input/menu/index.tsx +35 -0
  45. package/packages/chat/components/input/send.tsx +21 -0
  46. package/packages/chat/components/input/story.tsx +35 -0
  47. package/packages/chat/components/input/textarea/index.tsx +20 -0
  48. package/packages/chat/components/message/file.tsx +103 -0
  49. package/packages/chat/components/message/menu/index.tsx +26 -0
  50. package/packages/chat/components/message/story.tsx +49 -0
  51. package/packages/chat/components/messages/index.tsx +23 -0
  52. package/packages/chat/components/messages/story.tsx +11 -0
  53. package/packages/chat/components/ui/prose.tsx +263 -0
  54. package/packages/chat/edit-message.tsx +49 -0
  55. package/packages/chat/header.tsx +118 -0
  56. package/packages/chat/index.ts +14 -0
  57. package/packages/chat/input.tsx +89 -0
  58. package/packages/chat/message-menu.tsx +57 -0
  59. package/packages/chat/message.tsx +44 -0
  60. package/packages/chat/messages.tsx +44 -0
  61. package/packages/chat/model-selector.tsx +172 -0
  62. package/packages/chat/scenarios.tsx +68 -0
  63. package/packages/chat/settings.tsx +98 -0
  64. package/packages/chat/temperature-slider.tsx +67 -0
  65. package/packages/chat/tool-results.tsx +32 -0
  66. package/packages/crud/core.ts +75 -0
  67. package/packages/crud/fetcher.ts +64 -0
  68. package/packages/crud/index.ts +2 -0
  69. package/packages/crud/next.ts +128 -0
  70. package/packages/crud/react.tsx +365 -0
  71. package/packages/env.ts +8 -0
  72. package/packages/fields.tsx +157 -0
  73. package/packages/firebase.ts +13 -0
  74. package/packages/firestore.ts +51 -0
  75. package/packages/form.tsx +66 -0
  76. package/packages/next.ts +64 -0
  77. package/packages/openrouter.ts +4 -0
  78. package/packages/react/context.tsx +21 -0
  79. package/packages/react/crud.tsx +372 -0
  80. package/packages/react/hooks.ts +90 -0
  81. package/packages/react/store.tsx +20 -0
  82. package/packages/replit-db.ts +219 -0
  83. package/packages/wretch.ts +22 -0
  84. package/packages/yaml.ts +163 -0
  85. package/pnpm-workspace.yaml +4 -0
  86. package/server/db.ts +15 -0
@@ -0,0 +1,64 @@
1
+ import { ReactNode } from 'react'
2
+ import { ImageResponse } from 'next/og'
3
+ import { NextRequest, NextResponse } from 'next/server'
4
+ import { parse } from 'search-params'
5
+
6
+ type NextRouteProps<Params = {}> = {request: NextRequest} & Params
7
+ type NextRouteHandler<Params = {}> = (props: NextRouteProps<Params>) => Promise<NextResponse<any> | Response | ImageResponse | object | unknown>
8
+ type NextLayoutHandler<SP = {}> = (props: SP) => Promise<ReactNode>
9
+ type NextPageHandler<Params = {}> = (params: Params) => Promise<ReactNode>
10
+
11
+ export const route = <P = {}>(handler: NextRouteHandler<P>) : any => (
12
+ async (request: NextRequest, { params: promise }: { params: Promise<P> } ) => {
13
+ const params = await promise
14
+ const query = parse(request.nextUrl.search)
15
+ return handler({request, ...params, ...query})
16
+ .then(
17
+ response => {
18
+ if (response instanceof NextResponse)
19
+ return response
20
+ else if (response instanceof Response)
21
+ return response
22
+ else if (response instanceof ImageResponse)
23
+ return response
24
+ return NextResponse.json(response)
25
+ }
26
+ )
27
+ .catch(
28
+ error => {
29
+ console.error(error, request, params)
30
+ return NextResponse.json({
31
+ request: JSON.stringify(request),
32
+ params,
33
+ error: {
34
+ name: error.name,
35
+ message: error.message,
36
+ cause: error.cause,
37
+ stack: error.stack,
38
+ },
39
+ }, { url: request.url, status: 500 })
40
+ }
41
+ )
42
+ }
43
+ )
44
+
45
+ export const layout = <SlotsAndParams = {}>( handler: NextLayoutHandler<SlotsAndParams & { children: React.ReactNode }> ): any => (
46
+ async ({params, ...slots}: { params: Promise<any>, children: ReactNode }) => (
47
+ handler({ ...slots, ...(params ? await params : {}) } as SlotsAndParams & { children: React.ReactNode })
48
+ )
49
+ )
50
+ export const page = <Params = {}>( handler: NextPageHandler<Params>): any => (
51
+ async ({params, searchParams}: { params: Promise<any>, searchParams: Promise<any> }) => handler({
52
+ ...(await params), ...(await searchParams)
53
+ })
54
+ )
55
+ export const redirect = (url: string, auth?: string) => (
56
+ new NextResponse(null, {
57
+ status: 302,
58
+ headers: {
59
+ Location: url,
60
+ ...(auth ? { Authorization: auth } : {})
61
+ }
62
+ })
63
+ )
64
+
@@ -0,0 +1,4 @@
1
+ import { createOpenRouter } from '@openrouter/ai-sdk-provider'
2
+ const openrouter = createOpenRouter({ apiKey: process.env.OPENROUTER_API_KEY })
3
+
4
+ export default openrouter
@@ -0,0 +1,21 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+
5
+ export function createContextFromHook<Props, Result>(useHook: (props: Props) => Result) {
6
+
7
+ const Context = React.createContext<Result | undefined>(undefined)
8
+
9
+ function Provider( { children, ...props}: React.PropsWithChildren<Props> ) {
10
+
11
+ const value = useHook(props as Props) as Result
12
+
13
+ return <Context.Provider value={value}>{ children }</Context.Provider>
14
+ }
15
+
16
+ function useContext() {
17
+ return React.useContext(Context) as Result
18
+ }
19
+
20
+ return [Provider, useContext] as const
21
+ }
@@ -0,0 +1,372 @@
1
+ "use client"
2
+ import { z } from "zod"
3
+ import {
4
+ useState,
5
+ useCallback,
6
+ useEffect,
7
+ useMemo,
8
+ createContext,
9
+ useContext,
10
+ } from "react"
11
+ import { TableInterface, ListProps } from "@/packages/crud"
12
+ import { createContextFromHook } from "./context"
13
+ import { useIndex } from "./hooks"
14
+ import { FieldsProvider, useFields } from "@/packages/fields"
15
+ import { FormProvider, useForm, useFormProvider } from "@/packages/form"
16
+
17
+ export function database<
18
+ Database extends Record<
19
+ string,
20
+ { readable: z.SomeZodObject; writable: z.SomeZodObject }
21
+ >
22
+ >(
23
+ database: Database,
24
+ {
25
+ find,
26
+ create,
27
+ update,
28
+ remove,
29
+ list,
30
+ }: TableInterface<
31
+ z.infer<Database[keyof Database]["readable"]>,
32
+ z.infer<Database[keyof Database]["writable"]>
33
+ >
34
+ ) {
35
+ type TableKey = keyof Database & string
36
+
37
+ function useTableProvider<Table extends TableKey>({
38
+ table,
39
+ asAbove,
40
+ }: {
41
+ table: Table
42
+ asAbove?: Record<string, z.infer<Database[Table]["readable"]>>
43
+ }) {
44
+ type Readable = z.infer<Database[Table]["readable"]>
45
+ type Writable = z.infer<Database[Table]["writable"]>
46
+
47
+ const index = useIndex<Readable>({ ...(asAbove ?? {}) })
48
+
49
+ const array = useMemo(
50
+ () => Object.values(index.index) as Readable[],
51
+ [index.index]
52
+ )
53
+
54
+ useEffect(function soBelow() {
55
+ index.setIndex((prev) => ({ ...prev, ...asAbove }))
56
+ }, [])
57
+
58
+ const methods = { find, create, update, remove, list } as TableInterface<
59
+ Readable,
60
+ Writable
61
+ >
62
+
63
+ // Create wrapped method that updates the index after successful operations
64
+ const createWithIndex = useCallback(
65
+ (async (props) => {
66
+ const result = await methods.create({ ...props, table })
67
+ if (result && (result).id) {
68
+ index.set(result as Readable)
69
+ }
70
+ return result
71
+ }) as typeof create,
72
+ [methods, table, index]
73
+ )
74
+
75
+ const updateWithIndex = useCallback(
76
+ (async (props) => {
77
+ const result = await methods.update({ ...props, table })
78
+ if (result && (result).id) {
79
+ index.set(result as Readable)
80
+ }
81
+ return result
82
+ }) as typeof update,
83
+ [methods, table, index]
84
+ )
85
+
86
+ const removeWithIndex = useCallback(
87
+ (async (props) => {
88
+ const result = await methods.remove({ ...props, table })
89
+ if (result && (result).id) {
90
+ index.remove(result as Readable)
91
+ }
92
+ return result
93
+ }) as typeof remove,
94
+ [methods, table, index]
95
+ )
96
+
97
+ const listWithIndex = useCallback(
98
+ (async (props) => {
99
+ const result = await methods.list({ ...props, table })
100
+ if (Array.isArray(result)) {
101
+ index.setIndex(
102
+ Object.fromEntries(result.map((item) => [(item).id, item]))
103
+ )
104
+ }
105
+ return result
106
+ }) as typeof list,
107
+ [methods, table, index]
108
+ )
109
+
110
+ return {
111
+ ...index,
112
+ array,
113
+ find: useMethod((props) => methods.find({ ...props, table })),
114
+ create: useMethod(createWithIndex),
115
+ update: useMethod(updateWithIndex),
116
+ remove: useMethod(removeWithIndex),
117
+ list: useMethod(listWithIndex),
118
+ }
119
+ }
120
+
121
+ function useDatabaseProvider(tables: {
122
+ [T in TableKey]: ReturnType<typeof useTableProvider<T>>
123
+ }) {
124
+ return tables
125
+ }
126
+
127
+ const [DatabaseProvider, useDatabase] =
128
+ createContextFromHook(useDatabaseProvider)
129
+
130
+ function useTable<T extends TableKey>(name: T) {
131
+ return useDatabase()[name]
132
+ }
133
+
134
+ function useSingleProvider<Table extends TableKey>({
135
+ id,
136
+ table,
137
+ }: {
138
+ id: string
139
+ table: Table
140
+ }) {
141
+ const { index, find } = useTable(table)
142
+ const [single, setSingle] = useState<z.infer<Database[Table]["readable"]>>(
143
+ () => index[id]
144
+ )
145
+ useEffect(() => {
146
+ if (!single) find.trigger({ id }).then(setSingle)
147
+ }, [])
148
+ useEffect(() => {
149
+ setSingle(index[id])
150
+ }, [index[id]])
151
+ return {
152
+ id,
153
+ single,
154
+ setSingle,
155
+ loading: find.loading,
156
+ }
157
+ }
158
+
159
+ const SingleContext = createContext<
160
+ ReturnType<typeof useSingleProvider<any>> | undefined
161
+ >(undefined)
162
+
163
+ function SingleProvider<Table extends TableKey>({
164
+ children,
165
+ ...props
166
+ }: {
167
+ id: string
168
+ table: Table
169
+ children: React.ReactNode
170
+ }) {
171
+ const value = useSingleProvider(props)
172
+ if (!value.single) return null
173
+ return (
174
+ <SingleContext.Provider value={value}>{children}</SingleContext.Provider>
175
+ )
176
+ }
177
+
178
+ const useSingle = <Table extends TableKey>() =>
179
+ useContext(SingleContext) as ReturnType<typeof useSingleProvider<Table>>
180
+
181
+ function CreateForm<
182
+ T extends TableKey
183
+ >({
184
+ table,
185
+ defaults,
186
+ onSuccess,
187
+ children,
188
+ }: {
189
+ table: T
190
+ defaults?: Partial<z.infer<Database[T]["writable"]>>
191
+ onSuccess?: (result: z.infer<Database[T]["readable"]>) => void
192
+ children: (props: ReturnType<typeof useFormProvider<z.infer<Database[T]["writable"]>, z.infer<Database[T]["readable"]>>>) => React.ReactNode
193
+ }) {
194
+ type Readable = z.infer<Database[T]["readable"]>
195
+ type Writable = z.infer<Database[T]["writable"]>
196
+
197
+ const { create } = useTable(table)
198
+
199
+ const callback = useCallback(
200
+ async (fields: Writable) => {
201
+ const result = await create.trigger({ data: fields })
202
+ if (onSuccess) onSuccess(result as Readable)
203
+ return result
204
+ },
205
+ [create, onSuccess]
206
+ )
207
+
208
+ return (
209
+ <FieldsProvider<Writable> defaults={defaults || ({} as Writable)}>
210
+ {fields => (
211
+ <FormProvider<Writable, Readable> callback={callback} data={fields.fields}>
212
+ {form => children({...form, ...fields})}
213
+ </FormProvider>
214
+ )}
215
+ </FieldsProvider>
216
+ )
217
+ }
218
+
219
+ function UpdateForm<T extends TableKey>({
220
+ table,
221
+ id,
222
+ defaults,
223
+ onSuccess,
224
+ children,
225
+ }: {
226
+ table: TableKey
227
+ id: string
228
+ defaults?: Partial<z.infer<Database[TableKey]["writable"]>>
229
+ onSuccess?: (result: z.infer<Database[TableKey]["readable"]>) => void
230
+ children: (props: ReturnType<typeof useFormProvider<z.infer<Database[T]["writable"]>, z.infer<Database[T]["readable"]>>>) => React.ReactNode
231
+ }) {
232
+ type Readable = z.infer<Database[T]["readable"]>
233
+ type Writable = z.infer<Database[T]["writable"]>
234
+
235
+ const { update } = useTable(table)
236
+
237
+ const callback = useCallback(
238
+ async (fields: Partial<Writable>) => {
239
+ const result = await update.trigger({ id, data: fields })
240
+ if (onSuccess) onSuccess(result as Readable)
241
+ return result
242
+ },
243
+ [update, id, onSuccess]
244
+ )
245
+
246
+ return (
247
+ <FieldsProvider<Partial<Writable>>
248
+ defaults={defaults || ({} as Partial<Writable>)}
249
+ >
250
+ {fields => (
251
+ <FormProvider<Partial<Writable>, Readable> callback={callback} data={fields.fields}>
252
+ {form => children({...form, ...fields})}
253
+ </FormProvider>
254
+ )}
255
+ </FieldsProvider>
256
+ )
257
+ }
258
+
259
+ function FilterForm<T extends TableKey>({
260
+ table,
261
+ defaults,
262
+ onSuccess,
263
+ children,
264
+ }: {
265
+ table: T
266
+ defaults?: Partial<ListProps<z.infer<Database[T]["readable"]>>>
267
+ onSuccess?: (result: z.infer<Database[T]["readable"]>[]) => void
268
+ children: (props: ReturnType<typeof useFormProvider<z.infer<Database[T]["writable"]>, z.infer<Database[T]["readable"]>>>) => React.ReactNode
269
+ }) {
270
+ type Readable = z.infer<Database[T]["readable"]>
271
+ type Writable = z.infer<Database[T]["writable"]>
272
+
273
+ const { list } = useTable(table)
274
+
275
+ const callback = useCallback(
276
+ async (fields: Omit<ListProps<Readable>, "table">) => {
277
+ const result = await list.trigger(fields)
278
+ if (onSuccess) onSuccess(result)
279
+ return result
280
+ },
281
+ [list, onSuccess]
282
+ )
283
+
284
+ return (
285
+ <FieldsProvider<ListProps<Readable>>
286
+ defaults={(defaults || {}) as ListProps<Readable>}
287
+ >
288
+ {fields => (
289
+ <FormProvider<ListProps<Readable>, Readable[]> callback={callback} data={fields.fields}>
290
+ {form => children({...form, ...fields})}
291
+ </FormProvider>
292
+ )}
293
+ </FieldsProvider>
294
+ )
295
+ }
296
+
297
+ const useCreateForm = <T extends TableKey>(table: T) => {
298
+ return {
299
+ ...useFields<z.infer<Database[T]["writable"]>>(),
300
+ ...useForm<
301
+ z.infer<Database[T]["writable"]>,
302
+ z.infer<Database[T]["readable"]>
303
+ >(),
304
+ }
305
+ }
306
+ const useUpdateForm = <T extends TableKey>(table: T) => {
307
+ return {
308
+ ...useFields<Partial<z.infer<Database[T]["writable"]>>>(),
309
+ ...useForm<
310
+ Partial<z.infer<Database[T]["writable"]>>,
311
+ z.infer<Database[T]["readable"]>
312
+ >(),
313
+ }
314
+ }
315
+ const useFiltersForm = <T extends TableKey>(table: T) => {
316
+ return {
317
+ ...useFields<ListProps<z.infer<Database[T]["readable"]>>>(),
318
+ ...useForm<
319
+ ListProps<z.infer<Database[T]["readable"]>>,
320
+ z.infer<Database[T]["readable"]>[]
321
+ >(),
322
+ }
323
+ }
324
+
325
+ return {
326
+ DatabaseProvider,
327
+ useDatabase,
328
+ useTable,
329
+ useTableProvider,
330
+ SingleProvider,
331
+ useSingle,
332
+ CreateForm,
333
+ UpdateForm,
334
+ FilterForm,
335
+ useCreateForm,
336
+ useUpdateForm,
337
+ useFiltersForm,
338
+ }
339
+ }
340
+
341
+ function useMethod<Fn extends (props: any) => Promise<any>>(method: Fn) {
342
+ const [loading, setLoading] = useState(false)
343
+ const [error, setError] = useState<Error | null>(null)
344
+ const [result, setResult] = useState<Awaited<ReturnType<Fn>>>()
345
+
346
+ const trigger = useCallback(
347
+ (async (props) => {
348
+ if (loading) return
349
+ setLoading(true)
350
+ setError(null)
351
+ try {
352
+ const data = await method(props)
353
+ setResult(data)
354
+ return data
355
+ } catch (err) {
356
+ console.error("CRUD operation failed:", err)
357
+ setError(err as Error)
358
+ throw err
359
+ } finally {
360
+ setLoading(false)
361
+ }
362
+ }) as typeof method,
363
+ [method, loading]
364
+ )
365
+
366
+ return {
367
+ trigger,
368
+ loading,
369
+ error,
370
+ result,
371
+ }
372
+ }
@@ -0,0 +1,90 @@
1
+ 'use client'
2
+
3
+ import { useCallback, useEffect, useMemo, useState } from 'react'
4
+
5
+ export function useAction<Props, Result, Defaults = Partial<Props>>(action: (props: Props) => Promise<Result>, {
6
+ onSuccess,
7
+ autoTrigger,
8
+ ...props
9
+ } : {
10
+ defaults?: Defaults
11
+ onSuccess?: (result: Result, props?: Props) => void
12
+ autoTrigger?: boolean
13
+ } = {}) {
14
+ const [loading, setLoading] = useState<boolean>(false)
15
+ const [error, setError] = useState()
16
+ const [result, setResult] = useState<Result>()
17
+ const [defaults, setDefaults] = useState<Defaults>(props.defaults ?? {} as Defaults)
18
+
19
+ const trigger = useCallback(async (props: Omit<Props, keyof Defaults>): Promise<Result> => {
20
+ try {
21
+ setLoading(true)
22
+ const result = await action({
23
+ ...props,
24
+ ...defaults,
25
+ } as Props)
26
+
27
+ setResult(result)
28
+ if (onSuccess)
29
+ onSuccess(result)
30
+ return result
31
+
32
+ } catch (error) {
33
+ // @ts-expect-error
34
+ setError(error)
35
+ throw error
36
+ } finally {
37
+ setLoading(false)
38
+ }
39
+ }, [defaults, onSuccess, loading, setLoading])
40
+
41
+ useEffect(() => {
42
+ if (autoTrigger)
43
+ trigger(props as Omit<Props, keyof Defaults>)
44
+ }, [])
45
+
46
+ return {
47
+ trigger,
48
+ loading,
49
+ error,
50
+ result,
51
+ defaults,
52
+ setDefaults,
53
+ }
54
+ }
55
+
56
+ export function useIndex<T>(value: Record<string, any>) {
57
+
58
+ type readable = T
59
+
60
+ const [index, setIndex] = useState<Record<string, T>>(() => value)
61
+
62
+ const array = useMemo(() => Object.values(index) as readable[], [index])
63
+
64
+ const set = useCallback((...params: readable[]) => {
65
+ setIndex(prev => ({
66
+ ...prev,
67
+ ...Object.fromEntries(params.map(data => ([(data as readable & { id: string }).id, data])))
68
+ }))
69
+ }, [])
70
+
71
+ const remove = useCallback((...params: readable[]) => {
72
+ setIndex(prev => {
73
+ const newState = { ...prev }
74
+ for ( const data of params ) {
75
+ const id = (data as readable & { id: string }).id
76
+ if (newState[id])
77
+ delete newState[id]
78
+ }
79
+ return newState
80
+ })
81
+ }, [])
82
+
83
+ return {
84
+ index,
85
+ array,
86
+ set,
87
+ setIndex,
88
+ remove,
89
+ }
90
+ }
@@ -0,0 +1,20 @@
1
+ 'use client'
2
+
3
+ import { useIndex } from './hooks'
4
+ import { createContextFromHook } from './context'
5
+
6
+ type StoreProps<T> = {
7
+ [table: string]: (T & { id: string })[]
8
+ }
9
+
10
+ function useStoreProvider<T>(props : StoreProps<T>) {
11
+ return Object.fromEntries(
12
+ Object.entries(props).map(
13
+ ([table, initial]) => [table, useIndex<T>({ initial: initial as T & { id: string }[] })]
14
+ )
15
+ ) as {
16
+ [table: string]: ReturnType<typeof useIndex<T>>
17
+ }
18
+ }
19
+
20
+ export const [StoreProvider, useStore] = createContextFromHook(useStoreProvider<any>)