on-zero 0.14.3 → 0.14.4

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 (41) hide show
  1. package/README.md +7 -0
  2. package/dist/cjs/createUseQueryDirect.cjs +6 -6
  3. package/dist/cjs/createUseQueryDirect.native.js +6 -9
  4. package/dist/cjs/createUseQueryDirect.native.js.map +1 -1
  5. package/dist/cjs/createZeroClient.cjs +28 -30
  6. package/dist/cjs/createZeroClient.native.js +49 -35
  7. package/dist/cjs/createZeroClient.native.js.map +1 -1
  8. package/dist/cjs/provideZero.eagerInstance.test.cjs +196 -0
  9. package/dist/cjs/provideZero.eagerInstance.test.native.js +229 -0
  10. package/dist/cjs/provideZero.eagerInstance.test.native.js.map +1 -0
  11. package/dist/cjs/provideZero.ssr.test.cjs +60 -0
  12. package/dist/cjs/provideZero.ssr.test.native.js +69 -0
  13. package/dist/cjs/provideZero.ssr.test.native.js.map +1 -0
  14. package/dist/esm/createUseQueryDirect.mjs +6 -6
  15. package/dist/esm/createUseQueryDirect.mjs.map +1 -1
  16. package/dist/esm/createUseQueryDirect.native.js +6 -9
  17. package/dist/esm/createUseQueryDirect.native.js.map +1 -1
  18. package/dist/esm/createZeroClient.mjs +28 -30
  19. package/dist/esm/createZeroClient.mjs.map +1 -1
  20. package/dist/esm/createZeroClient.native.js +49 -35
  21. package/dist/esm/createZeroClient.native.js.map +1 -1
  22. package/dist/esm/provideZero.eagerInstance.test.mjs +197 -0
  23. package/dist/esm/provideZero.eagerInstance.test.mjs.map +1 -0
  24. package/dist/esm/provideZero.eagerInstance.test.native.js +227 -0
  25. package/dist/esm/provideZero.eagerInstance.test.native.js.map +1 -0
  26. package/dist/esm/provideZero.ssr.test.mjs +61 -0
  27. package/dist/esm/provideZero.ssr.test.mjs.map +1 -0
  28. package/dist/esm/provideZero.ssr.test.native.js +67 -0
  29. package/dist/esm/provideZero.ssr.test.native.js.map +1 -0
  30. package/package.json +2 -2
  31. package/src/createUseQueryDirect.tsx +22 -17
  32. package/src/createZeroClient.tsx +86 -75
  33. package/src/multiInstanceNested.test.tsx +2 -2
  34. package/src/provideZero.eagerInstance.test.tsx +235 -0
  35. package/src/provideZero.ssr.test.tsx +69 -0
  36. package/types/createUseQueryDirect.d.ts.map +1 -1
  37. package/types/createZeroClient.d.ts.map +1 -1
  38. package/types/provideZero.eagerInstance.test.d.ts +5 -0
  39. package/types/provideZero.eagerInstance.test.d.ts.map +1 -0
  40. package/types/provideZero.ssr.test.d.ts +2 -0
  41. package/types/provideZero.ssr.test.d.ts.map +1 -0
