@zenstackhq/client-helpers 3.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.
@@ -0,0 +1,24 @@
1
+
2
+ > @zenstackhq/client-helpers@3.1.0 build /home/runner/work/zenstack-v3/zenstack-v3/packages/clients/client-helpers
3
+ > tsc --noEmit && tsup-node && pnpm test:typecheck
4
+
5
+ CLI Building entry: {"index":"src/index.ts","fetch":"src/fetch.ts"}
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.5.0
8
+ CLI Using tsup config: /home/runner/work/zenstack-v3/zenstack-v3/packages/clients/client-helpers/tsup.config.ts
9
+ CLI Target: esnext
10
+ CLI Cleaning output folder
11
+ ESM Build start
12
+ ESM dist/index.js 25.68 KB
13
+ ESM dist/fetch.js 2.73 KB
14
+ ESM dist/index.js.map 63.32 KB
15
+ ESM dist/fetch.js.map 5.94 KB
16
+ ESM ⚡️ Build success in 136ms
17
+ DTS Build start
18
+ DTS ⚡️ Build success in 5075ms
19
+ DTS dist/index.d.ts 10.28 KB
20
+ DTS dist/fetch.d.ts 1.24 KB
21
+
22
+ > @zenstackhq/client-helpers@3.1.0 test:typecheck /home/runner/work/zenstack-v3/zenstack-v3/packages/clients/client-helpers
23
+ > tsc --noEmit --project tsconfig.test.json
24
+
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 ZenStack
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Function signature for `fetch`.
3
+ */
4
+ type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;
5
+ /**
6
+ * A fetcher function that uses fetch API to make HTTP requests and automatically unmarshals
7
+ * the response using superjson.
8
+ */
9
+ declare function fetcher<R>(url: string, options?: RequestInit, customFetch?: FetchFn): Promise<R>;
10
+ /**
11
+ * Makes a URL for the given endpoint, model, operation, and args that matches the RPC-style server API.
12
+ */
13
+ declare function makeUrl(endpoint: string, model: string, operation: string, args?: unknown): string;
14
+ /**
15
+ * Serialize the given value with superjson
16
+ */
17
+ declare function serialize(value: unknown): {
18
+ data: unknown;
19
+ meta: unknown;
20
+ };
21
+ /**
22
+ * Deserialize the given value with superjson using the given metadata
23
+ */
24
+ declare function deserialize(value: unknown, meta: any): unknown;
25
+ /**
26
+ * Marshal the given value to a string using superjson
27
+ */
28
+ declare function marshal(value: unknown): string;
29
+ /**
30
+ * Unmarshal the given string value using superjson, assuming the value is a JSON stringified
31
+ * object containing the serialized data and serialization metadata.
32
+ */
33
+ declare function unmarshal(value: string): any;
34
+
35
+ export { type FetchFn, deserialize, fetcher, makeUrl, marshal, serialize, unmarshal };
package/dist/fetch.js ADDED
@@ -0,0 +1,101 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/fetch.ts
5
+ import { lowerCaseFirst } from "@zenstackhq/common-helpers";
6
+ import Decimal from "decimal.js";
7
+ import SuperJSON from "superjson";
8
+ async function fetcher(url, options, customFetch) {
9
+ const _fetch = customFetch ?? fetch;
10
+ const res = await _fetch(url, options);
11
+ if (!res.ok) {
12
+ const errData = unmarshal(await res.text());
13
+ if (errData.error?.rejectedByPolicy && errData.error?.rejectReason === "cannot-read-back") {
14
+ return void 0;
15
+ }
16
+ const error = new Error("An error occurred while fetching the data.");
17
+ error.info = errData.error;
18
+ error.status = res.status;
19
+ throw error;
20
+ }
21
+ const textResult = await res.text();
22
+ try {
23
+ return unmarshal(textResult).data;
24
+ } catch (err) {
25
+ console.error(`Unable to deserialize data:`, textResult);
26
+ throw err;
27
+ }
28
+ }
29
+ __name(fetcher, "fetcher");
30
+ function makeUrl(endpoint, model, operation, args) {
31
+ const baseUrl = `${endpoint}/${lowerCaseFirst(model)}/${operation}`;
32
+ if (!args) {
33
+ return baseUrl;
34
+ }
35
+ const { data, meta } = serialize(args);
36
+ let result = `${baseUrl}?q=${encodeURIComponent(JSON.stringify(data))}`;
37
+ if (meta) {
38
+ result += `&meta=${encodeURIComponent(JSON.stringify({
39
+ serialization: meta
40
+ }))}`;
41
+ }
42
+ return result;
43
+ }
44
+ __name(makeUrl, "makeUrl");
45
+ SuperJSON.registerCustom({
46
+ isApplicable: /* @__PURE__ */ __name((v) => v instanceof Decimal || // interop with decimal.js
47
+ v?.toStringTag === "[object Decimal]", "isApplicable"),
48
+ serialize: /* @__PURE__ */ __name((v) => v.toJSON(), "serialize"),
49
+ deserialize: /* @__PURE__ */ __name((v) => new Decimal(v), "deserialize")
50
+ }, "Decimal");
51
+ function serialize(value) {
52
+ const { json, meta } = SuperJSON.serialize(value);
53
+ return {
54
+ data: json,
55
+ meta
56
+ };
57
+ }
58
+ __name(serialize, "serialize");
59
+ function deserialize(value, meta) {
60
+ return SuperJSON.deserialize({
61
+ json: value,
62
+ meta
63
+ });
64
+ }
65
+ __name(deserialize, "deserialize");
66
+ function marshal(value) {
67
+ const { data, meta } = serialize(value);
68
+ if (meta) {
69
+ return JSON.stringify({
70
+ ...data,
71
+ meta: {
72
+ serialization: meta
73
+ }
74
+ });
75
+ } else {
76
+ return JSON.stringify(data);
77
+ }
78
+ }
79
+ __name(marshal, "marshal");
80
+ function unmarshal(value) {
81
+ const parsed = JSON.parse(value);
82
+ if (typeof parsed === "object" && parsed?.data && parsed?.meta?.serialization) {
83
+ const deserializedData = deserialize(parsed.data, parsed.meta.serialization);
84
+ return {
85
+ ...parsed,
86
+ data: deserializedData
87
+ };
88
+ } else {
89
+ return parsed;
90
+ }
91
+ }
92
+ __name(unmarshal, "unmarshal");
93
+ export {
94
+ deserialize,
95
+ fetcher,
96
+ makeUrl,
97
+ marshal,
98
+ serialize,
99
+ unmarshal
100
+ };
101
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/fetch.ts"],"sourcesContent":["import { lowerCaseFirst } from '@zenstackhq/common-helpers';\nimport Decimal from 'decimal.js';\nimport SuperJSON from 'superjson';\nimport type { QueryError } from './types';\n\n/**\n * Function signature for `fetch`.\n */\nexport type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;\n\n/**\n * A fetcher function that uses fetch API to make HTTP requests and automatically unmarshals\n * the response using superjson.\n */\nexport async function fetcher<R>(url: string, options?: RequestInit, customFetch?: FetchFn): Promise<R> {\n const _fetch = customFetch ?? fetch;\n const res = await _fetch(url, options);\n if (!res.ok) {\n const errData = unmarshal(await res.text());\n if (errData.error?.rejectedByPolicy && errData.error?.rejectReason === 'cannot-read-back') {\n // policy doesn't allow mutation result to be read back, just return undefined\n return undefined as any;\n }\n const error: QueryError = new Error('An error occurred while fetching the data.');\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\n/**\n * Makes a URL for the given endpoint, model, operation, and args that matches the RPC-style server API.\n */\nexport function makeUrl(endpoint: string, model: string, operation: string, args?: unknown) {\n const baseUrl = `${endpoint}/${lowerCaseFirst(model)}/${operation}`;\n if (!args) {\n return baseUrl;\n }\n\n const { data, meta } = serialize(args);\n let result = `${baseUrl}?q=${encodeURIComponent(JSON.stringify(data))}`;\n if (meta) {\n result += `&meta=${encodeURIComponent(JSON.stringify({ serialization: meta }))}`;\n }\n return result;\n}\n\nSuperJSON.registerCustom<Decimal, string>(\n {\n isApplicable: (v): v is Decimal =>\n v instanceof Decimal ||\n // interop with decimal.js\n v?.toStringTag === '[object Decimal]',\n serialize: (v) => v.toJSON(),\n deserialize: (v) => new Decimal(v),\n },\n 'Decimal',\n);\n\n/**\n * Serialize the given value with superjson\n */\nexport function serialize(value: unknown): { data: unknown; meta: unknown } {\n const { json, meta } = SuperJSON.serialize(value);\n return { data: json, meta };\n}\n\n/**\n * Deserialize the given value with superjson using the given metadata\n */\nexport function deserialize(value: unknown, meta: any): unknown {\n return SuperJSON.deserialize({ json: value as any, meta });\n}\n\n/**\n * Marshal the given value to a string using superjson\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\n/**\n * Unmarshal the given string value using superjson, assuming the value is a JSON stringified\n * object containing the serialized data and serialization metadata.\n */\nexport function unmarshal(value: string) {\n const parsed = JSON.parse(value);\n if (typeof parsed === 'object' && 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"],"mappings":";;;;AAAA,SAASA,sBAAsB;AAC/B,OAAOC,aAAa;AACpB,OAAOC,eAAe;AAYtB,eAAsBC,QAAWC,KAAaC,SAAuBC,aAAqB;AACtF,QAAMC,SAASD,eAAeE;AAC9B,QAAMC,MAAM,MAAMF,OAAOH,KAAKC,OAAAA;AAC9B,MAAI,CAACI,IAAIC,IAAI;AACT,UAAMC,UAAUC,UAAU,MAAMH,IAAII,KAAI,CAAA;AACxC,QAAIF,QAAQG,OAAOC,oBAAoBJ,QAAQG,OAAOE,iBAAiB,oBAAoB;AAEvF,aAAOC;IACX;AACA,UAAMH,QAAoB,IAAII,MAAM,4CAAA;AACpCJ,UAAMK,OAAOR,QAAQG;AACrBA,UAAMM,SAASX,IAAIW;AACnB,UAAMN;EACV;AAEA,QAAMO,aAAa,MAAMZ,IAAII,KAAI;AACjC,MAAI;AACA,WAAOD,UAAUS,UAAAA,EAAYC;EACjC,SAASC,KAAK;AACVC,YAAQV,MAAM,+BAA+BO,UAAAA;AAC7C,UAAME;EACV;AACJ;AAtBsBpB;AA2Bf,SAASsB,QAAQC,UAAkBC,OAAeC,WAAmBC,MAAc;AACtF,QAAMC,UAAU,GAAGJ,QAAAA,IAAYK,eAAeJ,KAAAA,CAAAA,IAAUC,SAAAA;AACxD,MAAI,CAACC,MAAM;AACP,WAAOC;EACX;AAEA,QAAM,EAAER,MAAMU,KAAI,IAAKC,UAAUJ,IAAAA;AACjC,MAAIK,SAAS,GAAGJ,OAAAA,MAAaK,mBAAmBC,KAAKC,UAAUf,IAAAA,CAAAA,CAAAA;AAC/D,MAAIU,MAAM;AACNE,cAAU,SAASC,mBAAmBC,KAAKC,UAAU;MAAEC,eAAeN;IAAK,CAAA,CAAA,CAAA;EAC/E;AACA,SAAOE;AACX;AAZgBT;AAchBc,UAAUC,eACN;EACIC,cAAc,wBAACC,MACXA,aAAaC;EAEbD,GAAGE,gBAAgB,oBAHT;EAIdX,WAAW,wBAACS,MAAMA,EAAEG,OAAM,GAAf;EACXC,aAAa,wBAACJ,MAAM,IAAIC,QAAQD,CAAAA,GAAnB;AACjB,GACA,SAAA;AAMG,SAAST,UAAUc,OAAc;AACpC,QAAM,EAAEC,MAAMhB,KAAI,IAAKO,UAAUN,UAAUc,KAAAA;AAC3C,SAAO;IAAEzB,MAAM0B;IAAMhB;EAAK;AAC9B;AAHgBC;AAQT,SAASa,YAAYC,OAAgBf,MAAS;AACjD,SAAOO,UAAUO,YAAY;IAAEE,MAAMD;IAAcf;EAAK,CAAA;AAC5D;AAFgBc;AAOT,SAASG,QAAQF,OAAc;AAClC,QAAM,EAAEzB,MAAMU,KAAI,IAAKC,UAAUc,KAAAA;AACjC,MAAIf,MAAM;AACN,WAAOI,KAAKC,UAAU;MAAE,GAAIf;MAAcU,MAAM;QAAEM,eAAeN;MAAK;IAAE,CAAA;EAC5E,OAAO;AACH,WAAOI,KAAKC,UAAUf,IAAAA;EAC1B;AACJ;AAPgB2B;AAaT,SAASrC,UAAUmC,OAAa;AACnC,QAAMG,SAASd,KAAKe,MAAMJ,KAAAA;AAC1B,MAAI,OAAOG,WAAW,YAAYA,QAAQ5B,QAAQ4B,QAAQlB,MAAMM,eAAe;AAC3E,UAAMc,mBAAmBN,YAAYI,OAAO5B,MAAM4B,OAAOlB,KAAKM,aAAa;AAC3E,WAAO;MAAE,GAAGY;MAAQ5B,MAAM8B;IAAiB;EAC/C,OAAO;AACH,WAAOF;EACX;AACJ;AARgBtC;","names":["lowerCaseFirst","Decimal","SuperJSON","fetcher","url","options","customFetch","_fetch","fetch","res","ok","errData","unmarshal","text","error","rejectedByPolicy","rejectReason","undefined","Error","info","status","textResult","data","err","console","makeUrl","endpoint","model","operation","args","baseUrl","lowerCaseFirst","meta","serialize","result","encodeURIComponent","JSON","stringify","serialization","SuperJSON","registerCustom","isApplicable","v","Decimal","toStringTag","toJSON","deserialize","value","json","marshal","parsed","parse","deserializedData"]}
@@ -0,0 +1,278 @@
1
+ import { SchemaDef, FieldDef } from '@zenstackhq/schema';
2
+
3
+ /**
4
+ * The default query endpoint.
5
+ */
6
+ declare const DEFAULT_QUERY_ENDPOINT = "/api/model";
7
+
8
+ /**
9
+ * Logger configuration. `true` enables console logging. A function can be provided for custom logging.
10
+ */
11
+ type Logger = boolean | ((message: string) => void);
12
+ /**
13
+ * Logs a message using the provided logger.
14
+ */
15
+ declare function log(logger: Logger, message: string): void;
16
+
17
+ /**
18
+ * A type that represents either a value of type T or a Promise that resolves to type T.
19
+ */
20
+ type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;
21
+ /**
22
+ * List of ORM write actions.
23
+ */
24
+ declare const ORMWriteActions: readonly ["create", "createMany", "createManyAndReturn", "connectOrCreate", "update", "updateMany", "updateManyAndReturn", "upsert", "connect", "disconnect", "set", "delete", "deleteMany"];
25
+ /**
26
+ * Type representing ORM write action types.
27
+ */
28
+ type ORMWriteActionType = (typeof ORMWriteActions)[number];
29
+ /**
30
+ * Type for query and mutation errors.
31
+ */
32
+ type QueryError = Error & {
33
+ /**
34
+ * Additional error information.
35
+ */
36
+ info?: unknown;
37
+ /**
38
+ * HTTP status code.
39
+ */
40
+ status?: number;
41
+ };
42
+ /**
43
+ * Information about a cached query.
44
+ */
45
+ type QueryInfo = {
46
+ /**
47
+ * Model of the query.
48
+ */
49
+ model: string;
50
+ /**
51
+ * Query operation, e.g., `findUnique`
52
+ */
53
+ operation: string;
54
+ /**
55
+ * Query arguments.
56
+ */
57
+ args: unknown;
58
+ /**
59
+ * Current data cached for this query.
60
+ */
61
+ data: unknown;
62
+ /**
63
+ * Whether optimistic update is enabled for this query.
64
+ */
65
+ optimisticUpdate: boolean;
66
+ /**
67
+ * Function to update the cached data.
68
+ *
69
+ * @param data New data to set.
70
+ * @param cancelOnTheFlyQueries Whether to cancel on-the-fly queries to avoid accidentally
71
+ * overwriting the optimistic update.
72
+ */
73
+ updateData: (data: unknown, cancelOnTheFlyQueries: boolean) => void;
74
+ };
75
+
76
+ /**
77
+ * Type for a predicate that determines whether a query should be invalidated.
78
+ */
79
+ type InvalidationPredicate = ({ model, args }: {
80
+ model: string;
81
+ args: unknown;
82
+ }) => boolean;
83
+ /**
84
+ * Type for a function that invalidates queries matching the given predicate.
85
+ */
86
+ type InvalidateFunc = (predicate: InvalidationPredicate) => MaybePromise<void>;
87
+ /**
88
+ * Create a function that invalidates queries affected by the given mutation operation.
89
+ *
90
+ * @param model Model under mutation.
91
+ * @param operation Mutation operation (e.g, `update`).
92
+ * @param schema The schema.
93
+ * @param invalidator Function to invalidate queries matching a predicate. It should internally
94
+ * enumerate all query cache entries and invalidate those for which the predicate returns true.
95
+ * @param logging Logging option.
96
+ */
97
+ declare function createInvalidator(model: string, operation: string, schema: SchemaDef, invalidator: InvalidateFunc, logging: Logger | undefined): (...args: unknown[]) => Promise<void>;
98
+
99
+ /**
100
+ * Tries to apply a mutation to a query result.
101
+ *
102
+ * @param queryModel the model of the query
103
+ * @param queryOp the operation of the query
104
+ * @param queryData the result data of the query
105
+ * @param mutationModel the model of the mutation
106
+ * @param mutationOp the operation of the mutation
107
+ * @param mutationArgs the arguments of the mutation
108
+ * @param schema the schema
109
+ * @param logging logging configuration
110
+ * @returns the updated query data if the mutation is applicable, otherwise undefined
111
+ */
112
+ declare function applyMutation(queryModel: string, queryOp: string, queryData: any, mutationModel: string, mutationOp: ORMWriteActionType, mutationArgs: any, schema: SchemaDef, logging: Logger | undefined): Promise<any>;
113
+
114
+ /**
115
+ * Callback functions for nested read visitor.
116
+ */
117
+ type NestedReadVisitorCallback = {
118
+ /**
119
+ * Callback for each field visited.
120
+ * @returns If returns false, traversal will not continue into this field.
121
+ */
122
+ field?: (model: string, field: FieldDef | undefined, kind: 'include' | 'select' | undefined, args: unknown) => void | boolean;
123
+ };
124
+ /**
125
+ * Visitor for nested read payload.
126
+ */
127
+ declare class NestedReadVisitor {
128
+ private readonly schema;
129
+ private readonly callback;
130
+ constructor(schema: SchemaDef, callback: NestedReadVisitorCallback);
131
+ private doVisit;
132
+ visit(model: string, args: unknown): void;
133
+ }
134
+
135
+ type NestingPathItem = {
136
+ field?: FieldDef;
137
+ model: string;
138
+ where: any;
139
+ unique: boolean;
140
+ };
141
+ /**
142
+ * Context for visiting
143
+ */
144
+ type NestedWriteVisitorContext = {
145
+ /**
146
+ * Parent data, can be used to replace fields
147
+ */
148
+ parent: any;
149
+ /**
150
+ * Current field, undefined if toplevel
151
+ */
152
+ field?: FieldDef;
153
+ /**
154
+ * A top-down path of all nested update conditions and corresponding field till now
155
+ */
156
+ nestingPath: NestingPathItem[];
157
+ };
158
+ /**
159
+ * NestedWriteVisitor's callback actions. A call back function should return true or void to indicate
160
+ * that the visitor should continue traversing its children, or false to stop. It can also return an object
161
+ * to let the visitor traverse it instead of its original children.
162
+ */
163
+ type NestedWriteVisitorCallback = {
164
+ create?: (model: string, data: any, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
165
+ createMany?: (model: string, args: {
166
+ data: any;
167
+ skipDuplicates?: boolean;
168
+ }, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
169
+ connectOrCreate?: (model: string, args: {
170
+ where: object;
171
+ create: any;
172
+ }, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
173
+ connect?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
174
+ disconnect?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
175
+ set?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
176
+ update?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
177
+ updateMany?: (model: string, args: {
178
+ where?: object;
179
+ data: any;
180
+ }, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
181
+ upsert?: (model: string, args: {
182
+ where: object;
183
+ create: any;
184
+ update: any;
185
+ }, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
186
+ delete?: (model: string, args: object | boolean, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
187
+ deleteMany?: (model: string, args: any | object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;
188
+ field?: (field: FieldDef, action: ORMWriteActionType, data: any, context: NestedWriteVisitorContext) => MaybePromise<void>;
189
+ };
190
+ /**
191
+ * Recursive visitor for nested write (create/update) payload.
192
+ */
193
+ declare class NestedWriteVisitor {
194
+ private readonly schema;
195
+ private readonly callback;
196
+ constructor(schema: SchemaDef, callback: NestedWriteVisitorCallback);
197
+ private isWriteAction;
198
+ /**
199
+ * Start visiting
200
+ *
201
+ * @see NestedWriteVisitorCallback
202
+ */
203
+ visit(model: string, action: ORMWriteActionType, args: any): Promise<void>;
204
+ private doVisit;
205
+ private visitSubPayload;
206
+ private enumerateReverse;
207
+ }
208
+
209
+ /**
210
+ * Custom optimistic data provider. It takes query information (usually fetched from query cache)
211
+ * and returns a verdict on how to optimistically update the query data.
212
+ *
213
+ * @param args Arguments.
214
+ * @param args.queryModel The model of the query.
215
+ * @param args.queryOperation The operation of the query, `findMany`, `count`, etc.
216
+ * @param args.queryArgs The arguments of the query.
217
+ * @param args.currentData The current cache data for the query.
218
+ * @param args.mutationArgs The arguments of the mutation.
219
+ */
220
+ type OptimisticDataProvider = (args: {
221
+ queryModel: string;
222
+ queryOperation: string;
223
+ queryArgs: any;
224
+ currentData: any;
225
+ mutationArgs: any;
226
+ }) => OptimisticDataProviderResult | Promise<OptimisticDataProviderResult>;
227
+ /**
228
+ * Result of optimistic data provider.
229
+ */
230
+ type OptimisticDataProviderResult = {
231
+ /**
232
+ * Kind of the result.
233
+ * - Update: use the `data` field to update the query cache.
234
+ * - Skip: skip the optimistic update for this query.
235
+ * - ProceedDefault: proceed with the default optimistic update.
236
+ */
237
+ kind: 'Update' | 'Skip' | 'ProceedDefault';
238
+ /**
239
+ * Data to update the query cache. Only applicable if `kind` is 'Update'.
240
+ *
241
+ * If the data is an object with fields updated, it should have a `$optimistic`
242
+ * field set to `true`. If it's an array and an element object is created or updated,
243
+ * the element should have a `$optimistic` field set to `true`.
244
+ */
245
+ data?: any;
246
+ };
247
+ /**
248
+ * Options for optimistic update.
249
+ */
250
+ type OptimisticUpdateOptions = {
251
+ /**
252
+ * A custom optimistic data provider.
253
+ */
254
+ optimisticDataProvider?: OptimisticDataProvider;
255
+ };
256
+ /**
257
+ * Creates a function that performs optimistic updates for queries potentially
258
+ * affected by the given mutation operation.
259
+ *
260
+ * @param model Model under mutation.
261
+ * @param operation Mutation operation (e.g, `update`).
262
+ * @param schema The schema.
263
+ * @param options Optimistic update options.
264
+ * @param getAllQueries Callback to get all cached queries.
265
+ * @param logging Logging option.
266
+ */
267
+ declare function createOptimisticUpdater(model: string, operation: string, schema: SchemaDef, options: OptimisticUpdateOptions, getAllQueries: () => readonly QueryInfo[], logging: Logger | undefined): (...args: unknown[]) => Promise<void>;
268
+
269
+ /**
270
+ * Gets models read (including nested ones) given a query args.
271
+ */
272
+ declare function getReadModels(model: string, schema: SchemaDef, args: any): string[];
273
+ /**
274
+ * Gets mutated models (including nested ones) given a mutation args.
275
+ */
276
+ declare function getMutatedModels(model: string, operation: ORMWriteActionType, mutationArgs: any, schema: SchemaDef): Promise<string[]>;
277
+
278
+ export { DEFAULT_QUERY_ENDPOINT, type InvalidateFunc, type InvalidationPredicate, type Logger, type MaybePromise, NestedReadVisitor, type NestedReadVisitorCallback, NestedWriteVisitor, type NestedWriteVisitorCallback, type NestedWriteVisitorContext, type ORMWriteActionType, ORMWriteActions, type OptimisticDataProvider, type OptimisticDataProviderResult, type OptimisticUpdateOptions, type QueryError, type QueryInfo, applyMutation, createInvalidator, createOptimisticUpdater, getMutatedModels, getReadModels, log };