on-zero 0.16.9 → 0.16.10

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.
Files changed (46) hide show
  1. package/dist/cjs/generate-layout.cjs +53 -0
  2. package/dist/cjs/generate-layout.native.js +179 -42
  3. package/dist/cjs/generate-layout.native.js.map +1 -1
  4. package/dist/cjs/generate-lite.cjs +18 -0
  5. package/dist/cjs/generate-lite.native.js +339 -281
  6. package/dist/cjs/generate-lite.native.js.map +1 -1
  7. package/dist/cjs/generate-lite.test.cjs +37 -0
  8. package/dist/cjs/generate-lite.test.native.js +38 -0
  9. package/dist/cjs/generate-lite.test.native.js.map +1 -1
  10. package/dist/cjs/generate.test.cjs +25 -0
  11. package/dist/cjs/generate.test.native.js +25 -0
  12. package/dist/cjs/generate.test.native.js.map +1 -1
  13. package/dist/cjs/useQuery.aggregate.zero.test.cjs +117 -0
  14. package/dist/cjs/useQuery.aggregate.zero.test.native.js +133 -0
  15. package/dist/cjs/useQuery.aggregate.zero.test.native.js.map +1 -0
  16. package/dist/esm/generate-layout.mjs +53 -0
  17. package/dist/esm/generate-layout.mjs.map +1 -1
  18. package/dist/esm/generate-layout.native.js +179 -42
  19. package/dist/esm/generate-layout.native.js.map +1 -1
  20. package/dist/esm/generate-lite.mjs +18 -0
  21. package/dist/esm/generate-lite.mjs.map +1 -1
  22. package/dist/esm/generate-lite.native.js +339 -281
  23. package/dist/esm/generate-lite.native.js.map +1 -1
  24. package/dist/esm/generate-lite.test.mjs +37 -0
  25. package/dist/esm/generate-lite.test.mjs.map +1 -1
  26. package/dist/esm/generate-lite.test.native.js +38 -0
  27. package/dist/esm/generate-lite.test.native.js.map +1 -1
  28. package/dist/esm/generate.test.mjs +25 -0
  29. package/dist/esm/generate.test.mjs.map +1 -1
  30. package/dist/esm/generate.test.native.js +25 -0
  31. package/dist/esm/generate.test.native.js.map +1 -1
  32. package/dist/esm/useQuery.aggregate.zero.test.mjs +118 -0
  33. package/dist/esm/useQuery.aggregate.zero.test.mjs.map +1 -0
  34. package/dist/esm/useQuery.aggregate.zero.test.native.js +131 -0
  35. package/dist/esm/useQuery.aggregate.zero.test.native.js.map +1 -0
  36. package/package.json +2 -2
  37. package/src/generate-layout.ts +89 -0
  38. package/src/generate-lite.test.ts +35 -0
  39. package/src/generate-lite.ts +25 -0
  40. package/src/generate.test.ts +31 -0
  41. package/src/useQuery.aggregate.zero.test.tsx +115 -0
  42. package/types/generate-layout.d.ts.map +1 -1
  43. package/types/generate-lite.d.ts +1 -0
  44. package/types/generate-lite.d.ts.map +1 -1
  45. package/types/useQuery.aggregate.zero.test.d.ts +5 -0
  46. package/types/useQuery.aggregate.zero.test.d.ts.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createBuilder","createSchema","number","string","table","count","defineAggregates","sum","act","createRoot","afterEach","beforeEach","expect","test","createZeroClient","onMutationError","mutations","jsx","globalThis","IS_REACT_ACT_ENVIRONMENT","expense","columns","id","category","amount","primaryKey","categorySpend","expenseCount","spent","schema","tables","enableLegacyQueries","builder","aggregates","source","target","mode","groupBy","expenseMutations","insert","context","value","tx","mutate","categorySpendQuery","args","where","client","models","groupedQueries","instanceName","container","root","stopErrorSink","silentLogSink","log","document","createElement","activeZero","waitForZero","unmount","close","Promise","resolve","setTimeout","rows","Probe","useQuery","render","ProvideZero","server","userID","authData","logSink","children","Reflect","get","zero","expenseMutate","Error","result","apply","toEqual","objectContaining"],"sources":["../../src/useQuery.aggregate.zero.test.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,131 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createBuilder, createSchema, number, string, table } from "@rocicorp/zero";
