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.
- package/README.md +7 -0
- package/dist/cjs/createUseQueryDirect.cjs +6 -6
- package/dist/cjs/createUseQueryDirect.native.js +6 -9
- package/dist/cjs/createUseQueryDirect.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +28 -30
- package/dist/cjs/createZeroClient.native.js +49 -35
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/provideZero.eagerInstance.test.cjs +196 -0
- package/dist/cjs/provideZero.eagerInstance.test.native.js +229 -0
- package/dist/cjs/provideZero.eagerInstance.test.native.js.map +1 -0
- package/dist/cjs/provideZero.ssr.test.cjs +60 -0
- package/dist/cjs/provideZero.ssr.test.native.js +69 -0
- package/dist/cjs/provideZero.ssr.test.native.js.map +1 -0
- package/dist/esm/createUseQueryDirect.mjs +6 -6
- package/dist/esm/createUseQueryDirect.mjs.map +1 -1
- package/dist/esm/createUseQueryDirect.native.js +6 -9
- package/dist/esm/createUseQueryDirect.native.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +28 -30
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +49 -35
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/provideZero.eagerInstance.test.mjs +197 -0
- package/dist/esm/provideZero.eagerInstance.test.mjs.map +1 -0
- package/dist/esm/provideZero.eagerInstance.test.native.js +227 -0
- package/dist/esm/provideZero.eagerInstance.test.native.js.map +1 -0
- package/dist/esm/provideZero.ssr.test.mjs +61 -0
- package/dist/esm/provideZero.ssr.test.mjs.map +1 -0
- package/dist/esm/provideZero.ssr.test.native.js +67 -0
- package/dist/esm/provideZero.ssr.test.native.js.map +1 -0
- package/package.json +2 -2
- package/src/createUseQueryDirect.tsx +22 -17
- package/src/createZeroClient.tsx +86 -75
- package/src/multiInstanceNested.test.tsx +2 -2
- package/src/provideZero.eagerInstance.test.tsx +235 -0
- package/src/provideZero.ssr.test.tsx +69 -0
- package/types/createUseQueryDirect.d.ts.map +1 -1
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/provideZero.eagerInstance.test.d.ts +5 -0
- package/types/provideZero.eagerInstance.test.d.ts.map +1 -0
- package/types/provideZero.ssr.test.d.ts +2 -0
- 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
|
+
"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.
|
|
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
|
-
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
//
|
|
315
|
-
// the
|
|
316
|
-
//
|
|
317
|
-
//
|
|
318
|
-
//
|
|
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 (
|
|
329
|
+
typeof (zeroInstance as { materialize?: unknown }).materialize === 'function'
|
|
323
330
|
? enabled
|
|
324
331
|
: false
|
|
325
|
-
return directViewStore.getView(
|
|
326
|
-
|
|
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(
|