@zenstackhq/tanstack-query 1.0.0-beta.1 → 1.0.0-beta.11

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.
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
+ var __export = (target, all) => {
24
+ for (var name in all)
25
+ __defProp(target, name, { get: all[name], enumerable: true });
26
+ };
27
+ var __copyProps = (to, from, except, desc) => {
28
+ if (from && typeof from === "object" || typeof from === "function") {
29
+ for (let key of __getOwnPropNames(from))
30
+ if (!__hasOwnProp.call(to, key) && key !== except)
31
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
32
+ }
33
+ return to;
34
+ };
35
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
+ var __async = (__this, __arguments, generator) => {
37
+ return new Promise((resolve, reject) => {
38
+ var fulfilled = (value) => {
39
+ try {
40
+ step(generator.next(value));
41
+ } catch (e) {
42
+ reject(e);
43
+ }
44
+ };
45
+ var rejected = (value) => {
46
+ try {
47
+ step(generator.throw(value));
48
+ } catch (e) {
49
+ reject(e);
50
+ }
51
+ };
52
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
53
+ step((generator = generator.apply(__this, __arguments)).next());
54
+ });
55
+ };
56
+
57
+ // src/runtime/svelte.ts
58
+ var svelte_exports = {};
59
+ __export(svelte_exports, {
60
+ SvelteQueryContextKey: () => SvelteQueryContextKey,
61
+ deleteMutation: () => deleteMutation,
62
+ postMutation: () => postMutation,
63
+ putMutation: () => putMutation,
64
+ query: () => query
65
+ });
66
+ module.exports = __toCommonJS(svelte_exports);
67
+ var import_svelte_query = require("@tanstack/svelte-query");
68
+
69
+ // src/runtime/common.ts
70
+ var import_browser = require("@zenstackhq/runtime/browser");
71
+ var QUERY_KEY_PREFIX = "zenstack:";
72
+ function fetcher(url, options, fetch, checkReadBack) {
73
+ return __async(this, null, function* () {
74
+ var _a, _b, _c;
75
+ const _fetch = fetch != null ? fetch : window.fetch;
76
+ const res = yield _fetch(url, options);
77
+ if (!res.ok) {
78
+ const errData = unmarshal(yield res.text());
79
+ if (checkReadBack !== false && ((_a = errData.error) == null ? void 0 : _a.prisma) && ((_b = errData.error) == null ? void 0 : _b.code) === "P2004" && ((_c = errData.error) == null ? void 0 : _c.reason) === "RESULT_NOT_READABLE") {
80
+ return void 0;
81
+ }
82
+ const error = new Error(
83
+ "An error occurred while fetching the data."
84
+ );
85
+ error.info = errData.error;
86
+ error.status = res.status;
87
+ throw error;
88
+ }
89
+ const textResult = yield res.text();
90
+ try {
91
+ return unmarshal(textResult).data;
92
+ } catch (err) {
93
+ console.error(`Unable to deserialize data:`, textResult);
94
+ throw err;
95
+ }
96
+ });
97
+ }
98
+ function marshal(value) {
99
+ const { data, meta } = (0, import_browser.serialize)(value);
100
+ if (meta) {
101
+ return JSON.stringify(__spreadProps(__spreadValues({}, data), { meta: { serialization: meta } }));
102
+ } else {
103
+ return JSON.stringify(data);
104
+ }
105
+ }
106
+ function unmarshal(value) {
107
+ var _a;
108
+ const parsed = JSON.parse(value);
109
+ if (parsed.data && ((_a = parsed.meta) == null ? void 0 : _a.serialization)) {
110
+ const deserializedData = (0, import_browser.deserialize)(parsed.data, parsed.meta.serialization);
111
+ return __spreadProps(__spreadValues({}, parsed), { data: deserializedData });
112
+ } else {
113
+ return parsed;
114
+ }
115
+ }
116
+ function makeUrl(url, args) {
117
+ if (!args) {
118
+ return url;
119
+ }
120
+ const { data, meta } = (0, import_browser.serialize)(args);
121
+ let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;
122
+ if (meta) {
123
+ result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;
124
+ }
125
+ return result;
126
+ }
127
+
128
+ // src/runtime/svelte.ts
129
+ var SvelteQueryContextKey = "zenstack-svelte-query-context";
130
+ function query(model, url, args, options, fetch) {
131
+ const reqUrl = makeUrl(url, args);
132
+ return (0, import_svelte_query.createQuery)(__spreadValues({
133
+ queryKey: [QUERY_KEY_PREFIX + model, url, args],
134
+ queryFn: () => fetcher(reqUrl, void 0, fetch, false)
135
+ }, options));
136
+ }
137
+ function postMutation(model, url, options, fetch, invalidateQueries = true, checkReadBack) {
138
+ const queryClient = (0, import_svelte_query.useQueryClient)();
139
+ const mutationFn = (data) => fetcher(
140
+ url,
141
+ {
142
+ method: "POST",
143
+ headers: {
144
+ "content-type": "application/json"
145
+ },
146
+ body: marshal(data)
147
+ },
148
+ fetch,
149
+ checkReadBack
150
+ );
151
+ const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
152
+ const mutation = (0, import_svelte_query.createMutation)(finalOptions);
153
+ return mutation;
154
+ }
155
+ function putMutation(model, url, options, fetch, invalidateQueries = true, checkReadBack) {
156
+ const queryClient = (0, import_svelte_query.useQueryClient)();
157
+ const mutationFn = (data) => fetcher(
158
+ url,
159
+ {
160
+ method: "PUT",
161
+ headers: {
162
+ "content-type": "application/json"
163
+ },
164
+ body: marshal(data)
165
+ },
166
+ fetch,
167
+ checkReadBack
168
+ );
169
+ const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
170
+ const mutation = (0, import_svelte_query.createMutation)(finalOptions);
171
+ return mutation;
172
+ }
173
+ function deleteMutation(model, url, options, fetch, invalidateQueries = true, checkReadBack) {
174
+ const queryClient = (0, import_svelte_query.useQueryClient)();
175
+ const mutationFn = (data) => fetcher(
176
+ makeUrl(url, data),
177
+ {
178
+ method: "DELETE"
179
+ },
180
+ fetch,
181
+ checkReadBack
182
+ );
183
+ const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
184
+ const mutation = (0, import_svelte_query.createMutation)(finalOptions);
185
+ return mutation;
186
+ }
187
+ function mergeOptions(model, options, invalidateQueries, mutationFn, queryClient) {
188
+ const result = __spreadProps(__spreadValues({}, options), { mutationFn });
189
+ if ((options == null ? void 0 : options.onSuccess) || invalidateQueries) {
190
+ result.onSuccess = (...args) => {
191
+ var _a;
192
+ if (invalidateQueries) {
193
+ queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);
194
+ }
195
+ return (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, ...args);
196
+ };
197
+ }
198
+ return result;
199
+ }
200
+ // Annotate the CommonJS export names for ESM import in node:
201
+ 0 && (module.exports = {
202
+ SvelteQueryContextKey,
203
+ deleteMutation,
204
+ postMutation,
205
+ putMutation,
206
+ query
207
+ });
208
+ //# sourceMappingURL=svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/runtime/svelte.ts","../../src/runtime/common.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n createMutation,\n createQuery,\n useQueryClient,\n type MutateFunction,\n type MutationOptions,\n type QueryClient,\n type QueryOptions,\n} from '@tanstack/svelte-query';\nimport { FetchFn, QUERY_KEY_PREFIX, fetcher, makeUrl, marshal } from './common';\n\nexport { APIContext as RequestHandlerContext } from './common';\n\n/**\n * Key for setting and getting the global query context.\n */\nexport const SvelteQueryContextKey = 'zenstack-svelte-query-context';\n\n/**\n * Creates a svelte-query query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The svelte-query options object\n * @returns useQuery hook\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function query<R>(model: string, url: string, args?: unknown, options?: QueryOptions<R>, fetch?: FetchFn) {\n const reqUrl = makeUrl(url, args);\n return createQuery<R>({\n queryKey: [QUERY_KEY_PREFIX + model, url, args],\n queryFn: () => fetcher<R, false>(reqUrl, undefined, fetch, false),\n ...options,\n });\n}\n\n/**\n * Creates a POST mutation with svelte-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The svelte-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function postMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = createMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a PUT mutation with svelte-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The svelte-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function putMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'PUT',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = createMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a DELETE mutation with svelte-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The svelte-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function deleteMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n makeUrl(url, data),\n {\n method: 'DELETE',\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = createMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\nfunction mergeOptions<T, R = any>(\n model: string,\n options: Omit<MutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,\n invalidateQueries: boolean,\n mutationFn: MutateFunction<R, unknown, T>,\n queryClient: QueryClient\n): MutationOptions<R, unknown, T, unknown> {\n const result = { ...options, mutationFn };\n if (options?.onSuccess || invalidateQueries) {\n result.onSuccess = (...args) => {\n if (invalidateQueries) {\n queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);\n }\n return options?.onSuccess?.(...args);\n };\n }\n return result;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { serialize, deserialize } from '@zenstackhq/runtime/browser';\n\n/**\n * The default query endpoint.\n */\nexport const DEFAULT_QUERY_ENDPOINT = '/api/model';\n\n/**\n * Prefix for react-query keys.\n */\nexport const QUERY_KEY_PREFIX = 'zenstack:';\n\n/**\n * Function signature for `fetch`.\n */\nexport type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;\n\n/**\n * Context type for configuring the hooks.\n */\nexport type APIContext = {\n /**\n * The endpoint to use for the queries.\n */\n endpoint: string;\n\n /**\n * A custom fetch function for sending the HTTP requests.\n */\n fetch?: FetchFn;\n};\n\nexport async function fetcher<R, C extends boolean>(\n url: string,\n options?: RequestInit,\n fetch?: FetchFn,\n checkReadBack?: C\n): Promise<C extends true ? R | undefined : R> {\n const _fetch = fetch ?? window.fetch;\n const res = await _fetch(url, options);\n if (!res.ok) {\n const errData = unmarshal(await res.text());\n if (\n checkReadBack !== false &&\n errData.error?.prisma &&\n errData.error?.code === 'P2004' &&\n errData.error?.reason === 'RESULT_NOT_READABLE'\n ) {\n // policy doesn't allow mutation result to be read back, just return undefined\n return undefined as any;\n }\n const error: Error & { info?: unknown; status?: number } = new Error(\n 'An error occurred while fetching the data.'\n );\n error.info = errData.error;\n error.status = res.status;\n throw error;\n }\n\n const textResult = await res.text();\n try {\n return unmarshal(textResult).data as R;\n } catch (err) {\n console.error(`Unable to deserialize data:`, textResult);\n throw err;\n }\n}\n\nexport function marshal(value: unknown) {\n const { data, meta } = serialize(value);\n if (meta) {\n return JSON.stringify({ ...(data as any), meta: { serialization: meta } });\n } else {\n return JSON.stringify(data);\n }\n}\n\nexport function unmarshal(value: string) {\n const parsed = JSON.parse(value);\n if (parsed.data && parsed.meta?.serialization) {\n const deserializedData = deserialize(parsed.data, parsed.meta.serialization);\n return { ...parsed, data: deserializedData };\n } else {\n return parsed;\n }\n}\n\nexport function makeUrl(url: string, args: unknown) {\n if (!args) {\n return url;\n }\n\n const { data, meta } = serialize(args);\n let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;\n if (meta) {\n result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;\n }\n return result;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,186 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+
41
+ // src/runtime/svelte.ts
42
+ import {
43
+ createMutation,
44
+ createQuery,
45
+ useQueryClient
46
+ } from "@tanstack/svelte-query";
47
+
48
+ // src/runtime/common.ts
49
+ import { serialize, deserialize } from "@zenstackhq/runtime/browser";
50
+ var QUERY_KEY_PREFIX = "zenstack:";
51
+ function fetcher(url, options, fetch, checkReadBack) {
52
+ return __async(this, null, function* () {
53
+ var _a, _b, _c;
54
+ const _fetch = fetch != null ? fetch : window.fetch;
55
+ const res = yield _fetch(url, options);
56
+ if (!res.ok) {
57
+ const errData = unmarshal(yield res.text());
58
+ if (checkReadBack !== false && ((_a = errData.error) == null ? void 0 : _a.prisma) && ((_b = errData.error) == null ? void 0 : _b.code) === "P2004" && ((_c = errData.error) == null ? void 0 : _c.reason) === "RESULT_NOT_READABLE") {
59
+ return void 0;
60
+ }
61
+ const error = new Error(
62
+ "An error occurred while fetching the data."
63
+ );
64
+ error.info = errData.error;
65
+ error.status = res.status;
66
+ throw error;
67
+ }
68
+ const textResult = yield res.text();
69
+ try {
70
+ return unmarshal(textResult).data;
71
+ } catch (err) {
72
+ console.error(`Unable to deserialize data:`, textResult);
73
+ throw err;
74
+ }
75
+ });
76
+ }
77
+ function marshal(value) {
78
+ const { data, meta } = serialize(value);
79
+ if (meta) {
80
+ return JSON.stringify(__spreadProps(__spreadValues({}, data), { meta: { serialization: meta } }));
81
+ } else {
82
+ return JSON.stringify(data);
83
+ }
84
+ }
85
+ function unmarshal(value) {
86
+ var _a;
87
+ const parsed = JSON.parse(value);
88
+ if (parsed.data && ((_a = parsed.meta) == null ? void 0 : _a.serialization)) {
89
+ const deserializedData = deserialize(parsed.data, parsed.meta.serialization);
90
+ return __spreadProps(__spreadValues({}, parsed), { data: deserializedData });
91
+ } else {
92
+ return parsed;
93
+ }
94
+ }
95
+ function makeUrl(url, args) {
96
+ if (!args) {
97
+ return url;
98
+ }
99
+ const { data, meta } = serialize(args);
100
+ let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;
101
+ if (meta) {
102
+ result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;
103
+ }
104
+ return result;
105
+ }
106
+
107
+ // src/runtime/svelte.ts
108
+ var SvelteQueryContextKey = "zenstack-svelte-query-context";
109
+ function query(model, url, args, options, fetch) {
110
+ const reqUrl = makeUrl(url, args);
111
+ return createQuery(__spreadValues({
112
+ queryKey: [QUERY_KEY_PREFIX + model, url, args],
113
+ queryFn: () => fetcher(reqUrl, void 0, fetch, false)
114
+ }, options));
115
+ }
116
+ function postMutation(model, url, options, fetch, invalidateQueries = true, checkReadBack) {
117
+ const queryClient = useQueryClient();
118
+ const mutationFn = (data) => fetcher(
119
+ url,
120
+ {
121
+ method: "POST",
122
+ headers: {
123
+ "content-type": "application/json"
124
+ },
125
+ body: marshal(data)
126
+ },
127
+ fetch,
128
+ checkReadBack
129
+ );
130
+ const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
131
+ const mutation = createMutation(finalOptions);
132
+ return mutation;
133
+ }
134
+ function putMutation(model, url, options, fetch, invalidateQueries = true, checkReadBack) {
135
+ const queryClient = useQueryClient();
136
+ const mutationFn = (data) => fetcher(
137
+ url,
138
+ {
139
+ method: "PUT",
140
+ headers: {
141
+ "content-type": "application/json"
142
+ },
143
+ body: marshal(data)
144
+ },
145
+ fetch,
146
+ checkReadBack
147
+ );
148
+ const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
149
+ const mutation = createMutation(finalOptions);
150
+ return mutation;
151
+ }
152
+ function deleteMutation(model, url, options, fetch, invalidateQueries = true, checkReadBack) {
153
+ const queryClient = useQueryClient();
154
+ const mutationFn = (data) => fetcher(
155
+ makeUrl(url, data),
156
+ {
157
+ method: "DELETE"
158
+ },
159
+ fetch,
160
+ checkReadBack
161
+ );
162
+ const finalOptions = mergeOptions(model, options, invalidateQueries, mutationFn, queryClient);
163
+ const mutation = createMutation(finalOptions);
164
+ return mutation;
165
+ }
166
+ function mergeOptions(model, options, invalidateQueries, mutationFn, queryClient) {
167
+ const result = __spreadProps(__spreadValues({}, options), { mutationFn });
168
+ if ((options == null ? void 0 : options.onSuccess) || invalidateQueries) {
169
+ result.onSuccess = (...args) => {
170
+ var _a;
171
+ if (invalidateQueries) {
172
+ queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);
173
+ }
174
+ return (_a = options == null ? void 0 : options.onSuccess) == null ? void 0 : _a.call(options, ...args);
175
+ };
176
+ }
177
+ return result;
178
+ }
179
+ export {
180
+ SvelteQueryContextKey,
181
+ deleteMutation,
182
+ postMutation,
183
+ putMutation,
184
+ query
185
+ };
186
+ //# sourceMappingURL=svelte.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/runtime/svelte.ts","../../src/runtime/common.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n createMutation,\n createQuery,\n useQueryClient,\n type MutateFunction,\n type MutationOptions,\n type QueryClient,\n type QueryOptions,\n} from '@tanstack/svelte-query';\nimport { FetchFn, QUERY_KEY_PREFIX, fetcher, makeUrl, marshal } from './common';\n\nexport { APIContext as RequestHandlerContext } from './common';\n\n/**\n * Key for setting and getting the global query context.\n */\nexport const SvelteQueryContextKey = 'zenstack-svelte-query-context';\n\n/**\n * Creates a svelte-query query.\n *\n * @param model The name of the model under query.\n * @param url The request URL.\n * @param args The request args object, URL-encoded and appended as \"?q=\" parameter\n * @param options The svelte-query options object\n * @returns useQuery hook\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function query<R>(model: string, url: string, args?: unknown, options?: QueryOptions<R>, fetch?: FetchFn) {\n const reqUrl = makeUrl(url, args);\n return createQuery<R>({\n queryKey: [QUERY_KEY_PREFIX + model, url, args],\n queryFn: () => fetcher<R, false>(reqUrl, undefined, fetch, false),\n ...options,\n });\n}\n\n/**\n * Creates a POST mutation with svelte-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The svelte-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function postMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = createMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a PUT mutation with svelte-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The svelte-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function putMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n url,\n {\n method: 'PUT',\n headers: {\n 'content-type': 'application/json',\n },\n body: marshal(data),\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = createMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\n/**\n * Creates a DELETE mutation with svelte-query.\n *\n * @param model The name of the model under mutation.\n * @param url The request URL.\n * @param options The svelte-query options.\n * @param invalidateQueries Whether to invalidate queries after mutation.\n * @returns useMutation hooks\n */\nexport function deleteMutation<T, R = any, C extends boolean = boolean, Result = C extends true ? R | undefined : R>(\n model: string,\n url: string,\n options?: Omit<MutationOptions<Result, unknown, T>, 'mutationFn'>,\n fetch?: FetchFn,\n invalidateQueries = true,\n checkReadBack?: C\n) {\n const queryClient = useQueryClient();\n const mutationFn = (data: any) =>\n fetcher<R, C>(\n makeUrl(url, data),\n {\n method: 'DELETE',\n },\n fetch,\n checkReadBack\n ) as Promise<Result>;\n\n const finalOptions = mergeOptions<T, Result>(model, options, invalidateQueries, mutationFn, queryClient);\n const mutation = createMutation<Result, unknown, T>(finalOptions);\n return mutation;\n}\n\nfunction mergeOptions<T, R = any>(\n model: string,\n options: Omit<MutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,\n invalidateQueries: boolean,\n mutationFn: MutateFunction<R, unknown, T>,\n queryClient: QueryClient\n): MutationOptions<R, unknown, T, unknown> {\n const result = { ...options, mutationFn };\n if (options?.onSuccess || invalidateQueries) {\n result.onSuccess = (...args) => {\n if (invalidateQueries) {\n queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);\n }\n return options?.onSuccess?.(...args);\n };\n }\n return result;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { serialize, deserialize } from '@zenstackhq/runtime/browser';\n\n/**\n * The default query endpoint.\n */\nexport const DEFAULT_QUERY_ENDPOINT = '/api/model';\n\n/**\n * Prefix for react-query keys.\n */\nexport const QUERY_KEY_PREFIX = 'zenstack:';\n\n/**\n * Function signature for `fetch`.\n */\nexport type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;\n\n/**\n * Context type for configuring the hooks.\n */\nexport type APIContext = {\n /**\n * The endpoint to use for the queries.\n */\n endpoint: string;\n\n /**\n * A custom fetch function for sending the HTTP requests.\n */\n fetch?: FetchFn;\n};\n\nexport async function fetcher<R, C extends boolean>(\n url: string,\n options?: RequestInit,\n fetch?: FetchFn,\n checkReadBack?: C\n): Promise<C extends true ? R | undefined : R> {\n const _fetch = fetch ?? window.fetch;\n const res = await _fetch(url, options);\n if (!res.ok) {\n const errData = unmarshal(await res.text());\n if (\n checkReadBack !== false &&\n errData.error?.prisma &&\n errData.error?.code === 'P2004' &&\n errData.error?.reason === 'RESULT_NOT_READABLE'\n ) {\n // policy doesn't allow mutation result to be read back, just return undefined\n return undefined as any;\n }\n const error: Error & { info?: unknown; status?: number } = new Error(\n 'An error occurred while fetching the data.'\n );\n error.info = errData.error;\n error.status = res.status;\n throw error;\n }\n\n const textResult = await res.text();\n try {\n return unmarshal(textResult).data as R;\n } catch (err) {\n console.error(`Unable to deserialize data:`, textResult);\n throw err;\n }\n}\n\nexport function marshal(value: unknown) {\n const { data, meta } = serialize(value);\n if (meta) {\n return JSON.stringify({ ...(data as any), meta: { serialization: meta } });\n } else {\n return JSON.stringify(data);\n }\n}\n\nexport function unmarshal(value: string) {\n const parsed = JSON.parse(value);\n if (parsed.data && parsed.meta?.serialization) {\n const deserializedData = deserialize(parsed.data, parsed.meta.serialization);\n return { ...parsed, data: deserializedData };\n } else {\n return parsed;\n }\n}\n\nexport function makeUrl(url: string, args: unknown) {\n if (!args) {\n return url;\n }\n\n const { data, meta } = serialize(args);\n let result = `${url}?q=${encodeURIComponent(JSON.stringify(data))}`;\n if (meta) {\n result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;\n }\n return result;\n}\n"],"mappings":"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","names":[]}
@@ -1,12 +0,0 @@
1
- function marshal(value: unknown) {
2
- return JSON.stringify(value);
3
- }
4
-
5
- function unmarshal(value: string) {
6
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
- return JSON.parse(value) as any;
8
- }
9
-
10
- function makeUrl(url: string, args: unknown) {
11
- return args ? url + `?q=${encodeURIComponent(JSON.stringify(args))}` : url;
12
- }
@@ -1,20 +0,0 @@
1
- import superjson from 'superjson';
2
-
3
- function marshal(value: unknown) {
4
- return superjson.stringify(value);
5
- }
6
-
7
- function unmarshal(value: string) {
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- const j = JSON.parse(value) as any;
10
- if (j?.json) {
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- return superjson.parse<any>(value);
13
- } else {
14
- return j;
15
- }
16
- }
17
-
18
- function makeUrl(url: string, args: unknown) {
19
- return args ? url + `?q=${encodeURIComponent(superjson.stringify(args))}` : url;
20
- }
@@ -1,148 +0,0 @@
1
- /* eslint-disable */
2
-
3
- import {
4
- useMutation,
5
- useQuery,
6
- useQueryClient,
7
- type MutateFunction,
8
- type QueryClient,
9
- type UseMutationOptions,
10
- type UseQueryOptions,
11
- } from '@tanstack/react-query';
12
- import { createContext } from 'react';
13
-
14
- /**
15
- * Context for configuring react hooks.
16
- */
17
- export const RequestHandlerContext = createContext<RequestHandlerContext>({
18
- endpoint: DEFAULT_QUERY_ENDPOINT,
19
- });
20
-
21
- /**
22
- * Context provider.
23
- */
24
- export const Provider = RequestHandlerContext.Provider;
25
-
26
- /**
27
- * Creates a react-query query.
28
- *
29
- * @param model The name of the model under query.
30
- * @param url The request URL.
31
- * @param args The request args object, URL-encoded and appended as "?q=" parameter
32
- * @param options The react-query options object
33
- * @returns useQuery hook
34
- */
35
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
- export function query<R>(model: string, url: string, args?: unknown, options?: UseQueryOptions<R>) {
37
- const reqUrl = makeUrl(url, args);
38
- return useQuery<R>({
39
- queryKey: [QUERY_KEY_PREFIX + model, url, args],
40
- queryFn: () => fetcher<R>(reqUrl),
41
- ...options,
42
- });
43
- }
44
-
45
- /**
46
- * Creates a POST mutation with react-query.
47
- *
48
- * @param model The name of the model under mutation.
49
- * @param url The request URL.
50
- * @param options The react-query options.
51
- * @param invalidateQueries Whether to invalidate queries after mutation.
52
- * @returns useMutation hooks
53
- */
54
- export function postMutation<T, R = any>(
55
- model: string,
56
- url: string,
57
- options?: Omit<UseMutationOptions<R, unknown, T>, 'mutationFn'>,
58
- invalidateQueries = true
59
- ) {
60
- const queryClient = useQueryClient();
61
- const mutationFn = (data: any) =>
62
- fetcher<R>(url, {
63
- method: 'POST',
64
- headers: {
65
- 'content-type': 'application/json',
66
- },
67
- body: marshal(data),
68
- });
69
-
70
- const finalOptions = mergeOptions<T, R>(model, options, invalidateQueries, mutationFn, queryClient);
71
- const mutation = useMutation<R, unknown, T>(finalOptions);
72
- return mutation;
73
- }
74
-
75
- /**
76
- * Creates a PUT mutation with react-query.
77
- *
78
- * @param model The name of the model under mutation.
79
- * @param url The request URL.
80
- * @param options The react-query options.
81
- * @param invalidateQueries Whether to invalidate queries after mutation.
82
- * @returns useMutation hooks
83
- */
84
- export function putMutation<T, R = any>(
85
- model: string,
86
- url: string,
87
- options?: Omit<UseMutationOptions<R, unknown, T>, 'mutationFn'>,
88
- invalidateQueries = true
89
- ) {
90
- const queryClient = useQueryClient();
91
- const mutationFn = (data: any) =>
92
- fetcher<R>(url, {
93
- method: 'PUT',
94
- headers: {
95
- 'content-type': 'application/json',
96
- },
97
- body: marshal(data),
98
- });
99
-
100
- const finalOptions = mergeOptions<T, R>(model, options, invalidateQueries, mutationFn, queryClient);
101
- const mutation = useMutation<R, unknown, T>(finalOptions);
102
- return mutation;
103
- }
104
-
105
- /**
106
- * Creates a DELETE mutation with react-query.
107
- *
108
- * @param model The name of the model under mutation.
109
- * @param url The request URL.
110
- * @param options The react-query options.
111
- * @param invalidateQueries Whether to invalidate queries after mutation.
112
- * @returns useMutation hooks
113
- */
114
- export function deleteMutation<T, R = any>(
115
- model: string,
116
- url: string,
117
- options?: Omit<UseMutationOptions<R, unknown, T>, 'mutationFn'>,
118
- invalidateQueries = true
119
- ) {
120
- const queryClient = useQueryClient();
121
- const mutationFn = (data: any) =>
122
- fetcher<R>(makeUrl(url, data), {
123
- method: 'DELETE',
124
- });
125
-
126
- const finalOptions = mergeOptions<T, R>(model, options, invalidateQueries, mutationFn, queryClient);
127
- const mutation = useMutation<R, unknown, T>(finalOptions);
128
- return mutation;
129
- }
130
-
131
- function mergeOptions<T, R = any>(
132
- model: string,
133
- options: Omit<UseMutationOptions<R, unknown, T, unknown>, 'mutationFn'> | undefined,
134
- invalidateQueries: boolean,
135
- mutationFn: MutateFunction<R, unknown, T>,
136
- queryClient: QueryClient
137
- ): UseMutationOptions<R, unknown, T, unknown> {
138
- const result = { ...options, mutationFn };
139
- if (options?.onSuccess || invalidateQueries) {
140
- result.onSuccess = (...args) => {
141
- if (invalidateQueries) {
142
- queryClient.invalidateQueries([QUERY_KEY_PREFIX + model]);
143
- }
144
- return options?.onSuccess?.(...args);
145
- };
146
- }
147
- return result;
148
- }
package/res/shared.ts DELETED
@@ -1,36 +0,0 @@
1
- /**
2
- * The default query endpoint.
3
- */
4
- export const DEFAULT_QUERY_ENDPOINT = '/api/model';
5
-
6
- /**
7
- * Prefix for react-query keys.
8
- */
9
- export const QUERY_KEY_PREFIX = 'zenstack:';
10
-
11
- /**
12
- * Context type for configuring the hooks.
13
- */
14
- export type RequestHandlerContext = {
15
- endpoint: string;
16
- };
17
-
18
- async function fetcher<R>(url: string, options?: RequestInit) {
19
- const res = await fetch(url, options);
20
- if (!res.ok) {
21
- const error: Error & { info?: unknown; status?: number } = new Error(
22
- 'An error occurred while fetching the data.'
23
- );
24
- error.info = unmarshal(await res.text());
25
- error.status = res.status;
26
- throw error;
27
- }
28
-
29
- const textResult = await res.text();
30
- try {
31
- return unmarshal(textResult) as R;
32
- } catch (err) {
33
- console.error(`Unable to deserialize data:`, textResult);
34
- throw err;
35
- }
36
- }