modifywithai 1.5.1 → 1.7.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.
package/AGENTS.md CHANGED
@@ -31,7 +31,7 @@ Locate the root layout file at `app/layout.tsx` (or `src/app/layout.tsx` if usin
31
31
  Add the following imports at the top:
32
32
 
33
33
  ```tsx
34
- import { MWAIHead, MWAIProvider, MWAIComponents } from "modifywithai"
34
+ import { MWAIHead, MWAIProvider, MWAIComponents } from "modifywithai/react"
35
35
  ```
36
36
 
37
37
  Then modify the layout to include:
@@ -147,28 +147,27 @@ Create a client component for the button:
147
147
  "use client"
148
148
 
149
149
  import { useState } from "react"
150
- import { modifyWithAI } from "modifywithai"
150
+ import { useModify } from "modifywithai/react"
151
151
 
152
152
  export function ModifyWithAIButton() {
153
153
  const [isOpen, setIsOpen] = useState(false)
154
154
  const [prompt, setPrompt] = useState("")
155
- const [isLoading, setIsLoading] = useState(false)
155
+ const { mutate, isPending } = useModify()
156
156
 
157
- const handleSubmit = async () => {
157
+ const handleSubmit = () => {
158
158
  if (!prompt.trim()) return
159
159
 
160
- setIsLoading(true)
161
- const { success, error } = await modifyWithAI(prompt)
162
- setIsLoading(false)
163
-
164
- if (success) {
165
- setPrompt("")
166
- setIsOpen(false)
167
- // Optionally show a success toast/notification
168
- } else {
169
- // Optionally show an error toast/notification
170
- console.error(error)
171
- }
160
+ mutate(prompt, {
161
+ onSuccess: () => {
162
+ setPrompt("")
163
+ setIsOpen(false)
164
+ // Page will reload automatically
165
+ },
166
+ onError: (error) => {
167
+ // Optionally show an error toast/notification
168
+ console.error(error)
169
+ }
170
+ })
172
171
  }
173
172
 
174
173
  if (!isOpen) {
@@ -185,12 +184,12 @@ export function ModifyWithAIButton() {
185
184
  value={prompt}
186
185
  onChange={(e) => setPrompt(e.target.value)}
187
186
  placeholder="Describe the changes you want to make..."
188
- disabled={isLoading}
187
+ disabled={isPending}
189
188
  />
190
- <button onClick={handleSubmit} disabled={isLoading || !prompt.trim()}>
191
- {isLoading ? "Submitting..." : "Submit"}
189
+ <button onClick={handleSubmit} disabled={isPending || !prompt.trim()}>
190
+ {isPending ? "Submitting..." : "Submit"}
192
191
  </button>
193
- <button onClick={() => setIsOpen(false)} disabled={isLoading}>
192
+ <button onClick={() => setIsOpen(false)} disabled={isPending}>
194
193
  Cancel
195
194
  </button>
196
195
  </div>
@@ -297,7 +296,7 @@ When creating or modifying React/JSX elements, ALWAYS add a `data-mwai-id` attri
297
296
  After completing the setup, verify:
298
297
 
299
298
  - [ ] `modifywithai` is listed in `package.json` dependencies
300
- - [ ] Root layout imports `MWAIHead`, `MWAIProvider`, `MWAIComponents` from `"modifywithai"`
299
+ - [ ] Root layout imports `MWAIHead`, `MWAIProvider`, `MWAIComponents` from `"modifywithai/react"`
301
300
  - [ ] `<MWAIHead />` is inside the `<head>` tag
302
301
  - [ ] `<MWAIProvider>` wraps `<MWAIComponents />` and is placed in `<body>`
303
302
  - [ ] `app/api/mwai/api/[path]/route.ts` exists and exports HTTP method handlers
package/dist/index.d.ts CHANGED
@@ -1,40 +1,70 @@
1
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
- import { ReactNode } from "react";
1
+ import { _ as ModifyWithAIOptions, a as DisableResponseSchema, c as EnableResponseSchema, d as ModificationSchema, f as ModificationToggleOptions, g as ModifyWithAIArgs, h as ModifyResponseSchema, i as DisableResponse, l as ListModificationsArgs, m as ModifyResponse, n as ApiErrorSchema, o as EnableModificationArgs, p as ModificationsListSchema, r as DisableModificationArgs, s as EnableResponse, t as ApiError, u as Modification } from "./types-DP2zKGqL.js";
2
+
3
+ //#region src/core.d.ts
3
4
 
4
- //#region src/head.d.ts
5
- declare const MWAIHead: ({
6
- basePath
7
- }?: {
8
- basePath?: string;
9
- }) => react_jsx_runtime0.JSX.Element;
10
- //#endregion
11
- //#region src/provider.d.ts
12
- declare const MWAIProvider: ({
13
- id,
14
- children
15
- }: {
16
- id: string;
17
- children: ReactNode;
18
- }) => react_jsx_runtime0.JSX.Element;
19
- //#endregion
20
- //#region src/hook.d.ts
21
- declare const useMWAIComponents: () => react_jsx_runtime0.JSX.Element | null;
22
- declare const MWAIComponents: () => react_jsx_runtime0.JSX.Element | null;
23
- //#endregion
24
- //#region src/modify.d.ts
25
- type ModifyWithAIOptions = {
26
- /** Called when modification submission fails */
27
- onError?: (error: Error) => void;
28
- };
5
+ /**
6
+ * Fetch the list of modifications for a given MWAI instance
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * const modifications = await listModifications({ id: "your-mwai-id" })
11
+ * console.log(modifications)
12
+ * ```
13
+ */
14
+ declare function listModifications({
15
+ id
16
+ }: ListModificationsArgs): Promise<Modification[]>;
29
17
  /**
30
18
  * Submit a modification request to ModifyWithAI
31
- * @param prompt - The modification prompt describing the changes to make
32
- * @param options - Optional callbacks for success and error handling
33
- * @returns Promise that resolves when the modification is submitted
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const result = await modifyWithAI({
23
+ * id: "your-mwai-id",
24
+ * prompt: "Change the button color to blue"
25
+ * })
26
+ * ```
27
+ */
28
+ declare function modifyWithAI({
29
+ id,
30
+ prompt
31
+ }: ModifyWithAIArgs, options?: ModifyWithAIOptions): Promise<{
32
+ success: boolean;
33
+ error?: Error;
34
+ }>;
35
+ /**
36
+ * Enable a modification for the current user
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * const result = await enableModification({
41
+ * modificationId: "mod-123"
42
+ * })
43
+ * ```
44
+ */
45
+ declare function enableModification({
46
+ modificationId
47
+ }: EnableModificationArgs, options?: ModificationToggleOptions): Promise<{
48
+ success: boolean;
49
+ data?: EnableResponse;
50
+ error?: Error;
51
+ }>;
52
+ /**
53
+ * Disable a modification for the current user
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * const result = await disableModification({
58
+ * modificationId: "mod-123"
59
+ * })
60
+ * ```
34
61
  */
35
- declare function modifyWithAI(prompt: string, options?: ModifyWithAIOptions): Promise<{
62
+ declare function disableModification({
63
+ modificationId
64
+ }: DisableModificationArgs, options?: ModificationToggleOptions): Promise<{
36
65
  success: boolean;
66
+ data?: DisableResponse;
37
67
  error?: Error;
38
68
  }>;
39
69
  //#endregion
40
- export { MWAIComponents, MWAIHead, MWAIProvider, type ModifyWithAIOptions, modifyWithAI, useMWAIComponents };
70
+ export { type ApiError, ApiErrorSchema, type DisableModificationArgs, type DisableResponse, DisableResponseSchema, type EnableModificationArgs, type EnableResponse, EnableResponseSchema, type ListModificationsArgs, type Modification, ModificationSchema, type ModificationToggleOptions, ModificationsListSchema, type ModifyResponse, ModifyResponseSchema, type ModifyWithAIArgs, type ModifyWithAIOptions, disableModification, enableModification, listModifications, modifyWithAI };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use client";import*as e from"react/jsx-runtime";import{Fragment as t,jsx as n}from"react/jsx-runtime";import*as r from"react";import{createContext as i,useContext as a,useLayoutEffect as o,useState as s}from"react";import*as c from"react-dom";import*as l from"react-dom/client";import{createFetch as u,createSchema as d}from"@better-fetch/fetch";import{z as f}from"zod";import{logger as p}from"@better-fetch/logger";const m=({basePath:e=`/api/mwai`}={})=>n(`script`,{type:`importmap`,dangerouslySetInnerHTML:{__html:JSON.stringify({imports:{react:`${e}/shims/react-shim.js`,"react/jsx-runtime":`${e}/shims/react-jsx-shim.js`,"react-dom":`${e}/shims/react-dom-shim.js`,"react-dom/client":`${e}/shims/react-dom-client-shim.js`}})}}),h=i(null),g=({id:e,children:t})=>n(h.Provider,{value:e,children:t}),_=u({schema:d({"/api/mwai/api/list":{output:f.array(f.object({id:f.string(),title:f.string().nullable(),description:f.string().nullable(),status:f.enum([`pending`,`success`,`error`]),createdAt:f.number(),updatedAt:f.number(),enabled:f.boolean().nullable()}))},"/api/mwai/api/modify":{input:f.object({prompt:f.string()}),output:f.object({success:f.boolean()})}}),retry:{type:`exponential`,attempts:5,baseDelay:1e3,maxDelay:1e4},plugins:[p({enabled:!1})]}),v=()=>{let i=a(h),[u,d]=s(null);return o(()=>{if(!i){console.error(`ModifyWithAI: No id provided. Wrap your app with <ModifyWithAIProvider id='your-id'>`);return}typeof window<`u`&&(window.__REACT__=r,window.__REACT_JSX_RUNTIME__=e,window.__REACT_DOM__=c,window.__REACT_DOM_CLIENT__=l);let t=Function(`url`,`return import(url)`);_(`/api/mwai/api/list`).then(({data:e,error:n})=>{if(n){console.error(`Failed to fetch component list:`,n);return}console.log(`data`,e);let r=e.filter(e=>e.enabled&&e.status===`success`).map(e=>e.id);console.log(`componentsToLoad`,r),r.forEach(e=>{t(`https://bucket.modifywithai.com/${i}/${e}.js`).then(e=>d(t=>[...t||[],e.default])).catch(e=>console.error(`Failed to load external module:`,e))})})},[i]),u?n(t,{children:u.map(e=>n(e,{},e.name))}):null},y=()=>v();async function b(e,t){let n=e.trim();if(!n){let e=Error(`Prompt cannot be empty`);return t?.onError?.(e),{success:!1,error:e}}try{return{success:(await _(`/api/mwai/api/modify`,{method:`POST`,body:{prompt:n},retry:0,onSuccess:()=>{typeof window<`u`&&window.location.reload()},onError:e=>{let n=Error(e.error.message||`Request failed`);t?.onError?.(n)}})).data?.success??!1}}catch(e){let n=e instanceof Error?e:Error(`Unknown error`);return t?.onError?.(n),{success:!1,error:n}}}export{y as MWAIComponents,m as MWAIHead,g as MWAIProvider,b as modifyWithAI,v as useMWAIComponents};
1
+ import{a as e,i as t,n,o as r,r as i,t as a}from"./types-B-V0OtIq.js";async function o({id:t}){let n=await fetch(`/api/mwai/api/list`);if(!n.ok)throw Error(`Failed to fetch modifications`);let r=await n.json();return e.parse(r)}async function s({id:e,prompt:t},n){let i=t.trim();if(!i){let e=Error(`Prompt cannot be empty`);return n?.onError?.(e),{success:!1,error:e}}try{let e=await fetch(`/api/mwai/api/modify`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({prompt:i})});if(!e.ok){let t=await e.json().catch(()=>({})),n=a.safeParse(t),r=n.success&&(n.data.message||n.data.error)||`Failed to submit modification`;throw Error(r)}let t=await e.json(),o=r.parse(t);return n?.onSuccess?.(),typeof window<`u`&&window.location.reload(),{success:o.success}}catch(e){let t=e instanceof Error?e:Error(`Unknown error`);return n?.onError?.(t),{success:!1,error:t}}}async function c({modificationId:e},t){try{let n=await fetch(`/api/mwai/api/enable`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({modificationId:e})});if(!n.ok){let e=await n.json().catch(()=>({})),t=a.safeParse(e),r=t.success&&(t.data.message||t.data.error)||`Failed to enable modification`;throw Error(r)}let r=await n.json(),o=i.parse(r);return t?.onSuccess?.(),typeof window<`u`&&window.location.reload(),{success:!0,data:o}}catch(e){let n=e instanceof Error?e:Error(`Unknown error`);return t?.onError?.(n),{success:!1,error:n}}}async function l({modificationId:e},t){try{let r=await fetch(`/api/mwai/api/disable`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({modificationId:e})});if(!r.ok){let e=await r.json().catch(()=>({})),t=a.safeParse(e),n=t.success&&(t.data.message||t.data.error)||`Failed to disable modification`;throw Error(n)}let i=await r.json(),o=n.parse(i);return t?.onSuccess?.(),typeof window<`u`&&window.location.reload(),{success:!0,data:o}}catch(e){let n=e instanceof Error?e:Error(`Unknown error`);return t?.onError?.(n),{success:!1,error:n}}}export{a as ApiErrorSchema,n as DisableResponseSchema,i as EnableResponseSchema,t as ModificationSchema,e as ModificationsListSchema,r as ModifyResponseSchema,l as disableModification,c as enableModification,o as listModifications,s as modifyWithAI};
@@ -57,4 +57,22 @@ const ReactDOMClient = window.__REACT_DOM_CLIENT__;
57
57
  export const createRoot = ReactDOMClient?.createRoot;
58
58
  export const hydrateRoot = ReactDOMClient?.hydrateRoot;
59
59
  export default ReactDOMClient;
60
+ `,"next-link-shim.js":`// Re-export next/link from the window object (set by the app)
61
+ const NextLink = window.__NEXT_LINK__;
62
+ export default NextLink;
63
+ `,"next-image-shim.js":`// Re-export next/image from the window object (set by the app)
64
+ const NextImage = window.__NEXT_IMAGE__;
65
+ export default NextImage;
66
+ `,"next-navigation-shim.js":`// Re-export next/navigation from the window object (set by the app)
67
+ const NextNavigation = window.__NEXT_NAVIGATION__;
68
+ export const useRouter = NextNavigation?.useRouter;
69
+ export const usePathname = NextNavigation?.usePathname;
70
+ export const useSearchParams = NextNavigation?.useSearchParams;
71
+ export const useParams = NextNavigation?.useParams;
72
+ export const useSelectedLayoutSegment = NextNavigation?.useSelectedLayoutSegment;
73
+ export const useSelectedLayoutSegments = NextNavigation?.useSelectedLayoutSegments;
74
+ export const redirect = NextNavigation?.redirect;
75
+ export const notFound = NextNavigation?.notFound;
76
+ export const permanentRedirect = NextNavigation?.permanentRedirect;
77
+ export default NextNavigation;
60
78
  `};async function t(){return Object.keys(e).map(e=>({path:e}))}const n=async(t,{params:n})=>{let r=(await n).path;return new Response(e[r],{headers:{"Content-Type":`application/javascript`,"Cache-Control":`public, max-age=31536000, immutable`}})};export{n as GET,t as generateStaticParams};
@@ -0,0 +1,402 @@
1
+ import { _ as ModifyWithAIOptions, a as DisableResponseSchema, c as EnableResponseSchema, d as ModificationSchema, f as ModificationToggleOptions, h as ModifyResponseSchema, i as DisableResponse, m as ModifyResponse, n as ApiErrorSchema, p as ModificationsListSchema, s as EnableResponse, t as ApiError, u as Modification } from "../types-DP2zKGqL.js";
2
+ import * as react0 from "react";
3
+ import { ReactNode } from "react";
4
+ import * as _tanstack_react_query0 from "@tanstack/react-query";
5
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
6
+
7
+ //#region src/react/provider.d.ts
8
+ declare const MWAIContext: react0.Context<string | null>;
9
+ declare const MWAIProvider: ({
10
+ id,
11
+ children
12
+ }: {
13
+ id: string;
14
+ children: ReactNode;
15
+ }) => react_jsx_runtime0.JSX.Element;
16
+ //#endregion
17
+ //#region src/react/head.d.ts
18
+ declare const MWAIHead: ({
19
+ basePath
20
+ }?: {
21
+ basePath?: string;
22
+ }) => react_jsx_runtime0.JSX.Element;
23
+ //#endregion
24
+ //#region src/react/components.d.ts
25
+ declare const useComponents: () => react_jsx_runtime0.JSX.Element | null;
26
+ declare const MWAIComponents: () => react_jsx_runtime0.JSX.Element | null;
27
+ //#endregion
28
+ //#region src/react/hooks.d.ts
29
+ /**
30
+ * React hook for fetching the list of modifications
31
+ * Polls every 10 seconds for updates
32
+ *
33
+ * @example
34
+ * ```tsx
35
+ * const { data, isLoading, error } = useList()
36
+ * ```
37
+ */
38
+ declare function useList(): _tanstack_react_query0.UseQueryResult<{
39
+ id: string;
40
+ title: string | null;
41
+ description: string | null;
42
+ status: "error" | "pending" | "success";
43
+ createdAt: number;
44
+ updatedAt: number;
45
+ enabled: boolean | null;
46
+ }[], Error>;
47
+ /**
48
+ * React hook for submitting modification requests to ModifyWithAI
49
+ * Returns mutation state and a `modify` function for submitting prompts
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * const { modify, isPending, isError, error } = useModify()
54
+ *
55
+ * const handleSubmit = () => {
56
+ * modify("Change the button color to blue", {
57
+ * onSuccess: () => console.log("Submitted!"),
58
+ * onError: (err) => console.error(err),
59
+ * })
60
+ * }
61
+ * ```
62
+ */
63
+ declare function useModify(options?: ModifyWithAIOptions): {
64
+ data: undefined;
65
+ variables: undefined;
66
+ error: null;
67
+ isError: false;
68
+ isIdle: true;
69
+ isPending: false;
70
+ isSuccess: false;
71
+ status: "idle";
72
+ reset: () => void;
73
+ context: unknown;
74
+ failureCount: number;
75
+ failureReason: Error | null;
76
+ isPaused: boolean;
77
+ submittedAt: number;
78
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
79
+ success: boolean;
80
+ }, Error, string, unknown>;
81
+ modify: _tanstack_react_query0.UseMutateFunction<{
82
+ success: boolean;
83
+ }, Error, string, unknown>;
84
+ } | {
85
+ data: undefined;
86
+ variables: string;
87
+ error: null;
88
+ isError: false;
89
+ isIdle: false;
90
+ isPending: true;
91
+ isSuccess: false;
92
+ status: "pending";
93
+ reset: () => void;
94
+ context: unknown;
95
+ failureCount: number;
96
+ failureReason: Error | null;
97
+ isPaused: boolean;
98
+ submittedAt: number;
99
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
100
+ success: boolean;
101
+ }, Error, string, unknown>;
102
+ modify: _tanstack_react_query0.UseMutateFunction<{
103
+ success: boolean;
104
+ }, Error, string, unknown>;
105
+ } | {
106
+ data: undefined;
107
+ error: Error;
108
+ variables: string;
109
+ isError: true;
110
+ isIdle: false;
111
+ isPending: false;
112
+ isSuccess: false;
113
+ status: "error";
114
+ reset: () => void;
115
+ context: unknown;
116
+ failureCount: number;
117
+ failureReason: Error | null;
118
+ isPaused: boolean;
119
+ submittedAt: number;
120
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
121
+ success: boolean;
122
+ }, Error, string, unknown>;
123
+ modify: _tanstack_react_query0.UseMutateFunction<{
124
+ success: boolean;
125
+ }, Error, string, unknown>;
126
+ } | {
127
+ data: {
128
+ success: boolean;
129
+ };
130
+ error: null;
131
+ variables: string;
132
+ isError: false;
133
+ isIdle: false;
134
+ isPending: false;
135
+ isSuccess: true;
136
+ status: "success";
137
+ reset: () => void;
138
+ context: unknown;
139
+ failureCount: number;
140
+ failureReason: Error | null;
141
+ isPaused: boolean;
142
+ submittedAt: number;
143
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
144
+ success: boolean;
145
+ }, Error, string, unknown>;
146
+ modify: _tanstack_react_query0.UseMutateFunction<{
147
+ success: boolean;
148
+ }, Error, string, unknown>;
149
+ };
150
+ /**
151
+ * React hook for enabling a modification
152
+ * Returns mutation state and an `enable` function for enabling modifications
153
+ *
154
+ * @example
155
+ * ```tsx
156
+ * const { enable, isPending, isError, error } = useEnable()
157
+ *
158
+ * const handleEnable = () => {
159
+ * enable("modification-id", {
160
+ * onSuccess: () => console.log("Enabled!"),
161
+ * onError: (err) => console.error(err),
162
+ * })
163
+ * }
164
+ * ```
165
+ */
166
+ declare function useEnable(options?: ModificationToggleOptions): {
167
+ data: undefined;
168
+ variables: undefined;
169
+ error: null;
170
+ isError: false;
171
+ isIdle: true;
172
+ isPending: false;
173
+ isSuccess: false;
174
+ status: "idle";
175
+ reset: () => void;
176
+ context: unknown;
177
+ failureCount: number;
178
+ failureReason: Error | null;
179
+ isPaused: boolean;
180
+ submittedAt: number;
181
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
182
+ message: string;
183
+ modificationId: string;
184
+ endUserId: string;
185
+ }, Error, string, unknown>;
186
+ enable: _tanstack_react_query0.UseMutateFunction<{
187
+ message: string;
188
+ modificationId: string;
189
+ endUserId: string;
190
+ }, Error, string, unknown>;
191
+ } | {
192
+ data: undefined;
193
+ variables: string;
194
+ error: null;
195
+ isError: false;
196
+ isIdle: false;
197
+ isPending: true;
198
+ isSuccess: false;
199
+ status: "pending";
200
+ reset: () => void;
201
+ context: unknown;
202
+ failureCount: number;
203
+ failureReason: Error | null;
204
+ isPaused: boolean;
205
+ submittedAt: number;
206
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
207
+ message: string;
208
+ modificationId: string;
209
+ endUserId: string;
210
+ }, Error, string, unknown>;
211
+ enable: _tanstack_react_query0.UseMutateFunction<{
212
+ message: string;
213
+ modificationId: string;
214
+ endUserId: string;
215
+ }, Error, string, unknown>;
216
+ } | {
217
+ data: undefined;
218
+ error: Error;
219
+ variables: string;
220
+ isError: true;
221
+ isIdle: false;
222
+ isPending: false;
223
+ isSuccess: false;
224
+ status: "error";
225
+ reset: () => void;
226
+ context: unknown;
227
+ failureCount: number;
228
+ failureReason: Error | null;
229
+ isPaused: boolean;
230
+ submittedAt: number;
231
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
232
+ message: string;
233
+ modificationId: string;
234
+ endUserId: string;
235
+ }, Error, string, unknown>;
236
+ enable: _tanstack_react_query0.UseMutateFunction<{
237
+ message: string;
238
+ modificationId: string;
239
+ endUserId: string;
240
+ }, Error, string, unknown>;
241
+ } | {
242
+ data: {
243
+ message: string;
244
+ modificationId: string;
245
+ endUserId: string;
246
+ };
247
+ error: null;
248
+ variables: string;
249
+ isError: false;
250
+ isIdle: false;
251
+ isPending: false;
252
+ isSuccess: true;
253
+ status: "success";
254
+ reset: () => void;
255
+ context: unknown;
256
+ failureCount: number;
257
+ failureReason: Error | null;
258
+ isPaused: boolean;
259
+ submittedAt: number;
260
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
261
+ message: string;
262
+ modificationId: string;
263
+ endUserId: string;
264
+ }, Error, string, unknown>;
265
+ enable: _tanstack_react_query0.UseMutateFunction<{
266
+ message: string;
267
+ modificationId: string;
268
+ endUserId: string;
269
+ }, Error, string, unknown>;
270
+ };
271
+ /**
272
+ * React hook for disabling a modification
273
+ * Returns mutation state and a `disable` function for disabling modifications
274
+ *
275
+ * @example
276
+ * ```tsx
277
+ * const { disable, isPending, isError, error } = useDisable()
278
+ *
279
+ * const handleDisable = () => {
280
+ * disable("modification-id", {
281
+ * onSuccess: () => console.log("Disabled!"),
282
+ * onError: (err) => console.error(err),
283
+ * })
284
+ * }
285
+ * ```
286
+ */
287
+ declare function useDisable(options?: ModificationToggleOptions): {
288
+ data: undefined;
289
+ variables: undefined;
290
+ error: null;
291
+ isError: false;
292
+ isIdle: true;
293
+ isPending: false;
294
+ isSuccess: false;
295
+ status: "idle";
296
+ reset: () => void;
297
+ context: unknown;
298
+ failureCount: number;
299
+ failureReason: Error | null;
300
+ isPaused: boolean;
301
+ submittedAt: number;
302
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
303
+ message: string;
304
+ modificationId: string;
305
+ endUserId: string;
306
+ }, Error, string, unknown>;
307
+ disable: _tanstack_react_query0.UseMutateFunction<{
308
+ message: string;
309
+ modificationId: string;
310
+ endUserId: string;
311
+ }, Error, string, unknown>;
312
+ } | {
313
+ data: undefined;
314
+ variables: string;
315
+ error: null;
316
+ isError: false;
317
+ isIdle: false;
318
+ isPending: true;
319
+ isSuccess: false;
320
+ status: "pending";
321
+ reset: () => void;
322
+ context: unknown;
323
+ failureCount: number;
324
+ failureReason: Error | null;
325
+ isPaused: boolean;
326
+ submittedAt: number;
327
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
328
+ message: string;
329
+ modificationId: string;
330
+ endUserId: string;
331
+ }, Error, string, unknown>;
332
+ disable: _tanstack_react_query0.UseMutateFunction<{
333
+ message: string;
334
+ modificationId: string;
335
+ endUserId: string;
336
+ }, Error, string, unknown>;
337
+ } | {
338
+ data: undefined;
339
+ error: Error;
340
+ variables: string;
341
+ isError: true;
342
+ isIdle: false;
343
+ isPending: false;
344
+ isSuccess: false;
345
+ status: "error";
346
+ reset: () => void;
347
+ context: unknown;
348
+ failureCount: number;
349
+ failureReason: Error | null;
350
+ isPaused: boolean;
351
+ submittedAt: number;
352
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
353
+ message: string;
354
+ modificationId: string;
355
+ endUserId: string;
356
+ }, Error, string, unknown>;
357
+ disable: _tanstack_react_query0.UseMutateFunction<{
358
+ message: string;
359
+ modificationId: string;
360
+ endUserId: string;
361
+ }, Error, string, unknown>;
362
+ } | {
363
+ data: {
364
+ message: string;
365
+ modificationId: string;
366
+ endUserId: string;
367
+ };
368
+ error: null;
369
+ variables: string;
370
+ isError: false;
371
+ isIdle: false;
372
+ isPending: false;
373
+ isSuccess: true;
374
+ status: "success";
375
+ reset: () => void;
376
+ context: unknown;
377
+ failureCount: number;
378
+ failureReason: Error | null;
379
+ isPaused: boolean;
380
+ submittedAt: number;
381
+ mutateAsync: _tanstack_react_query0.UseMutateAsyncFunction<{
382
+ message: string;
383
+ modificationId: string;
384
+ endUserId: string;
385
+ }, Error, string, unknown>;
386
+ disable: _tanstack_react_query0.UseMutateFunction<{
387
+ message: string;
388
+ modificationId: string;
389
+ endUserId: string;
390
+ }, Error, string, unknown>;
391
+ };
392
+ //#endregion
393
+ //#region src/react/query-keys.d.ts
394
+ /**
395
+ * Centralized query key factory for type-safe, consistent cache management
396
+ */
397
+ declare const mwaiQueryKeys: {
398
+ readonly all: readonly ["mwai"];
399
+ readonly modifications: () => readonly ["mwai", "modifications"];
400
+ };
401
+ //#endregion
402
+ export { type ApiError, ApiErrorSchema, type DisableResponse, DisableResponseSchema, type EnableResponse, EnableResponseSchema, MWAIComponents, MWAIContext, MWAIHead, MWAIProvider, type Modification, ModificationSchema, type ModificationToggleOptions, ModificationsListSchema, type ModifyResponse, ModifyResponseSchema, type ModifyWithAIOptions, mwaiQueryKeys, useComponents, useDisable, useEnable, useList, useModify };
@@ -0,0 +1 @@
1
+ "use client";import{a as e,i as t,n,o as r,r as i,t as a}from"../types-B-V0OtIq.js";import*as o from"react";import{createContext as s,useContext as c,useLayoutEffect as l,useRef as u,useState as d}from"react";import{QueryClient as f,QueryClientProvider as p,useMutation as m,useQuery as h,useQueryClient as g}from"@tanstack/react-query";import*as _ from"react/jsx-runtime";import{Fragment as v,jsx as y}from"react/jsx-runtime";import*as b from"react-dom";import*as x from"react-dom/client";import S from"next/link";import C from"next/image";import*as w from"next/navigation";const T=s(null);function E(){return new f({defaultOptions:{queries:{staleTime:5e3,refetchOnWindowFocus:!1}}})}const D=({id:e,children:t})=>{let[n]=d(E);return y(p,{client:n,children:y(T.Provider,{value:e,children:t})})},O=({basePath:e=`/api/mwai`}={})=>y(`script`,{type:`importmap`,dangerouslySetInnerHTML:{__html:JSON.stringify({imports:{react:`${e}/shims/react-shim.js`,"react/jsx-runtime":`${e}/shims/react-jsx-shim.js`,"react-dom":`${e}/shims/react-dom-shim.js`,"react-dom/client":`${e}/shims/react-dom-client-shim.js`,"next/link":`${e}/shims/next-link-shim.js`,"next/image":`${e}/shims/next-image-shim.js`,"next/navigation":`${e}/shims/next-navigation-shim.js`}})}}),k={all:[`mwai`],modifications:()=>[...k.all,`modifications`]};function A(){return h({queryKey:k.modifications(),queryFn:async()=>{let t=await fetch(`/api/mwai/api/list`);if(!t.ok)throw Error(`Failed to fetch modifications`);let n=await t.json();return e.parse(n)},refetchInterval:1e4})}function j(e){let t=g(),{mutate:n,...i}=m({mutationFn:async e=>{let t=e.trim();if(!t)throw Error(`Prompt cannot be empty`);let n=await fetch(`/api/mwai/api/modify`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({prompt:t})});if(!n.ok){let e=await n.json().catch(()=>({})),t=a.safeParse(e),r=t.success&&(t.data.message||t.data.error)||`Failed to submit modification`;throw Error(r)}let i=await n.json();return r.parse(i)},onSuccess:()=>{t.invalidateQueries({queryKey:k.modifications()}),e?.onSuccess?.(),typeof window<`u`&&window.location.reload()},onError:t=>{let n=t instanceof Error?t:Error(`Unknown error`);e?.onError?.(n)}});return{modify:n,...i}}function M(e){let t=g(),{mutate:n,...r}=m({mutationFn:async e=>{let t=await fetch(`/api/mwai/api/enable`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({modificationId:e})});if(!t.ok){let e=await t.json().catch(()=>({})),n=a.safeParse(e),r=n.success&&(n.data.message||n.data.error)||`Failed to enable modification`;throw Error(r)}let n=await t.json();return i.parse(n)},onSuccess:()=>{t.invalidateQueries({queryKey:k.modifications()}),e?.onSuccess?.(),typeof window<`u`&&window.location.reload()},onError:t=>{let n=t instanceof Error?t:Error(`Unknown error`);e?.onError?.(n)}});return{enable:n,...r}}function N(e){let t=g(),{mutate:r,...i}=m({mutationFn:async e=>{let t=await fetch(`/api/mwai/api/disable`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({modificationId:e})});if(!t.ok){let e=await t.json().catch(()=>({})),n=a.safeParse(e),r=n.success&&(n.data.message||n.data.error)||`Failed to disable modification`;throw Error(r)}let r=await t.json();return n.parse(r)},onSuccess:()=>{t.invalidateQueries({queryKey:k.modifications()}),e?.onSuccess?.(),typeof window<`u`&&window.location.reload()},onError:t=>{let n=t instanceof Error?t:Error(`Unknown error`);e?.onError?.(n)}});return{disable:r,...i}}const P=()=>{let e=c(T),[t,n]=d(null),{data:r}=A(),i=u(null);return l(()=>{if(!e){console.error(`ModifyWithAI: No id provided. Wrap your app with <ModifyWithAIProvider id='your-id'>`);return}typeof window<`u`&&(window.__REACT__=o,window.__REACT_JSX_RUNTIME__=_,window.__REACT_DOM__=b,window.__REACT_DOM_CLIENT__=x,window.__NEXT_LINK__=S,window.__NEXT_IMAGE__=C,window.__NEXT_NAVIGATION__=w)},[e]),l(()=>{if(!e||!r)return;let t=Function(`url`,`return import(url)`),a=r.filter(e=>e.enabled&&e.status===`success`).map(e=>e.id),o=i.current;if(o!==null){let e=new Set(o),t=new Set(a);if(o.length!==a.length||a.some(t=>!e.has(t))||o.some(e=>!t.has(e))){typeof window<`u`&&window.location.reload();return}}i.current=a,n([]),a.forEach(r=>{t(`https://bucket.modifywithai.com/${e}/${r}.js`).then(e=>n(t=>[...t||[],e.default])).catch(e=>console.error(`Failed to load external module:`,e))})},[e,r]),t?y(v,{children:t.map(e=>y(e,{},e.name))}):null},F=()=>P();export{a as ApiErrorSchema,n as DisableResponseSchema,i as EnableResponseSchema,F as MWAIComponents,T as MWAIContext,O as MWAIHead,D as MWAIProvider,t as ModificationSchema,e as ModificationsListSchema,r as ModifyResponseSchema,k as mwaiQueryKeys,P as useComponents,N as useDisable,M as useEnable,A as useList,j as useModify};
@@ -0,0 +1 @@
1
+ import{z as e}from"zod";const t=e.object({id:e.string(),title:e.string().nullable(),description:e.string().nullable(),status:e.enum([`pending`,`success`,`error`]),createdAt:e.number(),updatedAt:e.number(),enabled:e.boolean().nullable()}),n=e.array(t),r=e.object({success:e.boolean()}),i=e.object({message:e.string(),modificationId:e.string(),endUserId:e.string()}),a=e.object({message:e.string(),modificationId:e.string(),endUserId:e.string()}),o=e.object({message:e.string().optional(),error:e.string().optional()});export{n as a,t as i,a as n,r as o,i as r,o as t};
@@ -0,0 +1,135 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/types.d.ts
4
+
5
+ /**
6
+ * Schema for a modification in the ModifyWithAI system
7
+ */
8
+ declare const ModificationSchema: z.ZodObject<{
9
+ id: z.ZodString;
10
+ title: z.ZodNullable<z.ZodString>;
11
+ description: z.ZodNullable<z.ZodString>;
12
+ status: z.ZodEnum<{
13
+ error: "error";
14
+ pending: "pending";
15
+ success: "success";
16
+ }>;
17
+ createdAt: z.ZodNumber;
18
+ updatedAt: z.ZodNumber;
19
+ enabled: z.ZodNullable<z.ZodBoolean>;
20
+ }, z.core.$strip>;
21
+ /**
22
+ * Schema for the list modifications API response
23
+ */
24
+ declare const ModificationsListSchema: z.ZodArray<z.ZodObject<{
25
+ id: z.ZodString;
26
+ title: z.ZodNullable<z.ZodString>;
27
+ description: z.ZodNullable<z.ZodString>;
28
+ status: z.ZodEnum<{
29
+ error: "error";
30
+ pending: "pending";
31
+ success: "success";
32
+ }>;
33
+ createdAt: z.ZodNumber;
34
+ updatedAt: z.ZodNumber;
35
+ enabled: z.ZodNullable<z.ZodBoolean>;
36
+ }, z.core.$strip>>;
37
+ /**
38
+ * Schema for the modify API response
39
+ */
40
+ declare const ModifyResponseSchema: z.ZodObject<{
41
+ success: z.ZodBoolean;
42
+ }, z.core.$strip>;
43
+ /**
44
+ * Schema for the enable API response
45
+ */
46
+ declare const EnableResponseSchema: z.ZodObject<{
47
+ message: z.ZodString;
48
+ modificationId: z.ZodString;
49
+ endUserId: z.ZodString;
50
+ }, z.core.$strip>;
51
+ /**
52
+ * Schema for the disable API response
53
+ */
54
+ declare const DisableResponseSchema: z.ZodObject<{
55
+ message: z.ZodString;
56
+ modificationId: z.ZodString;
57
+ endUserId: z.ZodString;
58
+ }, z.core.$strip>;
59
+ /**
60
+ * Schema for API error responses
61
+ */
62
+ declare const ApiErrorSchema: z.ZodObject<{
63
+ message: z.ZodOptional<z.ZodString>;
64
+ error: z.ZodOptional<z.ZodString>;
65
+ }, z.core.$strip>;
66
+ /**
67
+ * Represents a modification in the ModifyWithAI system
68
+ */
69
+ type Modification = z.infer<typeof ModificationSchema>;
70
+ /**
71
+ * Response from a modification request
72
+ */
73
+ type ModifyResponse = z.infer<typeof ModifyResponseSchema>;
74
+ /**
75
+ * Response from enabling a modification
76
+ */
77
+ type EnableResponse = z.infer<typeof EnableResponseSchema>;
78
+ /**
79
+ * Response from disabling a modification
80
+ */
81
+ type DisableResponse = z.infer<typeof DisableResponseSchema>;
82
+ /**
83
+ * API error response
84
+ */
85
+ type ApiError = z.infer<typeof ApiErrorSchema>;
86
+ /**
87
+ * Options for modification requests
88
+ */
89
+ type ModifyWithAIOptions = {
90
+ /** Called when modification submission succeeds */
91
+ onSuccess?: () => void;
92
+ /** Called when modification submission fails */
93
+ onError?: (error: Error) => void;
94
+ };
95
+ /**
96
+ * Arguments for listModifications function
97
+ */
98
+ type ListModificationsArgs = {
99
+ /** The MWAI instance ID */
100
+ id: string;
101
+ };
102
+ /**
103
+ * Arguments for modifyWithAI function
104
+ */
105
+ type ModifyWithAIArgs = {
106
+ /** The MWAI instance ID */
107
+ id: string;
108
+ /** The modification prompt */
109
+ prompt: string;
110
+ };
111
+ /**
112
+ * Arguments for enableModification function
113
+ */
114
+ type EnableModificationArgs = {
115
+ /** The ID of the modification to enable */
116
+ modificationId: string;
117
+ };
118
+ /**
119
+ * Arguments for disableModification function
120
+ */
121
+ type DisableModificationArgs = {
122
+ /** The ID of the modification to disable */
123
+ modificationId: string;
124
+ };
125
+ /**
126
+ * Options for enable/disable modification requests
127
+ */
128
+ type ModificationToggleOptions = {
129
+ /** Called when the operation succeeds */
130
+ onSuccess?: () => void;
131
+ /** Called when the operation fails */
132
+ onError?: (error: Error) => void;
133
+ };
134
+ //#endregion
135
+ export { ModifyWithAIOptions as _, DisableResponseSchema as a, EnableResponseSchema as c, ModificationSchema as d, ModificationToggleOptions as f, ModifyWithAIArgs as g, ModifyResponseSchema as h, DisableResponse as i, ListModificationsArgs as l, ModifyResponse as m, ApiErrorSchema as n, EnableModificationArgs as o, ModificationsListSchema as p, DisableModificationArgs as r, EnableResponse as s, ApiError as t, Modification as u };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modifywithai",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -9,6 +9,7 @@
9
9
  ".": "./dist/index.js",
10
10
  "./nextjs/api": "./dist/nextjs/api.js",
11
11
  "./nextjs/shims": "./dist/nextjs/shims.js",
12
+ "./react": "./dist/react/index.js",
12
13
  "./package.json": "./package.json"
13
14
  },
14
15
  "files": [
@@ -24,7 +25,7 @@
24
25
  "@types/bun": "latest",
25
26
  "@types/react": "^19.2.7",
26
27
  "@types/react-dom": "^19.2.3",
27
- "tsdown": "^0.17.4",
28
+ "tsdown": "^0.18.0",
28
29
  "typescript": "^5.9.3"
29
30
  },
30
31
  "peerDependencies": {
@@ -32,8 +33,7 @@
32
33
  "next": "^16.0.8"
33
34
  },
34
35
  "dependencies": {
35
- "@better-fetch/fetch": "^1.1.21",
36
- "@better-fetch/logger": "^1.1.21",
37
- "zod": "^4.1.13"
36
+ "@tanstack/react-query": "^5.0.0",
37
+ "zod": "^4.2.0"
38
38
  }
39
39
  }