@tscircuit/fake-snippets 0.0.82 → 0.0.83
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.
- package/bun-tests/fake-snippets-api/routes/package_releases/create.test.ts +3 -3
- package/dist/bundle.js +38 -10
- package/dist/index.d.ts +24 -4
- package/dist/index.js +5 -1
- package/dist/schema.d.ts +37 -5
- package/dist/schema.js +5 -1
- package/fake-snippets-api/lib/db/schema.ts +5 -1
- package/fake-snippets-api/lib/public-mapping/public-map-package-release.ts +14 -1
- package/fake-snippets-api/routes/api/package_releases/get.ts +11 -3
- package/fake-snippets-api/routes/api/package_releases/list.ts +8 -1
- package/package.json +1 -1
- package/src/App.tsx +0 -2
- package/src/components/PackageBuildsPage/package-build-header.tsx +14 -2
- package/src/components/ViewPackagePage/hooks/use-toast.tsx +70 -0
- package/src/components/dialogs/{import-snippet-dialog.tsx → import-package-dialog.tsx} +25 -24
- package/src/components/package-port/CodeEditorHeader.tsx +7 -6
- package/src/components/ui/toaster.tsx +1 -33
- package/src/hooks/use-current-package-release.ts +10 -1
- package/src/hooks/use-package-release.ts +15 -14
- package/src/hooks/use-toast.tsx +50 -169
- package/src/pages/view-package.tsx +1 -0
- package/src/components/ViewPackagePage/hooks/use-toast.ts +0 -191
|
@@ -4,6 +4,7 @@ import { usePackageRelease } from "./use-package-release"
|
|
|
4
4
|
import { useUrlParams } from "./use-url-params"
|
|
5
5
|
|
|
6
6
|
export const useCurrentPackageRelease = (options?: {
|
|
7
|
+
include_ai_review?: boolean
|
|
7
8
|
include_logs?: boolean
|
|
8
9
|
refetchInterval?: number
|
|
9
10
|
}) => {
|
|
@@ -26,9 +27,17 @@ export const useCurrentPackageRelease = (options?: {
|
|
|
26
27
|
query = { package_id: packageId, is_latest: true }
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
if (query && options?.include_logs !== undefined) {
|
|
31
|
+
query.include_logs = options.include_logs
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (query && options?.include_ai_review !== undefined) {
|
|
35
|
+
query.include_ai_review = options.include_ai_review
|
|
36
|
+
}
|
|
37
|
+
|
|
29
38
|
const { data: packageRelease, ...rest } = usePackageRelease(query, {
|
|
30
|
-
include_logs: options?.include_logs ?? false,
|
|
31
39
|
refetchInterval: options?.refetchInterval,
|
|
32
40
|
})
|
|
41
|
+
|
|
33
42
|
return { packageRelease, ...rest }
|
|
34
43
|
}
|
|
@@ -2,7 +2,7 @@ import type { PackageRelease } from "fake-snippets-api/lib/db/schema"
|
|
|
2
2
|
import { type UseQueryOptions, useQuery } from "react-query"
|
|
3
3
|
import { useAxios } from "./use-axios"
|
|
4
4
|
|
|
5
|
-
type PackageReleaseQuery =
|
|
5
|
+
type PackageReleaseQuery = (
|
|
6
6
|
| {
|
|
7
7
|
package_release_id: string
|
|
8
8
|
}
|
|
@@ -17,29 +17,30 @@ type PackageReleaseQuery =
|
|
|
17
17
|
package_id: string
|
|
18
18
|
is_latest: boolean
|
|
19
19
|
}
|
|
20
|
+
) & {
|
|
21
|
+
include_logs?: boolean | null | undefined
|
|
22
|
+
include_ai_review?: boolean | null | undefined
|
|
23
|
+
}
|
|
20
24
|
|
|
21
25
|
export const usePackageRelease = (
|
|
22
26
|
query: PackageReleaseQuery | null,
|
|
23
|
-
options?: {
|
|
27
|
+
options?: {
|
|
28
|
+
refetchInterval?: number
|
|
29
|
+
},
|
|
24
30
|
) => {
|
|
25
31
|
const axios = useAxios()
|
|
26
32
|
|
|
27
33
|
return useQuery<PackageRelease, Error & { status: number }>(
|
|
28
|
-
["packageRelease", query
|
|
34
|
+
["packageRelease", query],
|
|
29
35
|
async () => {
|
|
30
36
|
if (!query) return
|
|
31
37
|
|
|
32
|
-
const { data } = await axios.post(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
include_logs: true,
|
|
39
|
-
},
|
|
40
|
-
}
|
|
41
|
-
: undefined,
|
|
42
|
-
)
|
|
38
|
+
const { data } = await axios.post("/package_releases/get", query, {
|
|
39
|
+
params: {
|
|
40
|
+
include_logs: query.include_logs,
|
|
41
|
+
include_ai_review: query.include_ai_review,
|
|
42
|
+
},
|
|
43
|
+
})
|
|
43
44
|
|
|
44
45
|
if (!data.package_release) {
|
|
45
46
|
throw new Error("Package release not found")
|
package/src/hooks/use-toast.tsx
CHANGED
|
@@ -1,191 +1,72 @@
|
|
|
1
|
-
import
|
|
1
|
+
import toastLibrary, { Toaster, type Toast } from "react-hot-toast"
|
|
2
|
+
import React from "react"
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const TOAST_LIMIT = 1
|
|
6
|
-
const TOAST_REMOVE_DELAY = 1000000
|
|
7
|
-
|
|
8
|
-
export type ToasterToast = ToastProps & {
|
|
9
|
-
id: string
|
|
4
|
+
export interface ToasterToast {
|
|
10
5
|
title?: React.ReactNode
|
|
11
6
|
description?: React.ReactNode
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const actionTypes = {
|
|
16
|
-
ADD_TOAST: "ADD_TOAST",
|
|
17
|
-
UPDATE_TOAST: "UPDATE_TOAST",
|
|
18
|
-
DISMISS_TOAST: "DISMISS_TOAST",
|
|
19
|
-
REMOVE_TOAST: "REMOVE_TOAST",
|
|
20
|
-
} as const
|
|
21
|
-
|
|
22
|
-
let count = 0
|
|
23
|
-
|
|
24
|
-
function genId() {
|
|
25
|
-
count = (count + 1) % Number.MAX_SAFE_INTEGER
|
|
26
|
-
return count.toString()
|
|
7
|
+
variant?: "default" | "destructive"
|
|
8
|
+
duration?: number
|
|
27
9
|
}
|
|
28
10
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
11
|
+
function ToastContent({
|
|
12
|
+
title,
|
|
13
|
+
description,
|
|
14
|
+
variant,
|
|
15
|
+
t,
|
|
16
|
+
}: ToasterToast & { t: Toast }) {
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
className={`rounded-md border p-4 shadow-lg transition-all ${
|
|
20
|
+
t.visible
|
|
21
|
+
? "animate-in fade-in slide-in-from-top-full"
|
|
22
|
+
: "animate-out fade-out slide-out-to-right-full"
|
|
23
|
+
} ${
|
|
24
|
+
variant === "destructive"
|
|
25
|
+
? "border-red-500 bg-red-500 text-slate-50"
|
|
26
|
+
: "border-slate-200 bg-white text-slate-950 dark:bg-slate-950 dark:text-slate-50"
|
|
27
|
+
}`}
|
|
28
|
+
>
|
|
29
|
+
{title && <div className="text-sm font-semibold">{title}</div>}
|
|
30
|
+
{description && <div className="text-sm opacity-90">{description}</div>}
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
51
33
|
}
|
|
52
34
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
const toast = ({
|
|
36
|
+
duration,
|
|
37
|
+
description,
|
|
38
|
+
variant = "default",
|
|
39
|
+
title,
|
|
40
|
+
}: ToasterToast) => {
|
|
41
|
+
if (description) {
|
|
42
|
+
return toastLibrary.custom(
|
|
43
|
+
(t) => (
|
|
44
|
+
<ToastContent
|
|
45
|
+
title={title}
|
|
46
|
+
description={description}
|
|
47
|
+
variant={variant}
|
|
48
|
+
t={t}
|
|
49
|
+
/>
|
|
50
|
+
),
|
|
51
|
+
{ duration },
|
|
52
|
+
)
|
|
58
53
|
}
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
dispatch({
|
|
63
|
-
type: "REMOVE_TOAST",
|
|
64
|
-
toastId: toastId,
|
|
65
|
-
})
|
|
66
|
-
}, TOAST_REMOVE_DELAY)
|
|
67
|
-
|
|
68
|
-
toastTimeouts.set(toastId, timeout)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export const reducer = (state: State, action: Action): State => {
|
|
72
|
-
switch (action.type) {
|
|
73
|
-
case "ADD_TOAST":
|
|
74
|
-
return {
|
|
75
|
-
...state,
|
|
76
|
-
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
case "UPDATE_TOAST":
|
|
80
|
-
return {
|
|
81
|
-
...state,
|
|
82
|
-
toasts: state.toasts.map((t) =>
|
|
83
|
-
t.id === action.toast.id ? { ...t, ...action.toast } : t,
|
|
84
|
-
),
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
case "DISMISS_TOAST": {
|
|
88
|
-
const { toastId } = action
|
|
89
|
-
|
|
90
|
-
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
|
91
|
-
// but I'll keep it here for simplicity
|
|
92
|
-
if (toastId) {
|
|
93
|
-
addToRemoveQueue(toastId)
|
|
94
|
-
} else {
|
|
95
|
-
state.toasts.forEach((toast) => {
|
|
96
|
-
addToRemoveQueue(toast.id)
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return {
|
|
101
|
-
...state,
|
|
102
|
-
toasts: state.toasts.map((t) =>
|
|
103
|
-
t.id === toastId || toastId === undefined
|
|
104
|
-
? {
|
|
105
|
-
...t,
|
|
106
|
-
open: false,
|
|
107
|
-
}
|
|
108
|
-
: t,
|
|
109
|
-
),
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
case "REMOVE_TOAST":
|
|
113
|
-
if (action.toastId === undefined) {
|
|
114
|
-
return {
|
|
115
|
-
...state,
|
|
116
|
-
toasts: [],
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
return {
|
|
120
|
-
...state,
|
|
121
|
-
toasts: state.toasts.filter((t) => t.id !== action.toastId),
|
|
122
|
-
}
|
|
55
|
+
if (variant === "destructive") {
|
|
56
|
+
return toastLibrary.error(<>{title}</>, { duration })
|
|
123
57
|
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const listeners: Array<(state: State) => void> = []
|
|
127
|
-
|
|
128
|
-
let memoryState: State = { toasts: [] }
|
|
129
|
-
|
|
130
|
-
function dispatch(action: Action) {
|
|
131
|
-
memoryState = reducer(memoryState, action)
|
|
132
|
-
listeners.forEach((listener) => {
|
|
133
|
-
listener(memoryState)
|
|
134
|
-
})
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
type Toast = Omit<ToasterToast, "id">
|
|
138
58
|
|
|
139
|
-
|
|
140
|
-
const id = genId()
|
|
141
|
-
|
|
142
|
-
const update = (props: ToasterToast) =>
|
|
143
|
-
dispatch({
|
|
144
|
-
type: "UPDATE_TOAST",
|
|
145
|
-
toast: { ...props, id },
|
|
146
|
-
})
|
|
147
|
-
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
|
|
148
|
-
|
|
149
|
-
dispatch({
|
|
150
|
-
type: "ADD_TOAST",
|
|
151
|
-
toast: {
|
|
152
|
-
...props,
|
|
153
|
-
id,
|
|
154
|
-
open: true,
|
|
155
|
-
onOpenChange: (open) => {
|
|
156
|
-
if (!open) dismiss()
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
return {
|
|
162
|
-
id: id,
|
|
163
|
-
dismiss,
|
|
164
|
-
update,
|
|
165
|
-
}
|
|
59
|
+
return toastLibrary(<>{title}</>, { duration })
|
|
166
60
|
}
|
|
167
61
|
|
|
168
62
|
function useToast() {
|
|
169
|
-
const [state, setState] = React.useState<State>(memoryState)
|
|
170
|
-
|
|
171
|
-
React.useEffect(() => {
|
|
172
|
-
listeners.push(setState)
|
|
173
|
-
return () => {
|
|
174
|
-
const index = listeners.indexOf(setState)
|
|
175
|
-
if (index > -1) {
|
|
176
|
-
listeners.splice(index, 1)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}, [state])
|
|
180
|
-
|
|
181
63
|
return {
|
|
182
|
-
...state,
|
|
183
64
|
toast,
|
|
184
|
-
dismiss:
|
|
65
|
+
dismiss: toastLibrary.dismiss,
|
|
185
66
|
}
|
|
186
67
|
}
|
|
187
68
|
|
|
188
|
-
export { useToast, toast }
|
|
69
|
+
export { useToast, toast, Toaster }
|
|
189
70
|
|
|
190
71
|
export function useNotImplementedToast() {
|
|
191
72
|
const { toast } = useToast()
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
// Inspired by react-hot-toast library
|
|
4
|
-
import * as React from "react"
|
|
5
|
-
|
|
6
|
-
import type { ToastActionElement, ToastProps } from "@/components/ui/toast"
|
|
7
|
-
|
|
8
|
-
const TOAST_LIMIT = 1
|
|
9
|
-
const TOAST_REMOVE_DELAY = 1000000
|
|
10
|
-
|
|
11
|
-
type ToasterToast = ToastProps & {
|
|
12
|
-
id: string
|
|
13
|
-
title?: React.ReactNode
|
|
14
|
-
description?: React.ReactNode
|
|
15
|
-
action?: ToastActionElement
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const actionTypes = {
|
|
19
|
-
ADD_TOAST: "ADD_TOAST",
|
|
20
|
-
UPDATE_TOAST: "UPDATE_TOAST",
|
|
21
|
-
DISMISS_TOAST: "DISMISS_TOAST",
|
|
22
|
-
REMOVE_TOAST: "REMOVE_TOAST",
|
|
23
|
-
} as const
|
|
24
|
-
|
|
25
|
-
let count = 0
|
|
26
|
-
|
|
27
|
-
function genId() {
|
|
28
|
-
count = (count + 1) % Number.MAX_SAFE_INTEGER
|
|
29
|
-
return count.toString()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type ActionType = typeof actionTypes
|
|
33
|
-
|
|
34
|
-
type Action =
|
|
35
|
-
| {
|
|
36
|
-
type: ActionType["ADD_TOAST"]
|
|
37
|
-
toast: ToasterToast
|
|
38
|
-
}
|
|
39
|
-
| {
|
|
40
|
-
type: ActionType["UPDATE_TOAST"]
|
|
41
|
-
toast: Partial<ToasterToast>
|
|
42
|
-
}
|
|
43
|
-
| {
|
|
44
|
-
type: ActionType["DISMISS_TOAST"]
|
|
45
|
-
toastId?: ToasterToast["id"]
|
|
46
|
-
}
|
|
47
|
-
| {
|
|
48
|
-
type: ActionType["REMOVE_TOAST"]
|
|
49
|
-
toastId?: ToasterToast["id"]
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
interface State {
|
|
53
|
-
toasts: ToasterToast[]
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
|
|
57
|
-
|
|
58
|
-
const addToRemoveQueue = (toastId: string) => {
|
|
59
|
-
if (toastTimeouts.has(toastId)) {
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const timeout = setTimeout(() => {
|
|
64
|
-
toastTimeouts.delete(toastId)
|
|
65
|
-
dispatch({
|
|
66
|
-
type: "REMOVE_TOAST",
|
|
67
|
-
toastId: toastId,
|
|
68
|
-
})
|
|
69
|
-
}, TOAST_REMOVE_DELAY)
|
|
70
|
-
|
|
71
|
-
toastTimeouts.set(toastId, timeout)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export const reducer = (state: State, action: Action): State => {
|
|
75
|
-
switch (action.type) {
|
|
76
|
-
case "ADD_TOAST":
|
|
77
|
-
return {
|
|
78
|
-
...state,
|
|
79
|
-
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
case "UPDATE_TOAST":
|
|
83
|
-
return {
|
|
84
|
-
...state,
|
|
85
|
-
toasts: state.toasts.map((t) =>
|
|
86
|
-
t.id === action.toast.id ? { ...t, ...action.toast } : t,
|
|
87
|
-
),
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
case "DISMISS_TOAST": {
|
|
91
|
-
const { toastId } = action
|
|
92
|
-
|
|
93
|
-
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
|
94
|
-
// but I'll keep it here for simplicity
|
|
95
|
-
if (toastId) {
|
|
96
|
-
addToRemoveQueue(toastId)
|
|
97
|
-
} else {
|
|
98
|
-
state.toasts.forEach((toast) => {
|
|
99
|
-
addToRemoveQueue(toast.id)
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
...state,
|
|
105
|
-
toasts: state.toasts.map((t) =>
|
|
106
|
-
t.id === toastId || toastId === undefined
|
|
107
|
-
? {
|
|
108
|
-
...t,
|
|
109
|
-
open: false,
|
|
110
|
-
}
|
|
111
|
-
: t,
|
|
112
|
-
),
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
case "REMOVE_TOAST":
|
|
116
|
-
if (action.toastId === undefined) {
|
|
117
|
-
return {
|
|
118
|
-
...state,
|
|
119
|
-
toasts: [],
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return {
|
|
123
|
-
...state,
|
|
124
|
-
toasts: state.toasts.filter((t) => t.id !== action.toastId),
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const listeners: Array<(state: State) => void> = []
|
|
130
|
-
|
|
131
|
-
let memoryState: State = { toasts: [] }
|
|
132
|
-
|
|
133
|
-
function dispatch(action: Action) {
|
|
134
|
-
memoryState = reducer(memoryState, action)
|
|
135
|
-
listeners.forEach((listener) => {
|
|
136
|
-
listener(memoryState)
|
|
137
|
-
})
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
type Toast = Omit<ToasterToast, "id">
|
|
141
|
-
|
|
142
|
-
function toast({ ...props }: Toast) {
|
|
143
|
-
const id = genId()
|
|
144
|
-
|
|
145
|
-
const update = (props: ToasterToast) =>
|
|
146
|
-
dispatch({
|
|
147
|
-
type: "UPDATE_TOAST",
|
|
148
|
-
toast: { ...props, id },
|
|
149
|
-
})
|
|
150
|
-
const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
|
|
151
|
-
|
|
152
|
-
dispatch({
|
|
153
|
-
type: "ADD_TOAST",
|
|
154
|
-
toast: {
|
|
155
|
-
...props,
|
|
156
|
-
id,
|
|
157
|
-
open: true,
|
|
158
|
-
onOpenChange: (open) => {
|
|
159
|
-
if (!open) dismiss()
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
id: id,
|
|
166
|
-
dismiss,
|
|
167
|
-
update,
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
function useToast() {
|
|
172
|
-
const [state, setState] = React.useState<State>(memoryState)
|
|
173
|
-
|
|
174
|
-
React.useEffect(() => {
|
|
175
|
-
listeners.push(setState)
|
|
176
|
-
return () => {
|
|
177
|
-
const index = listeners.indexOf(setState)
|
|
178
|
-
if (index > -1) {
|
|
179
|
-
listeners.splice(index, 1)
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}, [state])
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
...state,
|
|
186
|
-
toast,
|
|
187
|
-
dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export { useToast, toast }
|