@@ -0,0 +1,197 @@
1
+ import { createSchema, string, table } from "@rocicorp/zero";
2
+ import { useZero } from "@rocicorp/zero/react";
3
+ import { act, StrictMode } from "react";
4
+ import { createRoot } from "react-dom/client";
5
+ import { renderToString } from "react-dom/server";
6
+ import { afterEach, beforeEach, expect, test, vi } from "vitest";
7
+ import { createZeroClient } from "./createZeroClient.mjs";
8
+ import { jsx } from "react/jsx-runtime";
9
+ const fakeZero = vi.hoisted(() => {
10
+ const instances = [];
11
+ class FakeZero {
12
+ clientID;
13
+ context = {};
14
+ query = {};
15
+ connection = {
16
+ state: {
17
+ current: {
18
+ name: "connecting"
19
+ },
20
+ subscribe: () => () => {}
21
+ },
22
+ connect: vi.fn(async () => {})
23
+ };
24
+ close = vi.fn();
25
+ delete = vi.fn(async () => ({
26
+ errors: []
27
+ }));
28
+ run = vi.fn(async () => []);
29
+ constructor(options) {
30
+ instances.push(this);
31
+ this.clientID = `fake-${instances.length}-${options.userID ?? "anon"}`;
32
+ }
33
+ }
34
+ return {
35
+ FakeZero,
36
+ instances
37
+ };
38
+ });
39
+ vi.mock("@rocicorp/zero", async importOriginal => {
40
+ const actual = await importOriginal();
41
+ return {
42
+ ...actual,
43
+ Zero: fakeZero.FakeZero
44
+ };
45
+ });
46
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
47
+ const todoTable = table("todo").columns({
48
+ id: string(),
49
+ title: string()
50
+ }).primaryKey("id");
51
+ const schema = createSchema({
52
+ tables: [todoTable]
53
+ });
54
+ let clientCount = 0;
55
+ const makeClient = () => createZeroClient({
56
+ schema,
57
+ models: {},
58
+ groupedQueries: {},
59
+ instanceName: `eager-instance-${++clientCount}`
60
+ });
61
+ let container;
62
+ let root;
63
+ beforeEach(() => {
64
+ fakeZero.instances.length = 0;
65
+ container = document.createElement("div");
66
+ root = null;
67
+ });
68
+ afterEach(() => {
69
+ if (root) act(() => root?.unmount());
70
+ });
71
+ test("a consumer reading zero in its first render gets a live instance, with no effects flushed", () => {
72
+ const client = makeClient();
73
+ const install = vi.fn();
74
+ const seen = {};
75
+ const Probe = () => {
76
+ seen.transportInstalled = install.mock.calls.length > 0;
77
+ seen.contextClientID = useZero().clientID;
78
+ try {
79
+ seen.facadeClientID = client.zero.clientID;
80
+ } catch (error) {
81
+ seen.error = error.message;
82
+ }
83
+ return null;
84
+ };
85
+ renderToString(/* @__PURE__ */jsx(client.ProvideZero, {
86
+ cacheURL: "http://127.0.0.1:7788/zero",
87
+ userID: "first-render",
88
+ transport: {
89
+ install
90
+ },
91
+ children: /* @__PURE__ */jsx(Probe, {})
92
+ }));
93
+ expect(seen.error).toBeUndefined();
94
+ expect(fakeZero.instances.length).toBe(1);
95
+ expect(seen.facadeClientID).toBe(fakeZero.instances[0].clientID);
96
+ expect(seen.contextClientID).toBe(fakeZero.instances[0].clientID);
97
+ expect(seen.transportInstalled).toBe(true);
98
+ });
99
+ test("the first committed render already carries the real instance", () => {
100
+ const client = makeClient();
101
+ const clientIDs = [];
102
+ const Probe = () => {
103
+ clientIDs.push(useZero().clientID);
104
+ return null;
105
+ };
106
+ root = createRoot(container);
107
+ act(() => {
108
+ root?.render(/* @__PURE__ */jsx(client.ProvideZero, {
109
+ cacheURL: "http://127.0.0.1:7788/zero",
110
+ userID: "committed",
111
+ children: /* @__PURE__ */jsx(Probe, {})
112
+ }));
113
+ });
114
+ expect(clientIDs.length).toBeGreaterThan(0);
115
+ expect(clientIDs).not.toContain("disabled");
116
+ expect(clientIDs[0]).toBe(fakeZero.instances[0].clientID);
117
+ });
118
+ test("StrictMode double-invoked render constructs exactly one instance", () => {
119
+ const client = makeClient();
120
+ root = createRoot(container);
121
+ act(() => {
122
+ root?.render(/* @__PURE__ */jsx(StrictMode, {
123
+ children: /* @__PURE__ */jsx(client.ProvideZero, {
124
+ cacheURL: "http://127.0.0.1:7788/zero",
125
+ userID: "strict",
126
+ children: /* @__PURE__ */jsx("span", {
127
+ children: "ok"
128
+ })
129
+ })
130
+ }));
131
+ });
132
+ expect(fakeZero.instances.length).toBe(1);
133
+ expect(fakeZero.instances[0].close).not.toHaveBeenCalled();
134
+ });
135
+ test("an identity change rotates the instance and closes the outgoing one", () => {
136
+ const client = makeClient();
137
+ root = createRoot(container);
138
+ const render = userID => act(() => {
139
+ root?.render(/* @__PURE__ */jsx(client.ProvideZero, {
140
+ cacheURL: "http://127.0.0.1:7788/zero",
141
+ userID,
142
+ children: /* @__PURE__ */jsx("span", {
143
+ children: "ok"
144
+ })
145
+ }));
146
+ });
147
+ render("one");
148
+ expect(fakeZero.instances.length).toBe(1);
149
+ render("two");
150
+ expect(fakeZero.instances.length).toBe(2);
151
+ expect(fakeZero.instances[0].close).toHaveBeenCalled();
152
+ expect(fakeZero.instances[1].close).not.toHaveBeenCalled();
153
+ });
154
+ test("a rotation that never commits is undone, not duplicated", () => {
155
+ const client = makeClient();
156
+ root = createRoot(container);
157
+ const mount = userID => act(() => {
158
+ root?.render(/* @__PURE__ */jsx(client.ProvideZero, {
159
+ cacheURL: "http://127.0.0.1:7788/zero",
160
+ userID,
161
+ children: /* @__PURE__ */jsx("span", {
162
+ children: "ok"
163
+ })
164
+ }));
165
+ });
166
+ mount("committed");
167
+ const first = fakeZero.instances[0];
168
+ renderToString(/* @__PURE__ */jsx(client.ProvideZero, {
169
+ cacheURL: "http://127.0.0.1:7788/zero",
170
+ userID: "abandoned",
171
+ children: /* @__PURE__ */jsx("span", {
172
+ children: "ok"
173
+ })
174
+ }));
175
+ expect(fakeZero.instances.length).toBe(2);
176
+ expect(first.close).not.toHaveBeenCalled();
177
+ mount("committed");
178
+ expect(fakeZero.instances.length).toBe(2);
179
+ expect(first.close).not.toHaveBeenCalled();
180
+ expect(fakeZero.instances[1].close).toHaveBeenCalled();
181
+ });
182
+ test("disable=true constructs nothing", () => {
183
+ const client = makeClient();
184
+ root = createRoot(container);
185
+ act(() => {
186
+ root?.render(/* @__PURE__ */jsx(client.ProvideZero, {
187
+ cacheURL: "http://127.0.0.1:7788/zero",
188
+ userID: "off",
189
+ disable: true,
190
+ children: /* @__PURE__ */jsx("span", {
191
+ children: "ok"
192
+ })
193
+ }));
194
+ });
195
+ expect(fakeZero.instances.length).toBe(0);
196
+ });
197
+ //# sourceMappingURL=provideZero.eagerInstance.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createSchema","string","table","useZero","act","StrictMode","createRoot","renderToString","afterEach","beforeEach","expect","test","vi","createZeroClient","jsx","fakeZero","hoisted","instances","FakeZero","clientID","context","query","connection","state","current","name","subscribe","connect","fn","close","delete","errors","run","constructor","options","push","length","userID","mock","importOriginal","actual","Zero","globalThis","IS_REACT_ACT_ENVIRONMENT","todoTable","columns","id","title","primaryKey","schema","tables","clientCount","makeClient","models","groupedQueries","instanceName","container","root","document","createElement","unmount","client","install","seen","Probe","transportInstalled","calls","contextClientID","facadeClientID","zero","error","message","ProvideZero","cacheURL","transport","children","toBeUndefined","toBe","clientIDs","render","toBeGreaterThan","not","toContain","toHaveBeenCalled","mount","first","disable"],"sources":["../../src/provideZero.eagerInstance.test.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,227 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createSchema, string, table } from "@rocicorp/zero";
3
+ import { useZero } from "@rocicorp/zero/react";
4
+ import { act, StrictMode } from "react";
5
+ import { createRoot } from "react-dom/client";
6
+ import { renderToString } from "react-dom/server";
7
+ import { afterEach, beforeEach, expect, test, vi } from "vitest";
8
+ import { createZeroClient } from "./createZeroClient.native.js";
9
+ function _class_call_check(instance, Constructor) {
10
+ if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
11
+ }
12
+ function _define_property(obj, key, value) {
13
+ if (key in obj) {
14
+ Object.defineProperty(obj, key, {
15
+ value,
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true
19
+ });
20
+ } else obj[key] = value;
21
+ return obj;
22
+ }
23
+ var fakeZero = vi.hoisted(function () {
24
+ var instances = [];
25
+ var FakeZero = function FakeZero2(options) {
26
+ "use strict";
27
+
28
+ _class_call_check(this, FakeZero2);
29
+ var _options_userID;
30
+ _define_property(this, "clientID", void 0);
31
+ _define_property(this, "context", {});
32
+ _define_property(this, "query", {});
33
+ _define_property(this, "connection", {
34
+ state: {
35
+ current: {
36
+ name: "connecting"
37
+ },
38
+ subscribe: function subscribe() {
39
+ return function () {};
40
+ }
41
+ },
42
+ connect: vi.fn(async function () {})
43
+ });
44
+ _define_property(this, "close", vi.fn());
45
+ _define_property(this, "delete", vi.fn(async function () {
46
+ return {
47
+ errors: []
48
+ };
49
+ }));
50
+ _define_property(this, "run", vi.fn(async function () {
51
+ return [];
52
+ }));
53
+ instances.push(this);
54
+ this.clientID = `fake-${instances.length}-${(_options_userID = options.userID) !== null && _options_userID !== void 0 ? _options_userID : "anon"}`;
55
+ };
56
+ return {
57
+ FakeZero,
58
+ instances
59
+ };
60
+ });
61
+ vi.mock("@rocicorp/zero", async function (importOriginal) {
62
+ var actual = await importOriginal();
63
+ return {
64
+ ...actual,
65
+ Zero: fakeZero.FakeZero
66
+ };
67
+ });
68
+ globalThis.IS_REACT_ACT_ENVIRONMENT = true;
69
+ var todoTable = table("todo").columns({
70
+ id: string(),
71
+ title: string()
72
+ }).primaryKey("id");
73
+ var schema = createSchema({
74
+ tables: [todoTable]
75
+ });
76
+ var clientCount = 0;
77
+ var makeClient = function makeClient2() {
78
+ return createZeroClient({
79
+ schema,
80
+ models: {},
81
+ groupedQueries: {},
82
+ instanceName: `eager-instance-${++clientCount}`
83
+ });
84
+ };
85
+ var container;
86
+ var root;
87
+ beforeEach(function () {
88
+ fakeZero.instances.length = 0;
89
+ container = document.createElement("div");
90
+ root = null;
91
+ });
92
+ afterEach(function () {
93
+ if (root) act(function () {
94
+ return root === null || root === void 0 ? void 0 : root.unmount();
95
+ });
96
+ });
97
+ test("a consumer reading zero in its first render gets a live instance, with no effects flushed", function () {
98
+ var client = makeClient();
99
+ var install = vi.fn();
100
+ var seen = {};
101
+ var Probe = function Probe2() {
102
+ seen.transportInstalled = install.mock.calls.length > 0;
103
+ seen.contextClientID = useZero().clientID;
104
+ try {
105
+ seen.facadeClientID = client.zero.clientID;
106
+ } catch (error) {
107
+ seen.error = error.message;
108
+ }
109
+ return null;
110
+ };
111
+ renderToString(/* @__PURE__ */_jsx(client.ProvideZero, {
112
+ cacheURL: "http://127.0.0.1:7788/zero",
113
+ userID: "first-render",
114
+ transport: {
115
+ install
116
+ },
117
+ children: /* @__PURE__ */_jsx(Probe, {})
118
+ }));
119
+ expect(seen.error).toBeUndefined();
120
+ expect(fakeZero.instances.length).toBe(1);
121
+ expect(seen.facadeClientID).toBe(fakeZero.instances[0].clientID);
122
+ expect(seen.contextClientID).toBe(fakeZero.instances[0].clientID);
123
+ expect(seen.transportInstalled).toBe(true);
124
+ });
125
+ test("the first committed render already carries the real instance", function () {
126
+ var client = makeClient();
127
+ var clientIDs = [];
128
+ var Probe = function Probe2() {
129
+ clientIDs.push(useZero().clientID);
130
+ return null;
131
+ };
132
+ root = createRoot(container);
133
+ act(function () {
134
+ root === null || root === void 0 ? void 0 : root.render(/* @__PURE__ */_jsx(client.ProvideZero, {
135
+ cacheURL: "http://127.0.0.1:7788/zero",
136
+ userID: "committed",
137
+ children: /* @__PURE__ */_jsx(Probe, {})
138
+ }));
139
+ });
140
+ expect(clientIDs.length).toBeGreaterThan(0);
141
+ expect(clientIDs).not.toContain("disabled");
142
+ expect(clientIDs[0]).toBe(fakeZero.instances[0].clientID);
143
+ });
144
+ test("StrictMode double-invoked render constructs exactly one instance", function () {
145
+ var client = makeClient();
146
+ root = createRoot(container);
147
+ act(function () {
148
+ root === null || root === void 0 ? void 0 : root.render(/* @__PURE__ */_jsx(StrictMode, {
149
+ children: /* @__PURE__ */_jsx(client.ProvideZero, {
150
+ cacheURL: "http://127.0.0.1:7788/zero",
151
+ userID: "strict",
152
+ children: /* @__PURE__ */_jsx("span", {
153
+ children: "ok"
154
+ })
155
+ })
156
+ }));
157
+ });
158
+ expect(fakeZero.instances.length).toBe(1);
159
+ expect(fakeZero.instances[0].close).not.toHaveBeenCalled();
160
+ });
161
+ test("an identity change rotates the instance and closes the outgoing one", function () {
162
+ var client = makeClient();
163
+ root = createRoot(container);
164
+ var render = function render2(userID) {
165
+ return act(function () {
166
+ root === null || root === void 0 ? void 0 : root.render(/* @__PURE__ */_jsx(client.ProvideZero, {
167
+ cacheURL: "http://127.0.0.1:7788/zero",
168
+ userID,
169
+ children: /* @__PURE__ */_jsx("span", {
170
+ children: "ok"
171
+ })
172
+ }));
173
+ });
174
+ };
175
+ render("one");
176
+ expect(fakeZero.instances.length).toBe(1);
177
+ render("two");
178
+ expect(fakeZero.instances.length).toBe(2);
179
+ expect(fakeZero.instances[0].close).toHaveBeenCalled();
180
+ expect(fakeZero.instances[1].close).not.toHaveBeenCalled();
181
+ });
182
+ test("a rotation that never commits is undone, not duplicated", function () {
183
+ var client = makeClient();
184
+ root = createRoot(container);
185
+ var mount = function mount2(userID) {
186
+ return act(function () {
187
+ root === null || root === void 0 ? void 0 : root.render(/* @__PURE__ */_jsx(client.ProvideZero, {
188
+ cacheURL: "http://127.0.0.1:7788/zero",
189
+ userID,
190
+ children: /* @__PURE__ */_jsx("span", {
191
+ children: "ok"
192
+ })
193
+ }));
194
+ });
195
+ };
196
+ mount("committed");
197
+ var first = fakeZero.instances[0];
198
+ renderToString(/* @__PURE__ */_jsx(client.ProvideZero, {
199
+ cacheURL: "http://127.0.0.1:7788/zero",
200
+ userID: "abandoned",
201
+ children: /* @__PURE__ */_jsx("span", {
202
+ children: "ok"
203
+ })
204
+ }));
205
+ expect(fakeZero.instances.length).toBe(2);
206
+ expect(first.close).not.toHaveBeenCalled();
207
+ mount("committed");
208
+ expect(fakeZero.instances.length).toBe(2);
209
+ expect(first.close).not.toHaveBeenCalled();
210
+ expect(fakeZero.instances[1].close).toHaveBeenCalled();
211
+ });
212
+ test("disable=true constructs nothing", function () {
213
+ var client = makeClient();
214
+ root = createRoot(container);
215
+ act(function () {
216
+ root === null || root === void 0 ? void 0 : root.render(/* @__PURE__ */_jsx(client.ProvideZero, {
217
+ cacheURL: "http://127.0.0.1:7788/zero",
218
+ userID: "off",
219
+ disable: true,
220
+ children: /* @__PURE__ */_jsx("span", {
221
+ children: "ok"
222
+ })
223
+ }));
224
+ });
225
+ expect(fakeZero.instances.length).toBe(0);
226
+ });
227
+ //# sourceMappingURL=provideZero.eagerInstance.test.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["jsx","_jsx","createSchema","string","table","useZero","act","StrictMode","createRoot","renderToString","afterEach","beforeEach","expect","test","vi","createZeroClient","_class_call_check","instance","Constructor","TypeError","_define_property","obj","key","value","Object","defineProperty","enumerable","configurable","writable","fakeZero","hoisted","instances","FakeZero","FakeZero2","options","_options_userID","state","current","name","subscribe","connect","fn","errors","push","clientID","length","userID","mock","importOriginal","actual","Zero","globalThis","IS_REACT_ACT_ENVIRONMENT","todoTable","columns","id","title","primaryKey","schema","tables","clientCount","makeClient","makeClient2","models","groupedQueries","instanceName","container","root","document","createElement","unmount","client","install","seen","Probe","Probe2","transportInstalled","calls","contextClientID","facadeClientID","zero","error","message","ProvideZero","cacheURL","transport","children","toBeUndefined","toBe","clientIDs","render","toBeGreaterThan","not","toContain"],"sources":["../../src/provideZero.eagerInstance.test.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,61 @@
1
+ import { createSchema, string, table } from "@rocicorp/zero";
2
+ import { useZero } from "@rocicorp/zero/react";
3
+ import { renderToString } from "react-dom/server";
4
+ import { expect, test, vi } from "vitest";
5
+ import { createZeroClient } from "./createZeroClient.mjs";
6
+ import { IS_SERVER_RUNTIME } from "./helpers/platform.mjs";
7
+ import { jsx } from "react/jsx-runtime";
8
+ const fakeZero = vi.hoisted(() => {
9
+ const instances = [];
10
+ class FakeZero {
11
+ constructor() {
12
+ instances.push(this);
13
+ }
14
+ }
15
+ return {
16
+ FakeZero,
17
+ instances
18
+ };
19
+ });
20
+ vi.mock("@rocicorp/zero", async importOriginal => {
21
+ const actual = await importOriginal();
22
+ return {
23
+ ...actual,
24
+ Zero: fakeZero.FakeZero
25
+ };
26
+ });
27
+ if (typeof window !== "undefined") {
28
+ throw new Error("provideZero.ssr.test.tsx must run with @vitest-environment node");
29
+ }
30
+ const todoTable = table("todo").columns({
31
+ id: string(),
32
+ title: string()
33
+ }).primaryKey("id");
34
+ const schema = createSchema({
35
+ tables: [todoTable]
36
+ });
37
+ const client = createZeroClient({
38
+ schema,
39
+ models: {},
40
+ groupedQueries: {},
41
+ instanceName: "ssr-eager-test"
42
+ });
43
+ test("the server runtime is what this file exercises", () => {
44
+ expect(IS_SERVER_RUNTIME).toBe(true);
45
+ });
46
+ test("rendering ProvideZero on the server constructs no client", () => {
47
+ let contextClientID;
48
+ const Probe = () => {
49
+ contextClientID = useZero().clientID;
50
+ return null;
51
+ };
52
+ renderToString(/* @__PURE__ */jsx(client.ProvideZero, {
53
+ cacheURL: "http://127.0.0.1:7788/zero",
54
+ userID: "ssr",
55
+ children: /* @__PURE__ */jsx(Probe, {})
56
+ }));
57
+ expect(fakeZero.instances.length).toBe(0);
58
+ expect(contextClientID).toBe("disabled");
59
+ expect(() => client.zero.clientID).toThrow(/Zero instance not initialized/);
60
+ });
61
+ //# sourceMappingURL=provideZero.ssr.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createSchema","string","table","useZero","renderToString","expect","test","vi","createZeroClient","IS_SERVER_RUNTIME","jsx","fakeZero","hoisted","instances","FakeZero","constructor","push","mock","importOriginal","actual","Zero","window","Error","todoTable","columns","id","title","primaryKey","schema","tables","client","models","groupedQueries","instanceName","toBe","contextClientID","Probe","clientID","ProvideZero","cacheURL","userID","children","length","zero","toThrow"],"sources":["../../src/provideZero.ssr.test.tsx"],"sourcesContent":[null],"mappings":"AAOA,SAASA,YAAA,EAAcC,MAAA,EAAQC,KAAA,QAAa;AAC5C,SAASC,OAAA,QAAe;AACxB,SAASC,cAAA,QAAsB;AAC/B,SAASC,MAAA,EAAQC,IAAA,EAAMC,EAAA,QAAU;AAiBjC,SAASC,gBAAA,QAAwB;AACjC,SAASC,iBAAA,QAAyB;AA+B5B,SAAAC,GAAA;AA/CN,MAAMC,QAAA,GAAWJ,EAAA,CAAGK,OAAA,CAAQ,MAAM;EAChC,MAAMC,SAAA,GAAuB,EAAC;EAC9B,MAAMC,QAAA,CAAS;IACbC,YAAA,EAAc;MACZF,SAAA,CAAUG,IAAA,CAAK,IAAI;IACrB;EACF;EACA,OAAO;IAAEF,QAAA;IAAUD;EAAU;AAC/B,CAAC;AAEDN,EAAA,CAAGU,IAAA,CAAK,kBAAkB,MAAOC,cAAA,IAAmB;EAClD,MAAMC,MAAA,GAAS,MAAMD,cAAA,CAAgD;EACrE,OAAO;IAAE,GAAGC,MAAA;IAAQC,IAAA,EAAMT,QAAA,CAASG;EAAS;AAC9C,CAAC;AAKD,IAAI,OAAOO,MAAA,KAAW,aAAa;EACjC,MAAM,IAAIC,KAAA,CAAM,iEAAiE;AACnF;AAEA,MAAMC,SAAA,GAAYrB,KAAA,CAAM,MAAM,EAC3BsB,OAAA,CAAQ;EAAEC,EAAA,EAAIxB,MAAA,CAAO;EAAGyB,KAAA,EAAOzB,MAAA,CAAO;AAAE,CAAC,EACzC0B,UAAA,CAAW,IAAI;AAClB,MAAMC,MAAA,GAAS5B,YAAA,CAAa;EAAE6B,MAAA,EAAQ,CAACN,SAAS;AAAE,CAAC;AAEnD,MAAMO,MAAA,GAAStB,gBAAA,CAAiB;EAC9BoB,MAAA;EACAG,MAAA,EAAQ,CAAC;EACTC,cAAA,EAAgB,CAAC;EACjBC,YAAA,EAAc;AAChB,CAAC;AAED3B,IAAA,CAAK,kDAAkD,MAAM;EAC3DD,MAAA,CAAOI,iBAAiB,EAAEyB,IAAA,CAAK,IAAI;AACrC,CAAC;AAED5B,IAAA,CAAK,4DAA4D,MAAM;EACrE,IAAI6B,eAAA;EACJ,MAAMC,KAAA,GAAQA,CAAA,KAAM;IAClBD,eAAA,GAAmBhC,OAAA,CAAQ,EAAsCkC,QAAA;IACjE,OAAO;EACT;EAEAjC,cAAA,CACE,eAAAM,GAAA,CAACoB,MAAA,CAAOQ,WAAA,EAAP;IAAmBC,QAAA,EAAS;IAA6BC,MAAA,EAAO;IAC/DC,QAAA,iBAAA/B,GAAA,CAAC0B,KAAA,IAAM;EAAA,CACT,CACF;EAEA/B,MAAA,CAAOM,QAAA,CAASE,SAAA,CAAU6B,MAAM,EAAER,IAAA,CAAK,CAAC;EACxC7B,MAAA,CAAO8B,eAAe,EAAED,IAAA,CAAK,UAAU;EACvC7B,MAAA,CAAO,MAAOyB,MAAA,CAAOa,IAAA,CAAyCN,QAAQ,EAAEO,OAAA,CACtE,+BACF;AACF,CAAC","ignoreList":[]}
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createSchema, string, table } from "@rocicorp/zero";
3
+ import { useZero } from "@rocicorp/zero/react";
4
+ import { renderToString } from "react-dom/server";
5
+ import { expect, test, vi } from "vitest";
6
+ import { createZeroClient } from "./createZeroClient.native.js";
7
+ import { IS_SERVER_RUNTIME } from "./helpers/platform.native.js";
8
+ function _class_call_check(instance, Constructor) {
9
+ if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
10
+ }
11
+ var fakeZero = vi.hoisted(function () {
12
+ var instances = [];
13
+ var FakeZero = function FakeZero2() {
14
+ "use strict";
15
+
16
+ _class_call_check(this, FakeZero2);
17
+ instances.push(this);
18
+ };
19
+ return {
20
+ FakeZero,
21
+ instances
22
+ };
23
+ });
24
+ vi.mock("@rocicorp/zero", async function (importOriginal) {
25
+ var actual = await importOriginal();
26
+ return {
27
+ ...actual,
28
+ Zero: fakeZero.FakeZero
29
+ };
30
+ });
31
+ if (typeof window !== "undefined") {
32
+ throw new Error("provideZero.ssr.test.tsx must run with @vitest-environment node");
33
+ }
34
+ var todoTable = table("todo").columns({
35
+ id: string(),
36
+ title: string()
37
+ }).primaryKey("id");
38
+ var schema = createSchema({
39
+ tables: [todoTable]
40
+ });
41
+ var client = createZeroClient({
42
+ schema,
43
+ models: {},
44
+ groupedQueries: {},
45
+ instanceName: "ssr-eager-test"
46
+ });
47
+ test("the server runtime is what this file exercises", function () {
48
+ expect(IS_SERVER_RUNTIME).toBe(true);
49
+ });
50
+ test("rendering ProvideZero on the server constructs no client", function () {
51
+ var contextClientID;
52
+ var Probe = function Probe2() {
53
+ contextClientID = useZero().clientID;
54
+ return null;
55
+ };
56
+ renderToString(/* @__PURE__ */_jsx(client.ProvideZero, {
57
+ cacheURL: "http://127.0.0.1:7788/zero",
58
+ userID: "ssr",
59
+ children: /* @__PURE__ */_jsx(Probe, {})
60
+ }));
61
+ expect(fakeZero.instances.length).toBe(0);
62
+ expect(contextClientID).toBe("disabled");
63
+ expect(function () {
64
+ return client.zero.clientID;
65
+ }).toThrow(/Zero instance not initialized/);
66
+ });
67
+ //# sourceMappingURL=provideZero.ssr.test.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["jsx","_jsx","createSchema","string","table","useZero","renderToString","expect","test","vi","createZeroClient","IS_SERVER_RUNTIME","_class_call_check","instance","Constructor","TypeError","fakeZero","hoisted","instances","FakeZero","FakeZero2","push","mock","importOriginal","actual","Zero","window","Error","todoTable","columns","id","title","primaryKey","schema","tables","client","models","groupedQueries","instanceName","toBe"],"sources":["../../src/provideZero.ssr.test.tsx"],"sourcesContent":[null],"mappings":"AAOA,SAASA,GAAA,IAAAC,IAAA,QAAc,mBAAqB;AAC5C,SAASC,YAAA,EAAAC,MAAe,EAAAC,KAAA;AACxB,SAASC,OAAA,8BAAsB;AAC/B,SAASC,cAAc,0BAAU;AAiBjC,SAASC,MAAA,EAAAC,IAAA,EAAAC,EAAA,QAAwB;AACjC,SAASC,gBAAA,sCAAyB;AA+B5B,SAAAC,iBAAA;AA/CN,SAAMC,iBAAcA,CAAAC,QAAc,EAAAC,WAAA;EAChC,MAAMD,QAAA,YAAwBC,WAAA,aAAAC,SAAA;AAAA;AACf,IACbC,QAAA,GAAAP,EAAA,CAAcQ,OAAA;EACZ,IAAAC,SAAA,GAAU;EAAS,IACrBC,QAAA,YAAAC,UAAA;IACF;;IACAR,iBAAmB,OAAAQ,SAAU;IAC9BF,SAAA,CAAAG,IAAA;EAED,CAAG;EACD,OAAM;IACNF,QAAS;IACVD;EAKD;AACE;AACFT,EAAA,CAAAa,IAAA,mCAAAC,cAAA;EAEA,IAAMC,MAAA,SAAYD,cACf;EAEH,OAAM;IAEN,GAAMC,MAAA;IACJC,IAAA,EAAAT,QAAA,CAAAG;EACA;AAAS,EACT;AAAiB,IACjB,OAAAO,MAAc;EACf,UAAAC,KAAA;AAED;AACE,IAAAC,SAAO,GAAAxB,KAAA,OAAmB,EAAAyB,OAAS;EACpCC,EAAA,EAAA3B,MAAA;EAED4B,KAAK,EAAA5B,MAAA;AACH,GAAA6B,UAAI;AACJ,IAAAC,MAAM,GAAA/B,YAAc;EAClBgC,MAAA,GACAN,SAAO;AAGT;AAAA,IACEO,MAAA,GAAAzB,gBAAC;EAGHuB,MAAA;EAEAG,MAAA,EAAO;EACPC,cAAO;EACPC,YAAO,EAAO;AAA0D;AACtE9B,IACF;EACDD,MAAA,CAAAI,iBAAA,EAAA4B,IAAA","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "on-zero",
3
- "version": "0.14.3",
3
+ "version": "0.14.4",
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.14.3",
108
+ "orez-lite": "0.14.4",
109
109
  "valibot": "^1.1.0"
