Skip to content

Conversation

@0xcadams
Copy link
Member

@0xcadams 0xcadams commented Dec 23, 2025

  • Introduce BaseDefaultSchema/BaseDefaultContext and use them across Zero options/hooks so defaults propagate without erasing custom types.
  • Make ZeroOptions require context when the context type isn’t unknown, and align generics in zero-react/zero-solid helpers to the new base defaults.
Screenshot 2025-12-23 at 12 12 15 PM Screenshot 2025-12-23 at 12 11 44 PM Screenshot 2025-12-23 at 12 11 28 PM

@vercel
Copy link

vercel bot commented Dec 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
replicache-docs Ready Ready Preview, Comment Dec 23, 2025 9:09pm
zbugs Ready Ready Preview, Comment Dec 23, 2025 9:09pm

@0xcadams 0xcadams requested review from aboodman and arv December 23, 2025 21:10
@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🐰 Bencher Report

Branch0xcadams/default-types-fix
TestbedLinux
Click to view all benchmark results
BenchmarkFile SizeBenchmark Result
kilobytes (KB)
(Result Δ%)
Upper Boundary
kilobytes (KB)
(Limit %)
zero-package.tgz📈 view plot
🚷 view threshold
1,771.84 KB
(+0.01%)Baseline: 1,771.67 KB
1,807.10 KB
(98.05%)
zero.js📈 view plot
🚷 view threshold
240.20 KB
(0.00%)Baseline: 240.20 KB
245.00 KB
(98.04%)
zero.js.br📈 view plot
🚷 view threshold
65.95 KB
(0.00%)Baseline: 65.95 KB
67.27 KB
(98.04%)
🐰 View full continuous benchmarking report in Bencher

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🐰 Bencher Report