3
+ import { count, defineAggregates, sum } from "orez-lite/aggregate";
4
+ import { act } from "react";
5
+ import { createRoot } from "react-dom/client";
6
+ import { afterEach, beforeEach, expect, test } from "vitest";
7
+ import { createZeroClient } from "./createZeroClient.native.js";
8
+ import { onMutationError } from "./helpers/useMutation.native.js";
9
+ import { mutations } from "./mutations.native.js";
10
+ function _type_of(obj) {
11
+ "@swc/helpers - typeof";
12
+
13
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
14
+ }
15
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
16
+ var expense = table("expense").columns({
17
+ id: string(),
18
+ category: string(),
19
+ amount: number()
20
+ }).primaryKey("id");
21
+ var categorySpend = table("categorySpend").columns({
22
+ category: string(),
23
+ expenseCount: number(),
24
+ spent: number()
25
+ }).primaryKey("category");
26
+ var schema = createSchema({
27
+ tables: [expense, categorySpend],
28
+ enableLegacyQueries: true
29
+ });
30
+ var builder = createBuilder(schema);
31
+ var aggregates = defineAggregates(schema, {
32
+ categorySpend: {
33
+ source: "expense",
34
+ target: "categorySpend",
35
+ mode: "materialized",
36
+ groupBy: {
37
+ category: "category"
38
+ },
39
+ columns: {
40
+ expenseCount: count(),
41
+ spent: sum("amount")
42
+ }
43
+ }
44
+ });
45
+ var expenseMutations = mutations(expense, function () {
46
+ return true;
47
+ }, {
48
+ insert: async function insert(context, value) {
49
+ await context.tx.mutate.expense.insert(value);
50
+ }
51
+ });
52
+ var categorySpendQuery = function categorySpendQuery2(args) {
53
+ return builder.categorySpend.where("category", args.category);
54
+ };
55
+ var client = createZeroClient({
56
+ schema,
57
+ models: {
58
+ expense: {
59
+ mutate: expenseMutations
60
+ }
61
+ },
62
+ groupedQueries: {
63
+ expense: {
64
+ categorySpendQuery
65
+ }
66
+ },
67
+ aggregates,
68
+ instanceName: "aggregate-react-view-test"
69
+ });
70
+ var container;
71
+ var root;
72
+ var stopErrorSink;
73
+ var silentLogSink = {
74
+ log() {}
75
+ };
76
+ beforeEach(function () {
77
+ stopErrorSink = onMutationError(function () {});
78
+ container = document.createElement("div");
79
+ root = createRoot(container);
80
+ });
81
+ afterEach(async function () {
82
+ var activeZero = await client.waitForZero();
83
+ act(function () {
84
+ return root.unmount();
85
+ });
86
+ await activeZero.close();
87
+ await new Promise(function (resolve) {
88
+ return setTimeout(resolve, 0);
89
+ });
90
+ stopErrorSink();
91
+ });
92
+ test("a mounted useQuery view updates after a custom mutation projects an aggregate", async function () {
93
+ var rows = [];
94
+ function Probe() {
95
+ ;
96
+ [rows] = client.useQuery(categorySpendQuery, {
97
+ category: "Food"
98
+ });
99
+ return null;
100
+ }
101
+ await act(async function () {
102
+ root.render(/* @__PURE__ */_jsx(client.ProvideZero, {
103
+ server: "https://on-zero-aggregate.test",
104
+ userID: "test-user",
105
+ authData: {},
106
+ logSink: silentLogSink,
107
+ children: /* @__PURE__ */_jsx(Probe, {})
108
+ }));
109
+ });
110
+ await act(async function () {
111
+ var mutate = Reflect.get(client.zero, "mutate");
112
+ var expenseMutate = Reflect.get(mutate, "expense");
113
+ var insert2 = Reflect.get(expenseMutate, "insert");
114
+ if (typeof insert2 !== "function") throw new Error("expense insert mutator is unavailable");
115
+ var result = Reflect.apply(insert2, expenseMutate, [{
116
+ id: "expense-1",
117
+ category: "Food",
118
+ amount: 4250
119
+ }]);
120
+ if (!result || (typeof result === "undefined" ? "undefined" : _type_of(result)) !== "object") {
121
+ throw new Error("expense insert did not return a mutation result");
122
+ }
123
+ await Reflect.get(result, "client");
124
+ });
125
+ expect(rows).toEqual([expect.objectContaining({
126
+ category: "Food",
127
+ expenseCount: 1,
128
+ spent: 4250
129
+ })]);
130
+ });
131
+ //# sourceMappingURL=useQuery.aggregate.zero.test.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["jsx","_jsx","createBuilder","createSchema","number","string","table","count","defineAggregates","sum","act","createRoot","afterEach","beforeEach","expect","test","createZeroClient","onMutationError","mutations","_type_of","obj","Symbol","constructor","globalThis","IS_REACT_ACT_ENVIRONMENT","expense","columns","id","category","amount","primaryKey","categorySpend","expenseCount","spent","schema","tables","enableLegacyQueries","builder","aggregates","source","target","mode","groupBy","expenseMutations","insert","context","value","tx","mutate","categorySpendQuery","categorySpendQuery2","args","where","client","models","groupedQueries","instanceName","container","root","stopErrorSink","silentLogSink","log","document","createElement","activeZero","waitForZero","unmount","close","Promise","resolve","setTimeout"],"sources":["../../src/useQuery.aggregate.zero.test.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "on-zero",
3
- "version": "0.16.9",
3
+ "version": "0.16.10",
4
4
  "description": "A typed layer over @rocicorp/zero with queries, mutations, and permissions",
