@zenstackhq/tanstack-query 3.0.0-beta.17 → 3.0.0-beta.19

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/dist/svelte.js ADDED
@@ -0,0 +1,1183 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/svelte.ts
5
+ import { createInfiniteQuery, createMutation, createQuery, useQueryClient } from "@tanstack/svelte-query";
6
+ import { lowerCaseFirst as lowerCaseFirst2 } from "@zenstackhq/common-helpers";
7
+ import { getContext, setContext } from "svelte";
8
+ import { derived, get } from "svelte/store";
9
+
10
+ // src/utils/common.ts
11
+ import { lowerCaseFirst } from "@zenstackhq/common-helpers";
12
+
13
+ // src/utils/mutator.ts
14
+ import { clone, enumerate as enumerate2, invariant, zip } from "@zenstackhq/common-helpers";
15
+
16
+ // src/utils/nested-write-visitor.ts
17
+ import { enumerate } from "@zenstackhq/common-helpers";
18
+
19
+ // src/utils/types.ts
20
+ var ORMWriteActions = [
21
+ "create",
22
+ "createMany",
23
+ "createManyAndReturn",
24
+ "connectOrCreate",
25
+ "update",
26
+ "updateMany",
27
+ "updateManyAndReturn",
28
+ "upsert",
29
+ "connect",
30
+ "disconnect",
31
+ "set",
32
+ "delete",
33
+ "deleteMany"
34
+ ];
35
+
36
+ // src/utils/nested-write-visitor.ts
37
+ var NestedWriteVisitor = class {
38
+ static {
39
+ __name(this, "NestedWriteVisitor");
40
+ }
41
+ schema;
42
+ callback;
43
+ constructor(schema, callback) {
44
+ this.schema = schema;
45
+ this.callback = callback;
46
+ }
47
+ isWriteAction(value) {
48
+ return ORMWriteActions.includes(value);
49
+ }
50
+ /**
51
+ * Start visiting
52
+ *
53
+ * @see NestedWriterVisitorCallback
54
+ */
55
+ async visit(model, action, args) {
56
+ if (!args) {
57
+ return;
58
+ }
59
+ let topData = args;
60
+ switch (action) {
61
+ // create has its data wrapped in 'data' field
62
+ case "create":
63
+ topData = topData.data;
64
+ break;
65
+ case "delete":
66
+ case "deleteMany":
67
+ topData = topData.where;
68
+ break;
69
+ }
70
+ await this.doVisit(model, action, topData, void 0, void 0, []);
71
+ }
72
+ async doVisit(model, action, data, parent, field, nestingPath) {
73
+ if (!data) {
74
+ return;
75
+ }
76
+ const toplevel = field == void 0;
77
+ const context = {
78
+ parent,
79
+ field,
80
+ nestingPath: [
81
+ ...nestingPath
82
+ ]
83
+ };
84
+ const pushNewContext = /* @__PURE__ */ __name((field2, model2, where, unique = false) => {
85
+ return {
86
+ ...context,
87
+ nestingPath: [
88
+ ...context.nestingPath,
89
+ {
90
+ field: field2,
91
+ model: model2,
92
+ where,
93
+ unique
94
+ }
95
+ ]
96
+ };
97
+ }, "pushNewContext");
98
+ switch (action) {
99
+ case "create":
100
+ for (const item of this.enumerateReverse(data)) {
101
+ const newContext = pushNewContext(field, model, {});
102
+ let callbackResult;
103
+ if (this.callback.create) {
104
+ callbackResult = await this.callback.create(model, item, newContext);
105
+ }
106
+ if (callbackResult !== false) {
107
+ const subPayload = typeof callbackResult === "object" ? callbackResult : item;
108
+ await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);
109
+ }
110
+ }
111
+ break;
112
+ case "createMany":
113
+ case "createManyAndReturn":
114
+ {
115
+ const newContext = pushNewContext(field, model, {});
116
+ let callbackResult;
117
+ if (this.callback.createMany) {
118
+ callbackResult = await this.callback.createMany(model, data, newContext);
119
+ }
120
+ if (callbackResult !== false) {
121
+ const subPayload = typeof callbackResult === "object" ? callbackResult : data.data;
122
+ await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);
123
+ }
124
+ }
125
+ break;
126
+ case "connectOrCreate":
127
+ for (const item of this.enumerateReverse(data)) {
128
+ const newContext = pushNewContext(field, model, item.where);
129
+ let callbackResult;
130
+ if (this.callback.connectOrCreate) {
131
+ callbackResult = await this.callback.connectOrCreate(model, item, newContext);
132
+ }
133
+ if (callbackResult !== false) {
134
+ const subPayload = typeof callbackResult === "object" ? callbackResult : item.create;
135
+ await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);
136
+ }
137
+ }
138
+ break;
139
+ case "connect":
140
+ if (this.callback.connect) {
141
+ for (const item of this.enumerateReverse(data)) {
142
+ const newContext = pushNewContext(field, model, item, true);
143
+ await this.callback.connect(model, item, newContext);
144
+ }
145
+ }
146
+ break;
147
+ case "disconnect":
148
+ if (this.callback.disconnect) {
149
+ for (const item of this.enumerateReverse(data)) {
150
+ const newContext = pushNewContext(field, model, item, typeof item === "object");
151
+ await this.callback.disconnect(model, item, newContext);
152
+ }
153
+ }
154
+ break;
155
+ case "set":
156
+ if (this.callback.set) {
157
+ for (const item of this.enumerateReverse(data)) {
158
+ const newContext = pushNewContext(field, model, item, true);
159
+ await this.callback.set(model, item, newContext);
160
+ }
161
+ }
162
+ break;
163
+ case "update":
164
+ for (const item of this.enumerateReverse(data)) {
165
+ const newContext = pushNewContext(field, model, item.where);
166
+ let callbackResult;
167
+ if (this.callback.update) {
168
+ callbackResult = await this.callback.update(model, item, newContext);
169
+ }
170
+ if (callbackResult !== false) {
171
+ const subPayload = typeof callbackResult === "object" ? callbackResult : typeof item.data === "object" ? item.data : item;
172
+ await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);
173
+ }
174
+ }
175
+ break;
176
+ case "updateMany":
177
+ case "updateManyAndReturn":
178
+ for (const item of this.enumerateReverse(data)) {
179
+ const newContext = pushNewContext(field, model, item.where);
180
+ let callbackResult;
181
+ if (this.callback.updateMany) {
182
+ callbackResult = await this.callback.updateMany(model, item, newContext);
183
+ }
184
+ if (callbackResult !== false) {
185
+ const subPayload = typeof callbackResult === "object" ? callbackResult : item;
186
+ await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);
187
+ }
188
+ }
189
+ break;
190
+ case "upsert": {
191
+ for (const item of this.enumerateReverse(data)) {
192
+ const newContext = pushNewContext(field, model, item.where);
193
+ let callbackResult;
194
+ if (this.callback.upsert) {
195
+ callbackResult = await this.callback.upsert(model, item, newContext);
196
+ }
197
+ if (callbackResult !== false) {
198
+ if (typeof callbackResult === "object") {
199
+ await this.visitSubPayload(model, action, callbackResult, newContext.nestingPath);
200
+ } else {
201
+ await this.visitSubPayload(model, action, item.create, newContext.nestingPath);
202
+ await this.visitSubPayload(model, action, item.update, newContext.nestingPath);
203
+ }
204
+ }
205
+ }
206
+ break;
207
+ }
208
+ case "delete": {
209
+ if (this.callback.delete) {
210
+ for (const item of this.enumerateReverse(data)) {
211
+ const newContext = pushNewContext(field, model, toplevel ? item.where : item);
212
+ await this.callback.delete(model, item, newContext);
213
+ }
214
+ }
215
+ break;
216
+ }
217
+ case "deleteMany":
218
+ if (this.callback.deleteMany) {
219
+ for (const item of this.enumerateReverse(data)) {
220
+ const newContext = pushNewContext(field, model, toplevel ? item.where : item);
221
+ await this.callback.deleteMany(model, item, newContext);
222
+ }
223
+ }
224
+ break;
225
+ default: {
226
+ throw new Error(`unhandled action type ${action}`);
227
+ }
228
+ }
229
+ }
230
+ async visitSubPayload(model, action, payload, nestingPath) {
231
+ for (const item of enumerate(payload)) {
232
+ if (!item || typeof item !== "object") {
233
+ continue;
234
+ }
235
+ for (const field of Object.keys(item)) {
236
+ const fieldDef = this.schema.models[model]?.fields[field];
237
+ if (!fieldDef) {
238
+ continue;
239
+ }
240
+ if (fieldDef.relation) {
241
+ if (item[field]) {
242
+ for (const [subAction, subData] of Object.entries(item[field])) {
243
+ if (this.isWriteAction(subAction) && subData) {
244
+ await this.doVisit(fieldDef.type, subAction, subData, item[field], fieldDef, [
245
+ ...nestingPath
246
+ ]);
247
+ }
248
+ }
249
+ }
250
+ } else {
251
+ if (this.callback.field) {
252
+ await this.callback.field(fieldDef, action, item[field], {
253
+ parent: item,
254
+ nestingPath,
255
+ field: fieldDef
256
+ });
257
+ }
258
+ }
259
+ }
260
+ }
261
+ }
262
+ // enumerate a (possible) array in reverse order, so that the enumeration
263
+ // callback can safely delete the current item
264
+ *enumerateReverse(data) {
265
+ if (Array.isArray(data)) {
266
+ for (let i = data.length - 1; i >= 0; i--) {
267
+ yield data[i];
268
+ }
269
+ } else {
270
+ yield data;
271
+ }
272
+ }
273
+ };
274
+
275
+ // src/utils/mutator.ts
276
+ async function applyMutation(queryModel, queryOp, queryData, mutationModel, mutationOp, mutationArgs, schema, logging) {
277
+ if (!queryData || typeof queryData !== "object" && !Array.isArray(queryData)) {
278
+ return void 0;
279
+ }
280
+ if (!queryOp.startsWith("find")) {
281
+ return void 0;
282
+ }
283
+ return await doApplyMutation(queryModel, queryData, mutationModel, mutationOp, mutationArgs, schema, logging);
284
+ }
285
+ __name(applyMutation, "applyMutation");
286
+ async function doApplyMutation(queryModel, queryData, mutationModel, mutationOp, mutationArgs, schema, logging) {
287
+ let resultData = queryData;
288
+ let updated = false;
289
+ const visitor = new NestedWriteVisitor(schema, {
290
+ create: /* @__PURE__ */ __name((model, args) => {
291
+ if (model === queryModel && Array.isArray(resultData)) {
292
+ const r = createMutate(queryModel, resultData, args, schema, logging);
293
+ if (r) {
294
+ resultData = r;
295
+ updated = true;
296
+ }
297
+ }
298
+ }, "create"),
299
+ createMany: /* @__PURE__ */ __name((model, args) => {
300
+ if (model === queryModel && args?.data && Array.isArray(resultData)) {
301
+ for (const oneArg of enumerate2(args.data)) {
302
+ const r = createMutate(queryModel, resultData, oneArg, schema, logging);
303
+ if (r) {
304
+ resultData = r;
305
+ updated = true;
306
+ }
307
+ }
308
+ }
309
+ }, "createMany"),
310
+ update: /* @__PURE__ */ __name((model, args) => {
311
+ if (model === queryModel && !Array.isArray(resultData)) {
312
+ const r = updateMutate(queryModel, resultData, model, args, schema, logging);
313
+ if (r) {
314
+ resultData = r;
315
+ updated = true;
316
+ }
317
+ }
318
+ }, "update"),
319
+ upsert: /* @__PURE__ */ __name((model, args) => {
320
+ if (model === queryModel && args?.where && args?.create && args?.update) {
321
+ const r = upsertMutate(queryModel, resultData, model, args, schema, logging);
322
+ if (r) {
323
+ resultData = r;
324
+ updated = true;
325
+ }
326
+ }
327
+ }, "upsert"),
328
+ delete: /* @__PURE__ */ __name((model, args) => {
329
+ if (model === queryModel) {
330
+ const r = deleteMutate(queryModel, resultData, model, args, schema, logging);
331
+ if (r) {
332
+ resultData = r;
333
+ updated = true;
334
+ }
335
+ }
336
+ }, "delete")
337
+ });
338
+ await visitor.visit(mutationModel, mutationOp, mutationArgs);
339
+ const modelFields = schema.models[queryModel]?.fields;
340
+ invariant(modelFields, `Model ${queryModel} not found in schema`);
341
+ if (Array.isArray(resultData)) {
342
+ let arrayCloned = false;
343
+ for (let i = 0; i < resultData.length; i++) {
344
+ const item = resultData[i];
345
+ if (!item || typeof item !== "object" || item.$optimistic) {
346
+ continue;
347
+ }
348
+ const r = await doApplyMutation(queryModel, item, mutationModel, mutationOp, mutationArgs, schema, logging);
349
+ if (r && typeof r === "object") {
350
+ if (!arrayCloned) {
351
+ resultData = [
352
+ ...resultData
353
+ ];
354
+ arrayCloned = true;
355
+ }
356
+ resultData[i] = r;
357
+ updated = true;
358
+ }
359
+ }
360
+ } else if (resultData !== null && typeof resultData === "object") {
361
+ const currentData = {
362
+ ...resultData
363
+ };
364
+ for (const [key, value] of Object.entries(currentData)) {
365
+ const fieldDef = modelFields[key];
366
+ if (!fieldDef?.relation) {
367
+ continue;
368
+ }
369
+ const r = await doApplyMutation(fieldDef.type, value, mutationModel, mutationOp, mutationArgs, schema, logging);
370
+ if (r && typeof r === "object") {
371
+ resultData = {
372
+ ...resultData,
373
+ [key]: r
374
+ };
375
+ updated = true;
376
+ }
377
+ }
378
+ }
379
+ return updated ? resultData : void 0;
380
+ }
381
+ __name(doApplyMutation, "doApplyMutation");
382
+ function createMutate(queryModel, currentData, newData, schema, logging) {
383
+ if (!newData) {
384
+ return void 0;
385
+ }
386
+ const modelFields = schema.models[queryModel]?.fields;
387
+ if (!modelFields) {
388
+ return void 0;
389
+ }
390
+ const insert = {};
391
+ const newDataFields = Object.keys(newData);
392
+ Object.entries(modelFields).forEach(([name, field]) => {
393
+ if (field.relation && newData[name]) {
394
+ assignForeignKeyFields(field, insert, newData[name]);
395
+ return;
396
+ }
397
+ if (newDataFields.includes(name)) {
398
+ insert[name] = clone(newData[name]);
399
+ } else {
400
+ const defaultAttr = field.attributes?.find((attr) => attr.name === "@default");
401
+ if (field.type === "DateTime") {
402
+ if (defaultAttr || field.attributes?.some((attr) => attr.name === "@updatedAt")) {
403
+ insert[name] = /* @__PURE__ */ new Date();
404
+ return;
405
+ }
406
+ }
407
+ const defaultArg = defaultAttr?.args?.[0]?.value;
408
+ if (defaultArg?.kind === "literal") {
409
+ insert[name] = defaultArg.value;
410
+ }
411
+ }
412
+ });
413
+ const idFields = getIdFields(schema, queryModel);
414
+ idFields.forEach((f) => {
415
+ if (insert[f.name] === void 0) {
416
+ if (f.type === "Int" || f.type === "BigInt") {
417
+ const currMax = Array.isArray(currentData) ? Math.max(...[
418
+ ...currentData
419
+ ].map((item) => {
420
+ const idv = parseInt(item[f.name]);
421
+ return isNaN(idv) ? 0 : idv;
422
+ })) : 0;
423
+ insert[f.name] = currMax + 1;
424
+ } else {
425
+ insert[f.name] = crypto.randomUUID();
426
+ }
427
+ }
428
+ });
429
+ insert.$optimistic = true;
430
+ if (logging) {
431
+ console.log(`Optimistic create for ${queryModel}:`, insert);
432
+ }
433
+ return [
434
+ insert,
435
+ ...Array.isArray(currentData) ? currentData : []
436
+ ];
437
+ }
438
+ __name(createMutate, "createMutate");
439
+ function updateMutate(queryModel, currentData, mutateModel, mutateArgs, schema, logging) {
440
+ if (!currentData || typeof currentData !== "object") {
441
+ return void 0;
442
+ }
443
+ if (!mutateArgs?.where || typeof mutateArgs.where !== "object") {
444
+ return void 0;
445
+ }
446
+ if (!mutateArgs?.data || typeof mutateArgs.data !== "object") {
447
+ return void 0;
448
+ }
449
+ if (!idFieldsMatch(mutateModel, currentData, mutateArgs.where, schema)) {
450
+ return void 0;
451
+ }
452
+ const modelFields = schema.models[queryModel]?.fields;
453
+ if (!modelFields) {
454
+ return void 0;
455
+ }
456
+ let updated = false;
457
+ let resultData = currentData;
458
+ for (const [key, value] of Object.entries(mutateArgs.data)) {
459
+ const fieldInfo = modelFields[key];
460
+ if (!fieldInfo) {
461
+ continue;
462
+ }
463
+ if (fieldInfo.relation && !value?.connect) {
464
+ continue;
465
+ }
466
+ if (!updated) {
467
+ resultData = {
468
+ ...currentData
469
+ };
470
+ }
471
+ if (fieldInfo.relation) {
472
+ assignForeignKeyFields(fieldInfo, resultData, value);
473
+ } else {
474
+ resultData[key] = clone(value);
475
+ }
476
+ resultData.$optimistic = true;
477
+ updated = true;
478
+ if (logging) {
479
+ console.log(`Optimistic update for ${queryModel}:`, resultData);
480
+ }
481
+ }
482
+ return updated ? resultData : void 0;
483
+ }
484
+ __name(updateMutate, "updateMutate");
485
+ function upsertMutate(queryModel, currentData, model, args, schema, logging) {
486
+ let updated = false;
487
+ let resultData = currentData;
488
+ if (Array.isArray(resultData)) {
489
+ const foundIndex = resultData.findIndex((x) => idFieldsMatch(model, x, args.where, schema));
490
+ if (foundIndex >= 0) {
491
+ const updateResult = updateMutate(queryModel, resultData[foundIndex], model, {
492
+ where: args.where,
493
+ data: args.update
494
+ }, schema, logging);
495
+ if (updateResult) {
496
+ resultData = [
497
+ ...resultData.slice(0, foundIndex),
498
+ updateResult,
499
+ ...resultData.slice(foundIndex + 1)
500
+ ];
501
+ updated = true;
502
+ }
503
+ } else {
504
+ const createResult = createMutate(queryModel, resultData, args.create, schema, logging);
505
+ if (createResult) {
506
+ resultData = createResult;
507
+ updated = true;
508
+ }
509
+ }
510
+ } else {
511
+ const updateResult = updateMutate(queryModel, resultData, model, {
512
+ where: args.where,
513
+ data: args.update
514
+ }, schema, logging);
515
+ if (updateResult) {
516
+ resultData = updateResult;
517
+ updated = true;
518
+ }
519
+ }
520
+ return updated ? resultData : void 0;
521
+ }
522
+ __name(upsertMutate, "upsertMutate");
523
+ function deleteMutate(queryModel, currentData, mutateModel, mutateArgs, schema, logging) {
524
+ if (!currentData || !mutateArgs) {
525
+ return void 0;
526
+ }
527
+ if (queryModel !== mutateModel) {
528
+ return void 0;
529
+ }
530
+ let updated = false;
531
+ let result = currentData;
532
+ if (Array.isArray(currentData)) {
533
+ for (const item of currentData) {
534
+ if (idFieldsMatch(mutateModel, item, mutateArgs, schema)) {
535
+ result = result.filter((x) => x !== item);
536
+ updated = true;
537
+ if (logging) {
538
+ console.log(`Optimistic delete for ${queryModel}:`, item);
539
+ }
540
+ }
541
+ }
542
+ } else {
543
+ if (idFieldsMatch(mutateModel, currentData, mutateArgs, schema)) {
544
+ result = null;
545
+ updated = true;
546
+ if (logging) {
547
+ console.log(`Optimistic delete for ${queryModel}:`, currentData);
548
+ }
549
+ }
550
+ }
551
+ return updated ? result : void 0;
552
+ }
553
+ __name(deleteMutate, "deleteMutate");
554
+ function idFieldsMatch(model, x, y, schema) {
555
+ if (!x || !y || typeof x !== "object" || typeof y !== "object") {
556
+ return false;
557
+ }
558
+ const idFields = getIdFields(schema, model);
559
+ if (idFields.length === 0) {
560
+ return false;
561
+ }
562
+ return idFields.every((f) => x[f.name] === y[f.name]);
563
+ }
564
+ __name(idFieldsMatch, "idFieldsMatch");
565
+ function assignForeignKeyFields(field, resultData, mutationData) {
566
+ if (!mutationData?.connect) {
567
+ return;
568
+ }
569
+ if (!field.relation?.fields || !field.relation.references) {
570
+ return;
571
+ }
572
+ for (const [idField, fkField] of zip(field.relation.references, field.relation.fields)) {
573
+ if (idField in mutationData.connect) {
574
+ resultData[fkField] = mutationData.connect[idField];
575
+ }
576
+ }
577
+ }
578
+ __name(assignForeignKeyFields, "assignForeignKeyFields");
579
+ function getIdFields(schema, model) {
580
+ return (schema.models[model]?.idFields ?? []).map((f) => schema.models[model].fields[f]);
581
+ }
582
+ __name(getIdFields, "getIdFields");
583
+
584
+ // src/utils/nested-read-visitor.ts
585
+ var NestedReadVisitor = class {
586
+ static {
587
+ __name(this, "NestedReadVisitor");
588
+ }
589
+ schema;
590
+ callback;
591
+ constructor(schema, callback) {
592
+ this.schema = schema;
593
+ this.callback = callback;
594
+ }
595
+ doVisit(model, field, kind, args) {
596
+ if (this.callback.field) {
597
+ const r = this.callback.field(model, field, kind, args);
598
+ if (r === false) {
599
+ return;
600
+ }
601
+ }
602
+ if (!args || typeof args !== "object") {
603
+ return;
604
+ }
605
+ let selectInclude;
606
+ let nextKind;
607
+ if (args.select) {
608
+ selectInclude = args.select;
609
+ nextKind = "select";
610
+ } else if (args.include) {
611
+ selectInclude = args.include;
612
+ nextKind = "include";
613
+ }
614
+ if (selectInclude && typeof selectInclude === "object") {
615
+ for (const [k, v] of Object.entries(selectInclude)) {
616
+ if (k === "_count" && typeof v === "object" && v) {
617
+ this.doVisit(model, field, kind, v);
618
+ } else {
619
+ const field2 = this.schema.models[model]?.fields[k];
620
+ if (field2) {
621
+ this.doVisit(field2.type, field2, nextKind, v);
622
+ }
623
+ }
624
+ }
625
+ }
626
+ }
627
+ visit(model, args) {
628
+ this.doVisit(model, void 0, void 0, args);
629
+ }
630
+ };
631
+
632
+ // src/utils/query-analysis.ts
633
+ function getReadModels(model, schema, args) {
634
+ const result = /* @__PURE__ */ new Set();
635
+ result.add(model);
636
+ const visitor = new NestedReadVisitor(schema, {
637
+ field: /* @__PURE__ */ __name((model2) => {
638
+ result.add(model2);
639
+ return true;
640
+ }, "field")
641
+ });
642
+ visitor.visit(model, args);
643
+ return [
644
+ ...result
645
+ ];
646
+ }
647
+ __name(getReadModels, "getReadModels");
648
+ async function getMutatedModels(model, operation, mutationArgs, schema) {
649
+ const result = /* @__PURE__ */ new Set();
650
+ result.add(model);
651
+ if (mutationArgs) {
652
+ const addModel = /* @__PURE__ */ __name((model2) => void result.add(model2), "addModel");
653
+ const addCascades = /* @__PURE__ */ __name((model2) => {
654
+ const cascades = /* @__PURE__ */ new Set();
655
+ const visited = /* @__PURE__ */ new Set();
656
+ collectDeleteCascades(model2, schema, cascades, visited);
657
+ cascades.forEach((m) => addModel(m));
658
+ }, "addCascades");
659
+ const visitor = new NestedWriteVisitor(schema, {
660
+ create: addModel,
661
+ createMany: addModel,
662
+ connectOrCreate: addModel,
663
+ connect: addModel,
664
+ disconnect: addModel,
665
+ set: addModel,
666
+ update: addModel,
667
+ updateMany: addModel,
668
+ upsert: addModel,
669
+ delete: /* @__PURE__ */ __name((model2) => {
670
+ addModel(model2);
671
+ addCascades(model2);
672
+ }, "delete"),
673
+ deleteMany: /* @__PURE__ */ __name((model2) => {
674
+ addModel(model2);
675
+ addCascades(model2);
676
+ }, "deleteMany")
677
+ });
678
+ await visitor.visit(model, operation, mutationArgs);
679
+ }
680
+ result.forEach((m) => {
681
+ getBaseRecursively(m, schema, result);
682
+ });
683
+ return [
684
+ ...result
685
+ ];
686
+ }
687
+ __name(getMutatedModels, "getMutatedModels");
688
+ function collectDeleteCascades(model, schema, result, visited) {
689
+ if (visited.has(model)) {
690
+ return;
691
+ }
692
+ visited.add(model);
693
+ const modelDef = schema.models[model];
694
+ if (!modelDef) {
695
+ return;
696
+ }
697
+ for (const [modelName, modelDef2] of Object.entries(schema.models)) {
698
+ if (!modelDef2) {
699
+ continue;
700
+ }
701
+ for (const fieldDef of Object.values(modelDef2.fields)) {
702
+ if (fieldDef.relation?.onDelete === "Cascade" && fieldDef.type === model) {
703
+ if (!result.has(modelName)) {
704
+ result.add(modelName);
705
+ }
706
+ collectDeleteCascades(modelName, schema, result, visited);
707
+ }
708
+ }
709
+ }
710
+ }
711
+ __name(collectDeleteCascades, "collectDeleteCascades");
712
+ function getBaseRecursively(model, schema, result) {
713
+ const modelDef = schema.models[model];
714
+ if (!modelDef) {
715
+ return;
716
+ }
717
+ if (modelDef.baseModel) {
718
+ result.add(modelDef.baseModel);
719
+ getBaseRecursively(modelDef.baseModel, schema, result);
720
+ }
721
+ }
722
+ __name(getBaseRecursively, "getBaseRecursively");
723
+
724
+ // src/utils/serialization.ts
725
+ import { Buffer as Buffer2 } from "buffer";
726
+ import Decimal from "decimal.js";
727
+ import SuperJSON from "superjson";
728
+ SuperJSON.registerCustom({
729
+ isApplicable: /* @__PURE__ */ __name((v) => v instanceof Decimal || // interop with decimal.js
730
+ v?.toStringTag === "[object Decimal]", "isApplicable"),
731
+ serialize: /* @__PURE__ */ __name((v) => v.toJSON(), "serialize"),
732
+ deserialize: /* @__PURE__ */ __name((v) => new Decimal(v), "deserialize")
733
+ }, "Decimal");
734
+ SuperJSON.registerCustom({
735
+ isApplicable: /* @__PURE__ */ __name((v) => Buffer2.isBuffer(v), "isApplicable"),
736
+ serialize: /* @__PURE__ */ __name((v) => v.toString("base64"), "serialize"),
737
+ deserialize: /* @__PURE__ */ __name((v) => Buffer2.from(v, "base64"), "deserialize")
738
+ }, "Bytes");
739
+ function serialize(value) {
740
+ const { json, meta } = SuperJSON.serialize(value);
741
+ return {
742
+ data: json,
743
+ meta
744
+ };
745
+ }
746
+ __name(serialize, "serialize");
747
+ function deserialize(value, meta) {
748
+ return SuperJSON.deserialize({
749
+ json: value,
750
+ meta
751
+ });
752
+ }
753
+ __name(deserialize, "deserialize");
754
+
755
+ // src/utils/common.ts
756
+ var QUERY_KEY_PREFIX = "zenstack";
757
+ async function fetcher(url, options, customFetch) {
758
+ const _fetch = customFetch ?? fetch;
759
+ const res = await _fetch(url, options);
760
+ if (!res.ok) {
761
+ const errData = unmarshal(await res.text());
762
+ if (errData.error?.rejectedByPolicy && errData.error?.rejectReason === "cannot-read-back") {
763
+ return void 0;
764
+ }
765
+ const error = new Error("An error occurred while fetching the data.");
766
+ error.info = errData.error;
767
+ error.status = res.status;
768
+ throw error;
769
+ }
770
+ const textResult = await res.text();
771
+ try {
772
+ return unmarshal(textResult).data;
773
+ } catch (err) {
774
+ console.error(`Unable to deserialize data:`, textResult);
775
+ throw err;
776
+ }
777
+ }
778
+ __name(fetcher, "fetcher");
779
+ function getQueryKey(model, operation, args, options = {
780
+ infinite: false,
781
+ optimisticUpdate: true
782
+ }) {
783
+ const infinite = options.infinite;
784
+ const optimisticUpdate2 = options.infinite ? false : options.optimisticUpdate;
785
+ return [
786
+ QUERY_KEY_PREFIX,
787
+ model,
788
+ operation,
789
+ args,
790
+ {
791
+ infinite,
792
+ optimisticUpdate: optimisticUpdate2
793
+ }
794
+ ];
795
+ }
796
+ __name(getQueryKey, "getQueryKey");
797
+ function marshal(value) {
798
+ const { data, meta } = serialize(value);
799
+ if (meta) {
800
+ return JSON.stringify({
801
+ ...data,
802
+ meta: {
803
+ serialization: meta
804
+ }
805
+ });
806
+ } else {
807
+ return JSON.stringify(data);
808
+ }
809
+ }
810
+ __name(marshal, "marshal");
811
+ function unmarshal(value) {
812
+ const parsed = JSON.parse(value);
813
+ if (typeof parsed === "object" && parsed?.data && parsed?.meta?.serialization) {
814
+ const deserializedData = deserialize(parsed.data, parsed.meta.serialization);
815
+ return {
816
+ ...parsed,
817
+ data: deserializedData
818
+ };
819
+ } else {
820
+ return parsed;
821
+ }
822
+ }
823
+ __name(unmarshal, "unmarshal");
824
+ function makeUrl(endpoint, model, operation, args) {
825
+ const baseUrl = `${endpoint}/${lowerCaseFirst(model)}/${operation}`;
826
+ if (!args) {
827
+ return baseUrl;
828
+ }
829
+ const { data, meta } = serialize(args);
830
+ let result = `${baseUrl}?q=${encodeURIComponent(JSON.stringify(data))}`;
831
+ if (meta) {
832
+ result += `&meta=${encodeURIComponent(JSON.stringify({
833
+ serialization: meta
834
+ }))}`;
835
+ }
836
+ return result;
837
+ }
838
+ __name(makeUrl, "makeUrl");
839
+ function setupInvalidation(model, operation, schema, options, invalidate, logging = false) {
840
+ const origOnSuccess = options?.onSuccess;
841
+ options.onSuccess = async (...args) => {
842
+ const [_, variables] = args;
843
+ const predicate = await getInvalidationPredicate(model, operation, variables, schema, logging);
844
+ await invalidate(predicate);
845
+ return origOnSuccess?.(...args);
846
+ };
847
+ }
848
+ __name(setupInvalidation, "setupInvalidation");
849
+ async function getInvalidationPredicate(model, operation, mutationArgs, schema, logging = false) {
850
+ const mutatedModels = await getMutatedModels(model, operation, mutationArgs, schema);
851
+ return ({ queryKey }) => {
852
+ const [_, queryModel, , args] = queryKey;
853
+ if (mutatedModels.includes(queryModel)) {
854
+ if (logging) {
855
+ console.log(`Invalidating query ${JSON.stringify(queryKey)} due to mutation "${model}.${operation}"`);
856
+ }
857
+ return true;
858
+ }
859
+ if (args) {
860
+ if (findNestedRead(queryModel, mutatedModels, schema, args)) {
861
+ if (logging) {
862
+ console.log(`Invalidating query ${JSON.stringify(queryKey)} due to mutation "${model}.${operation}"`);
863
+ }
864
+ return true;
865
+ }
866
+ }
867
+ return false;
868
+ };
869
+ }
870
+ __name(getInvalidationPredicate, "getInvalidationPredicate");
871
+ function findNestedRead(visitingModel, targetModels, schema, args) {
872
+ const modelsRead = getReadModels(visitingModel, schema, args);
873
+ return targetModels.some((m) => modelsRead.includes(m));
874
+ }
875
+ __name(findNestedRead, "findNestedRead");
876
+ function setupOptimisticUpdate(model, operation, schema, options, queryCache, setCache, invalidate, logging = false) {
877
+ const origOnMutate = options?.onMutate;
878
+ const origOnSettled = options?.onSettled;
879
+ options.onMutate = async (...args) => {
880
+ const [variables] = args;
881
+ await optimisticUpdate(model, operation, variables, options, schema, queryCache, setCache, logging);
882
+ return origOnMutate?.(...args);
883
+ };
884
+ options.onSettled = async (...args) => {
885
+ if (invalidate) {
886
+ const [, , variables] = args;
887
+ const predicate = await getInvalidationPredicate(model, operation, variables, schema, logging);
888
+ await invalidate(predicate);
889
+ }
890
+ return origOnSettled?.(...args);
891
+ };
892
+ }
893
+ __name(setupOptimisticUpdate, "setupOptimisticUpdate");
894
+ async function optimisticUpdate(mutationModel, mutationOp, mutationArgs, options, schema, queryCache, setCache, logging = false) {
895
+ for (const cacheItem of queryCache) {
896
+ const { queryKey, state: { data, error } } = cacheItem;
897
+ if (!isZenStackQueryKey(queryKey)) {
898
+ continue;
899
+ }
900
+ if (error) {
901
+ if (logging) {
902
+ console.warn(`Skipping optimistic update for ${JSON.stringify(queryKey)} due to error:`, error);
903
+ }
904
+ continue;
905
+ }
906
+ const [_, queryModel, queryOperation, queryArgs, queryOptions] = queryKey;
907
+ if (!queryOptions?.optimisticUpdate) {
908
+ if (logging) {
909
+ console.log(`Skipping optimistic update for ${JSON.stringify(queryKey)} due to opt-out`);
910
+ }
911
+ continue;
912
+ }
913
+ if (options.optimisticDataProvider) {
914
+ const providerResult = await options.optimisticDataProvider({
915
+ queryModel,
916
+ queryOperation,
917
+ queryArgs,
918
+ currentData: data,
919
+ mutationArgs
920
+ });
921
+ if (providerResult?.kind === "Skip") {
922
+ if (logging) {
923
+ console.log(`Skipping optimistic update for ${JSON.stringify(queryKey)} due to provider`);
924
+ }
925
+ continue;
926
+ } else if (providerResult?.kind === "Update") {
927
+ if (logging) {
928
+ console.log(`Optimistically updating query ${JSON.stringify(queryKey)} due to provider`);
929
+ }
930
+ setCache(queryKey, providerResult.data);
931
+ continue;
932
+ }
933
+ }
934
+ const mutatedData = await applyMutation(queryModel, queryOperation, data, mutationModel, mutationOp, mutationArgs, schema, logging);
935
+ if (mutatedData !== void 0) {
936
+ if (logging) {
937
+ console.log(`Optimistically updating query ${JSON.stringify(queryKey)} due to mutation "${mutationModel}.${mutationOp}"`);
938
+ }
939
+ setCache(queryKey, mutatedData);
940
+ }
941
+ }
942
+ }
943
+ __name(optimisticUpdate, "optimisticUpdate");
944
+ function isZenStackQueryKey(queryKey) {
945
+ if (queryKey.length < 5) {
946
+ return false;
947
+ }
948
+ if (queryKey[0] !== QUERY_KEY_PREFIX) {
949
+ return false;
950
+ }
951
+ return true;
952
+ }
953
+ __name(isZenStackQueryKey, "isZenStackQueryKey");
954
+
955
+ // src/svelte.ts
956
+ var DEFAULT_QUERY_ENDPOINT = "/api/model";
957
+ var SvelteQueryContextKey = "zenstack-svelte-query-context";
958
+ function setHooksContext(context) {
959
+ setContext(SvelteQueryContextKey, context);
960
+ }
961
+ __name(setHooksContext, "setHooksContext");
962
+ function setQuerySettingsContext(context) {
963
+ setContext(SvelteQueryContextKey, context);
964
+ }
965
+ __name(setQuerySettingsContext, "setQuerySettingsContext");
966
+ function getQuerySettings() {
967
+ const { endpoint, ...rest } = getContext(SvelteQueryContextKey) ?? {};
968
+ return {
969
+ endpoint: endpoint ?? DEFAULT_QUERY_ENDPOINT,
970
+ ...rest
971
+ };
972
+ }
973
+ __name(getQuerySettings, "getQuerySettings");
974
+ function useClientQueries(schema) {
975
+ return Object.keys(schema.models).reduce((acc, model) => {
976
+ acc[lowerCaseFirst2(model)] = useModelQueries(schema, model);
977
+ return acc;
978
+ }, {});
979
+ }
980
+ __name(useClientQueries, "useClientQueries");
981
+ function useModelQueries(schema, model) {
982
+ const modelDef = Object.values(schema.models).find((m) => m.name.toLowerCase() === model.toLowerCase());
983
+ if (!modelDef) {
984
+ throw new Error(`Model "${model}" not found in schema`);
985
+ }
986
+ const modelName = modelDef.name;
987
+ return {
988
+ useFindUnique: /* @__PURE__ */ __name((args, options) => {
989
+ return useInternalQuery(schema, modelName, "findUnique", args, options);
990
+ }, "useFindUnique"),
991
+ useFindFirst: /* @__PURE__ */ __name((args, options) => {
992
+ return useInternalQuery(schema, modelName, "findFirst", args, options);
993
+ }, "useFindFirst"),
994
+ useFindMany: /* @__PURE__ */ __name((args, options) => {
995
+ return useInternalQuery(schema, modelName, "findMany", args, options);
996
+ }, "useFindMany"),
997
+ useInfiniteFindMany: /* @__PURE__ */ __name((args, options) => {
998
+ return useInternalInfiniteQuery(schema, modelName, "findMany", args, options);
999
+ }, "useInfiniteFindMany"),
1000
+ useCreate: /* @__PURE__ */ __name((options) => {
1001
+ return useInternalMutation(schema, modelName, "POST", "create", options);
1002
+ }, "useCreate"),
1003
+ useCreateMany: /* @__PURE__ */ __name((options) => {
1004
+ return useInternalMutation(schema, modelName, "POST", "createMany", options);
1005
+ }, "useCreateMany"),
1006
+ useCreateManyAndReturn: /* @__PURE__ */ __name((options) => {
1007
+ return useInternalMutation(schema, modelName, "POST", "createManyAndReturn", options);
1008
+ }, "useCreateManyAndReturn"),
1009
+ useUpdate: /* @__PURE__ */ __name((options) => {
1010
+ return useInternalMutation(schema, modelName, "PUT", "update", options);
1011
+ }, "useUpdate"),
1012
+ useUpdateMany: /* @__PURE__ */ __name((options) => {
1013
+ return useInternalMutation(schema, modelName, "PUT", "updateMany", options);
1014
+ }, "useUpdateMany"),
1015
+ useUpdateManyAndReturn: /* @__PURE__ */ __name((options) => {
1016
+ return useInternalMutation(schema, modelName, "PUT", "updateManyAndReturn", options);
1017
+ }, "useUpdateManyAndReturn"),
1018
+ useUpsert: /* @__PURE__ */ __name((options) => {
1019
+ return useInternalMutation(schema, modelName, "POST", "upsert", options);
1020
+ }, "useUpsert"),
1021
+ useDelete: /* @__PURE__ */ __name((options) => {
1022
+ return useInternalMutation(schema, modelName, "DELETE", "delete", options);
1023
+ }, "useDelete"),
1024
+ useDeleteMany: /* @__PURE__ */ __name((options) => {
1025
+ return useInternalMutation(schema, modelName, "DELETE", "deleteMany", options);
1026
+ }, "useDeleteMany"),
1027
+ useCount: /* @__PURE__ */ __name((args, options) => {
1028
+ return useInternalQuery(schema, modelName, "count", args, options);
1029
+ }, "useCount"),
1030
+ useAggregate: /* @__PURE__ */ __name((args, options) => {
1031
+ return useInternalQuery(schema, modelName, "aggregate", args, options);
1032
+ }, "useAggregate"),
1033
+ useGroupBy: /* @__PURE__ */ __name((args, options) => {
1034
+ return useInternalQuery(schema, modelName, "groupBy", args, options);
1035
+ }, "useGroupBy")
1036
+ };
1037
+ }
1038
+ __name(useModelQueries, "useModelQueries");
1039
+ function useInternalQuery(_schema, model, operation, args, options) {
1040
+ const { endpoint, fetch: fetch2 } = getQuerySettings();
1041
+ const argsValue = unwrapStore(args);
1042
+ const reqUrl = makeUrl(endpoint, model, operation, argsValue);
1043
+ const optionsValue = unwrapStore(options);
1044
+ const queryKey = getQueryKey(model, operation, argsValue, {
1045
+ infinite: false,
1046
+ optimisticUpdate: optionsValue?.optimisticUpdate !== false
1047
+ });
1048
+ const queryFn = /* @__PURE__ */ __name(({ signal }) => fetcher(reqUrl, {
1049
+ signal
1050
+ }, fetch2), "queryFn");
1051
+ let mergedOpt;
1052
+ if (isStore(options)) {
1053
+ mergedOpt = derived([
1054
+ options
1055
+ ], ([$opt]) => {
1056
+ return {
1057
+ queryKey,
1058
+ queryFn,
1059
+ ...$opt
1060
+ };
1061
+ });
1062
+ } else {
1063
+ mergedOpt = {
1064
+ queryKey,
1065
+ queryFn,
1066
+ ...options
1067
+ };
1068
+ }
1069
+ const result = createQuery(mergedOpt);
1070
+ return derived(result, (r) => ({
1071
+ queryKey,
1072
+ ...r
1073
+ }));
1074
+ }
1075
+ __name(useInternalQuery, "useInternalQuery");
1076
+ function useInternalInfiniteQuery(_schema, model, operation, args, options) {
1077
+ options = options ?? {
1078
+ getNextPageParam: /* @__PURE__ */ __name(() => void 0, "getNextPageParam")
1079
+ };
1080
+ const { endpoint, fetch: fetch2 } = getQuerySettings();
1081
+ const argsValue = unwrapStore(args);
1082
+ const queryKey = getQueryKey(model, operation, argsValue, {
1083
+ infinite: true,
1084
+ optimisticUpdate: false
1085
+ });
1086
+ const queryFn = /* @__PURE__ */ __name(({ pageParam, signal }) => fetcher(makeUrl(endpoint, model, operation, pageParam ?? argsValue), {
1087
+ signal
1088
+ }, fetch2), "queryFn");
1089
+ let mergedOpt;
1090
+ if (isStore(options)) {
1091
+ mergedOpt = derived([
1092
+ options
1093
+ ], ([$opt]) => {
1094
+ return {
1095
+ queryKey,
1096
+ queryFn,
1097
+ initialPageParam: argsValue,
1098
+ ...$opt
1099
+ };
1100
+ });
1101
+ } else {
1102
+ mergedOpt = {
1103
+ queryKey,
1104
+ queryFn,
1105
+ initialPageParam: argsValue,
1106
+ ...options
1107
+ };
1108
+ }
1109
+ const result = createInfiniteQuery(mergedOpt);
1110
+ return derived(result, (r) => ({
1111
+ queryKey,
1112
+ ...r
1113
+ }));
1114
+ }
1115
+ __name(useInternalInfiniteQuery, "useInternalInfiniteQuery");
1116
+ function useInternalMutation(schema, model, method, operation, options) {
1117
+ const { endpoint, fetch: fetch2, logging } = getQuerySettings();
1118
+ const queryClient = useQueryClient();
1119
+ const optionsValue = unwrapStore(options);
1120
+ const mutationFn = /* @__PURE__ */ __name((data) => {
1121
+ const reqUrl = method === "DELETE" ? makeUrl(endpoint, model, operation, data) : makeUrl(endpoint, model, operation);
1122
+ const fetchInit = {
1123
+ method,
1124
+ ...method !== "DELETE" && {
1125
+ headers: {
1126
+ "content-type": "application/json"
1127
+ },
1128
+ body: marshal(data)
1129
+ }
1130
+ };
1131
+ return fetcher(reqUrl, fetchInit, fetch2);
1132
+ }, "mutationFn");
1133
+ let mergedOpt;
1134
+ if (isStore(options)) {
1135
+ mergedOpt = derived([
1136
+ options
1137
+ ], ([$opt]) => ({
1138
+ ...$opt,
1139
+ mutationFn
1140
+ }));
1141
+ } else {
1142
+ mergedOpt = {
1143
+ ...options,
1144
+ mutationFn
1145
+ };
1146
+ }
1147
+ const invalidateQueries = optionsValue?.invalidateQueries !== false;
1148
+ const optimisticUpdate2 = !!optionsValue?.optimisticUpdate;
1149
+ if (operation) {
1150
+ if (invalidateQueries) {
1151
+ setupInvalidation(model, operation, schema, unwrapStore(mergedOpt), (predicate) => queryClient.invalidateQueries({
1152
+ predicate
1153
+ }), logging);
1154
+ }
1155
+ if (optimisticUpdate2) {
1156
+ setupOptimisticUpdate(model, operation, schema, unwrapStore(mergedOpt), queryClient.getQueryCache().getAll(), (queryKey, data) => queryClient.setQueryData(queryKey, data), invalidateQueries ? (predicate) => queryClient.invalidateQueries({
1157
+ predicate
1158
+ }) : void 0, logging);
1159
+ }
1160
+ }
1161
+ return createMutation(mergedOpt);
1162
+ }
1163
+ __name(useInternalMutation, "useInternalMutation");
1164
+ function isStore(opt) {
1165
+ return typeof opt?.subscribe === "function";
1166
+ }
1167
+ __name(isStore, "isStore");
1168
+ function unwrapStore(storeOrValue) {
1169
+ return isStore(storeOrValue) ? get(storeOrValue) : storeOrValue;
1170
+ }
1171
+ __name(unwrapStore, "unwrapStore");
1172
+ export {
1173
+ DEFAULT_QUERY_ENDPOINT,
1174
+ SvelteQueryContextKey,
1175
+ setHooksContext,
1176
+ setQuerySettingsContext,
1177
+ useClientQueries,
1178
+ useInternalInfiniteQuery,
1179
+ useInternalMutation,
1180
+ useInternalQuery,
1181
+ useModelQueries
1182
+ };
1183
+ //# sourceMappingURL=svelte.js.map