Branch0xcadams/default-types-fix
Testbedself-hosted
Click to view all benchmark results
BenchmarkThroughputBenchmark Result
operations / second (ops/s)
(Result Δ%)
Lower Boundary
operations / second (ops/s)
(Limit %)
1 exists: track.exists(album)📈 view plot
🚷 view threshold
14,763.24 ops/s
(+0.15%)Baseline: 14,741.15 ops/s
13,467.80 ops/s
(91.23%)
10 exists (AND)📈 view plot
🚷 view threshold
219,632.37 ops/s
(+0.57%)Baseline: 218,382.66 ops/s
211,332.65 ops/s
(96.22%)
10 exists (OR)📈 view plot
🚷 view threshold
4,339.73 ops/s
(+2.82%)Baseline: 4,220.77 ops/s
3,896.06 ops/s
(89.78%)
12 exists (AND)📈 view plot
🚷 view threshold
192,228.35 ops/s
(-0.09%)Baseline: 192,411.12 ops/s
183,597.36 ops/s
(95.51%)
12 exists (OR)📈 view plot
🚷 view threshold
3,538.37 ops/s
(-1.39%)Baseline: 3,588.22 ops/s
3,340.59 ops/s
(94.41%)
12 level nesting📈 view plot
🚷 view threshold
3,171.18 ops/s
(+1.41%)Baseline: 3,126.99 ops/s
2,907.71 ops/s
(91.69%)
2 exists (AND): track.exists(album).exists(genre)📈 view plot
🚷 view threshold
5,550.41 ops/s
(-0.51%)Baseline: 5,578.72 ops/s
5,134.87 ops/s
(92.51%)
3 exists (AND)📈 view plot
🚷 view threshold
2,145.30 ops/s
(-0.17%)Baseline: 2,149.03 ops/s
1,973.58 ops/s
(92.00%)
3 exists (OR)📈 view plot
🚷 view threshold
1,089.41 ops/s
(+0.97%)Baseline: 1,078.97 ops/s
985.79 ops/s
(90.49%)
5 exists (AND)📈 view plot
🚷 view threshold
345.22 ops/s
(+1.81%)Baseline: 339.10 ops/s
313.04 ops/s
(90.68%)
5 exists (OR)📈 view plot
🚷 view threshold
185.51 ops/s
(+3.50%)Baseline: 179.23 ops/s
165.27 ops/s
(89.09%)
Nested 2 levels: track > album > artist📈 view plot
🚷 view threshold
4,832.04 ops/s
(+0.30%)Baseline: 4,817.57 ops/s
4,458.17 ops/s
(92.26%)
Nested 4 levels: playlist > tracks > album > artist📈 view plot
🚷 view threshold
810.87 ops/s
(+2.39%)Baseline: 791.92 ops/s
729.37 ops/s
(89.95%)
Nested with filters: track > album > artist (filtered)📈 view plot
🚷 view threshold
4,083.57 ops/s
(+1.89%)Baseline: 4,007.94 ops/s
3,664.19 ops/s
(89.73%)
planned: playlist.exists(tracks)📈 view plot
🚷 view threshold
665.16 ops/s
(+1.71%)Baseline: 653.99 ops/s
623.45 ops/s
(93.73%)
planned: track.exists(album) OR exists(genre)📈 view plot
🚷 view threshold
173.54 ops/s
(+0.85%)Baseline: 172.08 ops/s
162.63 ops/s
(93.71%)
planned: track.exists(album) where title="Big Ones"📈 view plot
🚷 view threshold
8,052.73 ops/s
(+1.03%)Baseline: 7,970.26 ops/s
7,566.30 ops/s
(93.96%)
planned: track.exists(album).exists(genre)📈 view plot
🚷 view threshold
42.51 ops/s
(+2.09%)Baseline: 41.64 ops/s
39.91 ops/s
(93.89%)
planned: track.exists(album).exists(genre) with filters📈 view plot
🚷 view threshold
5,677.11 ops/s
(+0.87%)Baseline: 5,628.24 ops/s
5,335.13 ops/s
(93.98%)
planned: track.exists(playlists)📈 view plot
🚷 view threshold
4.19 ops/s
(-0.78%)Baseline: 4.23 ops/s
4.06 ops/s
(96.83%)
unplanned: playlist.exists(tracks)📈 view plot
🚷 view threshold
646.83 ops/s
(+1.86%)Baseline: 635.02 ops/s
607.46 ops/s
(93.91%)
unplanned: track.exists(album) OR exists(genre)📈 view plot
🚷 view threshold
48.73 ops/s
(+2.43%)Baseline: 47.57 ops/s
45.07 ops/s
(92.49%)
unplanned: track.exists(album) where title="Big Ones"📈 view plot
🚷 view threshold
59.63 ops/s
(+0.36%)Baseline: 59.41 ops/s
56.84 ops/s
(95.33%)
unplanned: track.exists(album).exists(genre)📈 view plot
🚷 view threshold
41.75 ops/s
(+0.88%)Baseline: 41.39 ops/s
39.59 ops/s
(94.82%)
unplanned: track.exists(album).exists(genre) with filters📈 view plot
🚷 view threshold
57.83 ops/s
(-0.08%)Baseline: 57.87 ops/s
55.53 ops/s
(96.02%)
unplanned: track.exists(playlists)📈 view plot
🚷 view threshold
4.32 ops/s
(+2.16%)Baseline: 4.23 ops/s
4.07 ops/s
(94.07%)
zpg: all playlists📈 view plot
🚷 view threshold
5.83 ops/s
(+0.25%)Baseline: 5.82 ops/s
5.68 ops/s
(97.39%)
zql: all playlists📈 view plot
🚷 view threshold
8.28 ops/s
(+2.34%)Baseline: 8.09 ops/s
7.50 ops/s
(90.66%)
zql: edit for limited query, inside the bound📈 view plot
🚷 view threshold
217,113.11 ops/s
(-0.94%)Baseline: 219,172.84 ops/s
201,098.09 ops/s
(92.62%)
zql: edit for limited query, outside the bound📈 view plot
🚷 view threshold
230,558.71 ops/s
(+0.69%)Baseline: 228,985.69 ops/s
197,691.79 ops/s
(85.74%)
zql: push into limited query, inside the bound📈 view plot
🚷 view threshold
113,619.06 ops/s
(+0.41%)Baseline: 113,151.50 ops/s
106,222.15 ops/s
(93.49%)
zql: push into limited query, outside the bound📈 view plot
🚷 view threshold
439,506.19 ops/s
(+5.72%)Baseline: 415,739.66 ops/s
360,434.85 ops/s
(82.01%)
zql: push into unlimited query📈 view plot
🚷 view threshold
373,007.95 ops/s
(+8.19%)Baseline: 344,769.79 ops/s
313,153.74 ops/s
(83.95%)
zqlite: all playlists📈 view plot
🚷 view threshold
1.91 ops/s
(+1.18%)Baseline: 1.88 ops/s
1.80 ops/s
(94.16%)
zqlite: edit for limited query, inside the bound📈 view plot
🚷 view threshold
79,769.20 ops/s
(+0.33%)Baseline: 79,507.40 ops/s
71,209.59 ops/s
(89.27%)
zqlite: edit for limited query, outside the bound📈 view plot
🚷 view threshold
81,155.64 ops/s
(+1.33%)Baseline: 80,092.04 ops/s
67,890.67 ops/s
(83.65%)
zqlite: push into limited query, inside the bound📈 view plot
🚷 view threshold
4,118.16 ops/s
(-0.44%)Baseline: 4,136.20 ops/s
3,988.68 ops/s
(96.86%)
zqlite: push into limited query, outside the bound📈 view plot
🚷 view threshold
88,006.61 ops/s
(-3.12%)Baseline: 90,844.03 ops/s
83,214.55 ops/s
(94.55%)
zqlite: push into unlimited query📈 view plot
🚷 view threshold
122,306.23 ops/s
(-5.42%)Baseline: 129,316.21 ops/s
118,945.12 ops/s
(97.25%)
🐰 View full continuous benchmarking report in Bencher

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