5
5
  "sideEffects": false,
6
6
  "files": [
@@ -105,7 +105,7 @@
105
105
  "chokidar": "^4.0.3",
106
106
  "citty": "^0.1.6",
107
107
  "dequal": "^2.0.3",
108
- "orez-lite": "0.16.9",
108
+ "orez-lite": "0.16.10",
109
109
  "valibot": "^1.1.0"
110
110
  },
111
111
  "peerDependencies": {
@@ -692,6 +692,83 @@ function queriedTables(
692
692
  return reached
693
693
  }
694
694
 
695
+ function aggregateTables(
696
+ ts: typeof import('typescript'),
697
+ namespace: DataNamespace
698
+ ): string[] {
699
+ if (!namespace.aggregatePath) return []
700
+ const source = ts.createSourceFile(
701
+ namespace.aggregatePath,
702
+ readFileSync(namespace.aggregatePath, 'utf8'),
703
+ ts.ScriptTarget.Latest,
704
+ true
705
+ )
706
+ const unwrap = (node: ts.Expression): ts.Expression => {
707
+ let current = node
708
+ while (
709
+ ts.isSatisfiesExpression(current) ||
710
+ ts.isAsExpression(current) ||
711
+ ts.isParenthesizedExpression(current)
712
+ ) {
713
+ current = current.expression
714
+ }
715
+ return current
716
+ }
717
+ const tables = new Set<string>()
718
+ for (const statement of source.statements) {
719
+ if (!ts.isVariableStatement(statement)) continue
720
+ if (
721
+ !statement.modifiers?.some(
722
+ (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword
723
+ )
724
+ ) {
725
+ continue
726
+ }
727
+ for (const declaration of statement.declarationList.declarations) {
728
+ if (
729
+ !ts.isIdentifier(declaration.name) ||
730
+ declaration.name.text !== 'aggregates' ||
731
+ !declaration.initializer
732
+ ) {
733
+ continue
734
+ }
735
+ const definitions = unwrap(declaration.initializer)
736
+ if (!ts.isObjectLiteralExpression(definitions)) {
737
+ throw new Error(
738
+ `[on-zero] ${namespace.aggregatePath} must export aggregates as an object literal`
739
+ )
740
+ }
741
+ for (const property of definitions.properties) {
742
+ if (!ts.isPropertyAssignment(property)) {
743
+ throw new Error(
744
+ `[on-zero] ${namespace.aggregatePath} aggregate definitions must use explicit properties`
745
+ )
746
+ }
747
+ const definition = unwrap(property.initializer)
748
+ if (!ts.isObjectLiteralExpression(definition)) {
749
+ throw new Error(
750
+ `[on-zero] ${namespace.aggregatePath} aggregate ${property.name.getText(source)} must be an object literal`
751
+ )
752
+ }
753
+ for (const fieldName of ['source', 'target']) {
754
+ const field = definition.properties.find(
755
+ (candidate): candidate is ts.PropertyAssignment =>
756
+ ts.isPropertyAssignment(candidate) &&
757
+ propertyName(ts, candidate.name) === fieldName
758
+ )
759
+ if (!field || !ts.isStringLiteralLike(unwrap(field.initializer))) {
760
+ throw new Error(
761
+ `[on-zero] ${namespace.aggregatePath} aggregate ${property.name.getText(source)} ${fieldName} must be a string literal`
762
+ )
763
+ }
764
+ tables.add((unwrap(field.initializer) as ts.StringLiteralLike).text)
765
+ }
766
+ }
767
+ }
768
+ }
769
+ return [...tables].sort()
770
+ }
771
+
695
772
  function mutationSupportTables(
696
773
  ts: typeof import('typescript'),
697
774
  baseDir: string,
@@ -890,6 +967,18 @@ export function discoverDataLayout(
890
967
  )
891
968
  const syncTables = new Set(tables)
892
969
  for (const namespace of instance.namespaces) {
970
+ for (const table of aggregateTables(ts, namespace)) {
971
+ const owner = tableOwners.get(table) ?? relatedOwners.get(table)
972
+ if (owner && owner !== instance.name) {
973
+ throw new Error(
974
+ `[on-zero] ${namespace.name} aggregates in instance '${instance.name}' reach ` +
975
+ `table '${table}' owned by instance '${owner}'`
976
+ )
977
+ }
978
+ relatedOwners.set(table, instance.name)
979
+ tables.add(table)
980
+ syncTables.add(table)
981
+ }
893
982
  for (const reached of queriedTables(ts, namespace, relations)) {
894
983
  const owner = tableOwners.get(reached.table) ?? relatedOwners.get(reached.table)
895
984
  if (owner && owner !== instance.name) {
@@ -129,6 +129,16 @@ describe('generateLite', () => {
129
129
  dir: DIR,
130
130
  parse: makeParse({
131
131
  [`${DIR}/post/queries.ts`]: { mutations: [], queries: [] },
132
+ [`${DIR}/post/aggregates.ts`]: {
133
+ mutations: [],
134
+ queries: [],
135
+ aggregateTables: [],
136
+ },
137
+ [`${DIR}/order/aggregates.ts`]: {
138
+ mutations: [],
139
+ queries: [],
140
+ aggregateTables: [],
141
+ },
132
142
  }),
133
143
  })
134
144
 
@@ -222,6 +232,31 @@ describe('generateLite', () => {
222
232
  expect(result.instances[0]?.syncTables).toEqual(['expense'])
223
233
  })
224
234
 
235
+ test('derives aggregate source and target membership', () => {
236
+ const mutationsPath = `${DIR}/expense/mutations.ts`
237
+ const aggregatesPath = `${DIR}/expense/aggregates.ts`
238
+ const result = generateLite({
239
+ files: {
240
+ [mutationsPath]: '// mutations',
241
+ [aggregatesPath]: '// aggregates',
242
+ },
243
+ dir: DIR,
244
+ parse: makeParse({
245
+ [mutationsPath]: {
246
+ mutations: [{ modelName: 'expense', handlers: [], schema: null }],
247
+ queries: [],
248
+ },
249
+ [aggregatesPath]: {
250
+ mutations: [],
251
+ queries: [],
252
+ aggregateTables: ['expense', 'dashboardSummary'],
253
+ },
254
+ }),
255
+ })
256
+
257
+ expect(result.instances[0]?.syncTables).toEqual(['dashboardSummary', 'expense'])
258
+ })
259
+
225
260
  test('includes a fileless support table in every lite instance that uses it', () => {
226
261
  const files = {
227
262
  [`${DIR}/on-zero.config.ts`]: `export default defineConfig({ instances: { control: { dir: './planes/control', supportTables: ['manual'] }, project: { scope: 'projectId' } } })`,
@@ -110,6 +110,8 @@ export type LiteParsedFile = {
110
110
  queries: LiteQueryExport[]
111
111
  relations?: LiteRelationInfo[]
112
112
  tables?: LiteTableInfo[]
113
+ // source and target table names declared by exported aggregate definitions.
114
+ aggregateTables?: string[]
113
115
  // static table names reached through tx.mutate.<table> or tx.query.<table>.
114
116
  // element access such as tx.mutate[name] is intentionally omitted.
115
117
  supportTables?: string[]
@@ -447,6 +449,17 @@ export function generateLite(opts: LiteGenerateOptions): LiteGenerateResult {
447
449
  (namespace): namespace is LiteNamespace & { modelPath: string } =>
448
450
  namespace.modelPath !== null
449
451
  )
452
+ const aggregateTables = new Map<string, string[]>()
453
+ for (const namespace of namespaces) {
454
+ if (!namespace.aggregatePath) continue
455
+ const parsed = parse(files[namespace.aggregatePath]!, namespace.aggregatePath)
456
+ if (parsed.parseError) {
457
+ throw new Error(
458
+ `[on-zero] unable to derive aggregate membership from ${namespace.aggregatePath}: ${parsed.parseError}`
459
+ )
460
+ }
461
+ aggregateTables.set(namespace.name, [...new Set(parsed.aggregateTables ?? [])])
462
+ }
450
463
  const relations = new Map<string, Map<string, string>>()
451
464
  const tableColumns = new Map<string, Set<string>>()
452
465
  for (const path of Object.keys(files).filter(
@@ -643,6 +656,18 @@ export function generateLite(opts: LiteGenerateOptions): LiteGenerateResult {
643
656
  )
644
657
  const synced = new Set(direct)
645
658
  for (const namespace of instance.namespaces) {
659
+ for (const table of aggregateTables.get(namespace.name) ?? []) {
660
+ const owner = owners.get(table) ?? relatedOwners.get(table)
661
+ if (owner && owner !== instance.name) {
662
+ throw new Error(
663
+ `[on-zero] ${namespace.name} aggregates in instance '${instance.name}' reach ` +
664
+ `table '${table}' owned by instance '${owner}'`
665
+ )
666
+ }
667
+ relatedOwners.set(table, instance.name)
668
+ direct.add(table)
669
+ synced.add(table)
670
+ }
646
671
  for (const query of queryPaths.get(namespace.name) ?? []) {
647
672
  const rootOwner =
648
673
  owners.get(query.rootTable) ?? relatedOwners.get(query.rootTable)
@@ -219,6 +219,37 @@ export async function writeAudit(tx: Transaction) {
219
219
  })
220
220
  })
221
221
 
222
+ test('derives aggregate source and target membership', async () => {
223
+ writeFileSync(
224
+ join(dataDir(), 'expense/mutations.ts'),
225
+ `export const mutate = mutations('expense', permissions, { save: async () => {} })`
226
+ )
227
+ writeFileSync(
228
+ join(dataDir(), 'expense/aggregates.ts'),
229
+ `export const aggregates = {
230
+ dashboardSummary: {
231
+ source: 'expense',
232
+ target: 'dashboardSummary',
233
+ mode: 'materialized',
234
+ groupBy: { userId: 'userId' },
235
+ columns: { expenseCount: count() },
236
+ },
237
+ } satisfies AggregateDefinitions<typeof schema>`
238
+ )
239
+
240
+ await expect(deriveDataMembership({ dir: dataDir() })).resolves.toEqual({
241
+ instances: {
242
+ default: {
243
+ tables: ['dashboardSummary', 'expense'],
244
+ syncTables: ['dashboardSummary', 'expense'],
245
+ supportTables: [],
246
+ scope: null,
247
+ },
248
+ },
249
+ allTables: ['dashboardSummary', 'expense'],
250
+ })
251
+ })
252
+
222
253
  test('includes a fileless support table in every instance that uses it', async () => {
223
254
  writeFileSync(
224
255
  join(dataDir(), 'control/account.ts'),
@@ -0,0 +1,115 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import { createBuilder, createSchema, number, string, table } from '@rocicorp/zero'
4
+ import { count, defineAggregates, sum } from 'orez-lite/aggregate'
5
+ import { act } from 'react'
6
+ import { createRoot, type Root } from 'react-dom/client'
7
+ import { afterEach, beforeEach, expect, test } from 'vitest'
8
+
9
+ import { createZeroClient } from './createZeroClient'
10
+ import { onMutationError } from './helpers/useMutation'
11
+ import { mutations } from './mutations'
12
+
13
+ import type { MutatorContext } from './types'
14
+
15
+ declare global {
16
+ // eslint-disable-next-line no-var
17
+ var IS_REACT_ACT_ENVIRONMENT: boolean | undefined
18
+ }
19
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true
20
+
21
+ const expense = table('expense')
22
+ .columns({ id: string(), category: string(), amount: number() })
23
+ .primaryKey('id')
24
+ const categorySpend = table('categorySpend')
25
+ .columns({ category: string(), expenseCount: number(), spent: number() })
26
+ .primaryKey('category')
27
+ const schema = createSchema({
28
+ tables: [expense, categorySpend],
29
+ enableLegacyQueries: true,
30
+ })
31
+ const builder = createBuilder(schema)
32
+ const aggregates = defineAggregates(schema, {
33
+ categorySpend: {
34
+ source: 'expense',
35
+ target: 'categorySpend',
36
+ mode: 'materialized',
37
+ groupBy: { category: 'category' },
38
+ columns: { expenseCount: count(), spent: sum('amount') },
39
+ },
40
+ })
41
+ const expenseMutations = mutations(expense, () => true, {
42
+ insert: async (
43
+ context: MutatorContext,
44
+ value: { id: string; category: string; amount: number }
45
+ ) => {
46
+ await context.tx.mutate.expense.insert(value)
47
+ },
48
+ })
49
+ const categorySpendQuery = (args: { category: string }) =>
50
+ builder.categorySpend.where('category', args.category)
51
+ const client = createZeroClient({
52
+ schema,
53
+ models: { expense: { mutate: expenseMutations } },
54
+ groupedQueries: { expense: { categorySpendQuery } },
55
+ aggregates,
56
+ instanceName: 'aggregate-react-view-test',
57
+ })
58
+
59
+ let container: HTMLDivElement
60
+ let root: Root
61
+ let stopErrorSink: () => void
62
+ const silentLogSink = { log() {} }
63
+
64
+ beforeEach(() => {
65
+ stopErrorSink = onMutationError(() => {})
66
+ container = document.createElement('div')
67
+ root = createRoot(container)
68
+ })
69
+
70
+ afterEach(async () => {
71
+ const activeZero = await client.waitForZero()
72
+ act(() => root.unmount())
73
+ await activeZero.close()
74
+ await new Promise((resolve) => setTimeout(resolve, 0))
75
+ stopErrorSink()
76
+ })
77
+
78
+ test('a mounted useQuery view updates after a custom mutation projects an aggregate', async () => {
79
+ let rows: readonly { category: string; expenseCount: number; spent: number }[] = []
80
+ function Probe() {
81
+ ;[rows] = client.useQuery(categorySpendQuery, { category: 'Food' })
82
+ return null
83
+ }
84
+
85
+ await act(async () => {
86
+ root.render(
87
+ <client.ProvideZero
88
+ server="https://on-zero-aggregate.test"
89
+ userID="test-user"
90
+ authData={{}}
91
+ logSink={silentLogSink}
92
+ >
93
+ <Probe />
94
+ </client.ProvideZero>
95
+ )
96
+ })
97
+ await act(async () => {
98
+ const mutate = Reflect.get(client.zero, 'mutate')
99
+ const expenseMutate = Reflect.get(mutate, 'expense')
100
+ const insert = Reflect.get(expenseMutate, 'insert')
101
+ if (typeof insert !== 'function')
102
+ throw new Error('expense insert mutator is unavailable')
103
+ const result = Reflect.apply(insert, expenseMutate, [
104
+ { id: 'expense-1', category: 'Food', amount: 4250 },
105
+ ])
106
+ if (!result || typeof result !== 'object') {
107
+ throw new Error('expense insert did not return a mutation result')
108
+ }
109
+ await Reflect.get(result, 'client')
110
+ })
111
+
112
+ expect(rows).toEqual([
113
+ expect.objectContaining({ category: 'Food', expenseCount: 1, spent: 4250 }),
114
+ ])
115
+ })
@@ -1 +1 @@
1
- {"version":3,"file":"generate-layout.d.ts","sourceRoot":"","sources":["../src/generate-layout.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,uDAAuD;IACvD,qBAAqB,EAAE,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,YAAY,EAAE,CAAA;IACzB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAmxBD,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,cAAc,YAAY,CAAC,EAC/B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,UAAU,CAwHZ;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzE"}
1
+ {"version":3,"file":"generate-layout.d.ts","sourceRoot":"","sources":["../src/generate-layout.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,uDAAuD;IACvD,qBAAqB,EAAE,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,YAAY,EAAE,CAAA;IACzB,UAAU,EAAE,aAAa,EAAE,CAAA;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAg2BD,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,cAAc,YAAY,CAAC,EAC/B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,UAAU,CAoIZ;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzE"}
@@ -41,6 +41,7 @@ export type LiteParsedFile = {
41
41
  queries: LiteQueryExport[];
42
42
  relations?: LiteRelationInfo[];
43
43
  tables?: LiteTableInfo[];
44
+ aggregateTables?: string[];
44
45
  supportTables?: string[];
45
46
  imports?: string[];
46
47
  dataConfig?: LiteDataConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"generate-lite.d.ts","sourceRoot":"","sources":["../src/generate-lite.ts"],"names":[],"mappings":"AAmCA,MAAM,MAAM,kBAAkB,GAAG;IAI/B,SAAS,EAAE,MAAM,CAAA;IAEjB,QAAQ,EAAE,KAAK,CAAC;QAEd,IAAI,EAAE,MAAM,CAAA;QAMZ,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAC7B,CAAC,CAAA;IAKF,MAAM,EAAE,cAAc,GAAG,IAAI,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,EAAE,CAAA;IAGrB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACtD,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAE5B,IAAI,EAAE,MAAM,CAAA;IAIZ,SAAS,EAAE,MAAM,CAAA;IAIjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAG5B,YAAY,EAAE,MAAM,EAAE,EAAE,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CACf,MAAM,EACN;QACE,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KACzB,CACF,CAAA;CACF,CAAA;AAGD,MAAM,MAAM,cAAc,GAAG;IAG3B,SAAS,EAAE,kBAAkB,EAAE,CAAA;IAC/B,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC9B,MAAM,CAAC,EAAE,aAAa,EAAE,CAAA;IAGxB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IAExB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAElB,UAAU,CAAC,EAAE,cAAc,CAAA;IAE3B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAID,MAAM,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,cAAc,CAAA;AAElF,MAAM,MAAM,mBAAmB,GAAG;IAGhC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAG7B,GAAG,EAAE,MAAM,CAAA;IAEX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,WAAW,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAG/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAI7B,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;IACjF,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAgSD,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,kBAAkB,CA6X1E"}
1
+ {"version":3,"file":"generate-lite.d.ts","sourceRoot":"","sources":["../src/generate-lite.ts"],"names":[],"mappings":"AAmCA,MAAM,MAAM,kBAAkB,GAAG;IAI/B,SAAS,EAAE,MAAM,CAAA;IAEjB,QAAQ,EAAE,KAAK,CAAC;QAEd,IAAI,EAAE,MAAM,CAAA;QAMZ,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAC7B,CAAC,CAAA;IAKF,MAAM,EAAE,cAAc,GAAG,IAAI,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,EAAE,CAAA;IAGrB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACtD,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAE5B,IAAI,EAAE,MAAM,CAAA;IAIZ,SAAS,EAAE,MAAM,CAAA;IAIjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAG5B,YAAY,EAAE,MAAM,EAAE,EAAE,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CACf,MAAM,EACN;QACE,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KACzB,CACF,CAAA;CACF,CAAA;AAGD,MAAM,MAAM,cAAc,GAAG;IAG3B,SAAS,EAAE,kBAAkB,EAAE,CAAA;IAC/B,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC9B,MAAM,CAAC,EAAE,aAAa,EAAE,CAAA;IAExB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAG1B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IAExB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAElB,UAAU,CAAC,EAAE,cAAc,CAAA;IAE3B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAID,MAAM,MAAM,WAAW,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,cAAc,CAAA;AAElF,MAAM,MAAM,mBAAmB,GAAG;IAGhC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAG7B,GAAG,EAAE,MAAM,CAAA;IAEX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,WAAW,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAG/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAI7B,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;IACjF,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAgSD,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,kBAAkB,CAoZ1E"}
@@ -0,0 +1,5 @@
1
+ declare global {
2
+ var IS_REACT_ACT_ENVIRONMENT: boolean | undefined;
3
+ }
4
+ export {};
5
+ //# sourceMappingURL=useQuery.aggregate.zero.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useQuery.aggregate.zero.test.d.ts","sourceRoot":"","sources":["../src/useQuery.aggregate.zero.test.tsx"],"names":[],"mappings":"AAcA,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,wBAAwB,EAAE,OAAO,GAAG,SAAS,CAAA;CAClD"}