110
110
  },
111
111
  "peerDependencies": {
@@ -279,7 +279,10 @@ export function createUseQueryDirect<Schema extends ZeroSchema>({
279
279
  const disableMode = useContext(DisabledContext)
280
280
  const [fn, paramsOrOptions, optionsArg] = args
281
281
 
282
- const version = useEmitterValue(zeroVersion)
282
+ // subscribe so a swap re-renders this hook even when it has no provider
283
+ // above it re-rendering the subtree (connectHeadless publishes with no
284
+ // react tree at all). the instance identity below decides what changes.
285
+ useEmitterValue(zeroVersion)
283
286
  const { params, options } = parseUseQueryArgs(paramsOrOptions, optionsArg)
284
287
 
285
288
  let enabled = true
@@ -306,26 +309,28 @@ export function createUseQueryDirect<Schema extends ZeroSchema>({
306
309
  const emptyForQuery = useMemo(() => emptyResponseFor(queryRequest), [queryRequest])
307
310
  const lastRef = useRef<any>(emptyForQuery)
308
311
 
312
+ // the published instance is the memo's dependency, so a swap re-keys the
313
+ // view and nothing else does. keying on `version` instead left the memo
314
+ // holding a null view through every render between the emitter's bump and
315
+ // the instance actually appearing, and made a redundant bump tear down and
316
+ // rebuild a view that was already pointed at the right client.
317
+ const zeroInstance = getZero()
309
318
  const view = useMemo((): DirectView | null => {
310
- const zero = getZero()
311
- if (!zero) return null
312
- // when ProvideZero renders with disable=true (or pre-instance), the
313
- // ZeroContext.value is the inert stub which has no `.materialize` —
314
- // calling it throws "this[#zero].materialize is not a function". detect
315
- // the stub and short-circuit to the disabled snapshot via enabled=false
316
- // (mirroring the wrapper-useQuery path at createUseQuery.tsx).
317
- // DisabledContext is not a reliable signal here: it flips 'empty'
318
- // false within one render once the active instance is created, which
319
- // would re-key the useMemo and re-materialize the view — that breaks
320
- // the "subscribers share one materialized view" invariant.
319
+ if (!zeroInstance) return null
320
+ // when ProvideZero renders with disable=true, the ZeroContext.value is
321
+ // the inert stub which has no `.materialize` — calling it throws
322
+ // "this[#zero].materialize is not a function". detect the stub and
323
+ // short-circuit to the disabled snapshot via enabled=false (mirroring
324
+ // the wrapper-useQuery path at createUseQuery.tsx). DisabledContext is
325
+ // not a reliable signal here: it flips 'empty' → false as the provider
326
+ // enables, which would re-key the useMemo and re-materialize the view
327
+ // that breaks the "subscribers share one materialized view" invariant.
321
328
  const effectiveEnabled =
322
- typeof (zero as { materialize?: unknown }).materialize === 'function'
329
+ typeof (zeroInstance as { materialize?: unknown }).materialize === 'function'
323
330
  ? enabled
324
331
  : false
325
- return directViewStore.getView(zero, queryRequest, effectiveEnabled, ttl)
326
- // version re-materializes on a new zero
327
- // eslint-disable-next-line react-hooks/exhaustive-deps
328
- }, [queryRequest, enabled, ttl, version])
332
+ return directViewStore.getView(zeroInstance, queryRequest, effectiveEnabled, ttl)
333
+ }, [queryRequest, enabled, ttl, zeroInstance])
329
334
 
330
335
  const getEmpty = () => emptyForQuery as DirectSnapshot
331
336
  const out = useSyncExternalStore(