🐰 Bencher Report

Branch0xcadams/default-types-fix
Testbedself-hosted
Click to view all benchmark results
BenchmarkThroughputBenchmark Result
operations / second (ops/s)
(Result Δ%)
Lower Boundary
operations / second (ops/s)
(Limit %)
src/client/custom.bench.ts > big schema📈 view plot
🚷 view threshold
145,936.81 ops/s
(-74.09%)Baseline: 563,179.84 ops/s
-309,484.71 ops/s
(-212.07%)
src/client/zero.bench.ts > basics > All 1000 rows x 10 columns (numbers)📈 view plot
🚷 view threshold
2,642.41 ops/s
(+3.18%)Baseline: 2,561.07 ops/s
2,274.48 ops/s
(86.08%)
src/client/zero.bench.ts > pk compare > pk = N📈 view plot
🚷 view threshold
68,680.26 ops/s
(+4.88%)Baseline: 65,487.53 ops/s
59,634.05 ops/s
(86.83%)
src/client/zero.bench.ts > with filter > Lower rows 500 x 10 columns (numbers)📈 view plot
🚷 view threshold
3,962.00 ops/s
(+1.11%)Baseline: 3,918.63 ops/s
3,598.49 ops/s
(90.82%)
🐰 View full continuous benchmarking report in Bencher

@aboodman
Copy link
Contributor

I have only skimmed this so I might be misunderstanding...

IIUC this changes the meaning of the types defined by module extension from being the "default" type to a required base type. If so, I think developers can still end up with cases where the types "lie". Consider BaseDefaultContext as an example - because we are requiring that C extend BaseDefaultContext at each usage, developer can call useZero with some context C1 that extends BaseDefaultContext but is different than the context that Zero was actually instantiated with. The types would allow this happily and the user would get some confusing runtime error.

@0xcadams
Copy link
Member Author

I have only skimmed this so I might be misunderstanding...

IIUC this changes the meaning of the types defined by module extension from being the "default" type to a required base type. If so, I think developers can still end up with cases where the types "lie". Consider BaseDefaultContext as an example - because we are requiring that C extend BaseDefaultContext at each usage, developer can call useZero with some context C1 that extends BaseDefaultContext but is different than the context that Zero was actually instantiated with. The types would allow this happily and the user would get some confusing runtime error.

What would be the confusing runtime error? They would see only the properties in the types. We actually do exactly that in zbugs. But since the types don't show exp and other unrelated JWT fields, nothing happens.

@aboodman
Copy link
Contributor

aboodman commented Dec 24, 2025

I'm thinking something like this:

// zero/auth.ts
export type MyContext = {
  userID: string;
}

declare module '@rocicorp/zero' {
  interface DefaultTypes {
    context: MyContext;
  }
}

// zero-init.ts
<ZeroProvider context={{userID: 42}}>...</ZeroProvider>

// my-component.ts
type ContextWithRole = MyContext & {role: string}

const z = useZero<ContextWithRole,..>();

I think the types will allow this. But context isn't actually a MyContextWithRole. So .role will be undefined, not string at runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants