on-zero 0.4.25 → 0.4.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/createUseQuery.cjs +28 -16
- package/dist/cjs/createUseQuery.native.js +42 -30
- package/dist/cjs/createUseQuery.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +13 -1
- package/dist/cjs/createZeroClient.native.js +13 -1
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/httpPull/auth.test.cjs +197 -0
- package/dist/cjs/httpPull/auth.test.native.js +279 -0
- package/dist/cjs/httpPull/auth.test.native.js.map +1 -0
- package/dist/cjs/httpPull/churn.test.cjs +132 -0
- package/dist/cjs/httpPull/churn.test.native.js +155 -0
- package/dist/cjs/httpPull/churn.test.native.js.map +1 -0
- package/dist/cjs/httpPull/fixtureSchema.cjs +76 -0
- package/dist/cjs/httpPull/fixtureSchema.native.js +82 -0
- package/dist/cjs/httpPull/fixtureSchema.native.js.map +1 -0
- package/dist/cjs/httpPull/fixtureServer.cjs +340 -0
- package/dist/cjs/httpPull/fixtureServer.native.js +534 -0
- package/dist/cjs/httpPull/fixtureServer.native.js.map +1 -0
- package/dist/cjs/httpPull/integration.test.cjs +53 -0
- package/dist/cjs/httpPull/integration.test.native.js +60 -0
- package/dist/cjs/httpPull/integration.test.native.js.map +1 -0
- package/dist/cjs/httpPull/rebase.test.cjs +360 -0
- package/dist/cjs/httpPull/rebase.test.native.js +420 -0
- package/dist/cjs/httpPull/rebase.test.native.js.map +1 -0
- package/dist/cjs/httpPull/relations.test.cjs +107 -0
- package/dist/cjs/httpPull/relations.test.native.js +119 -0
- package/dist/cjs/httpPull/relations.test.native.js.map +1 -0
- package/dist/cjs/httpPull/testHarness.cjs +100 -0
- package/dist/cjs/httpPull/testHarness.native.js +112 -0
- package/dist/cjs/httpPull/testHarness.native.js.map +1 -0
- package/dist/cjs/httpPull/transport.test.cjs +568 -0
- package/dist/cjs/httpPull/transport.test.native.js +655 -0
- package/dist/cjs/httpPull/transport.test.native.js.map +1 -0
- package/dist/cjs/httpPullTransport.cjs +432 -0
- package/dist/cjs/httpPullTransport.native.js +695 -0
- package/dist/cjs/httpPullTransport.native.js.map +1 -0
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/index.native.js +1 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/multiInstanceNested.test.cjs +26 -0
- package/dist/cjs/multiInstanceNested.test.native.js +34 -0
- package/dist/cjs/multiInstanceNested.test.native.js.map +1 -1
- package/dist/esm/createUseQuery.mjs +28 -16
- package/dist/esm/createUseQuery.mjs.map +1 -1
- package/dist/esm/createUseQuery.native.js +42 -30
- package/dist/esm/createUseQuery.native.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +13 -1
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +13 -1
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/httpPull/auth.test.mjs +198 -0
- package/dist/esm/httpPull/auth.test.mjs.map +1 -0
- package/dist/esm/httpPull/auth.test.native.js +277 -0
- package/dist/esm/httpPull/auth.test.native.js.map +1 -0
- package/dist/esm/httpPull/churn.test.mjs +133 -0
- package/dist/esm/httpPull/churn.test.mjs.map +1 -0
- package/dist/esm/httpPull/churn.test.native.js +153 -0
- package/dist/esm/httpPull/churn.test.native.js.map +1 -0
- package/dist/esm/httpPull/fixtureSchema.mjs +50 -0
- package/dist/esm/httpPull/fixtureSchema.mjs.map +1 -0
- package/dist/esm/httpPull/fixtureSchema.native.js +53 -0
- package/dist/esm/httpPull/fixtureSchema.native.js.map +1 -0
- package/dist/esm/httpPull/fixtureServer.mjs +315 -0
- package/dist/esm/httpPull/fixtureServer.mjs.map +1 -0
- package/dist/esm/httpPull/fixtureServer.native.js +506 -0
- package/dist/esm/httpPull/fixtureServer.native.js.map +1 -0
- package/dist/esm/httpPull/integration.test.mjs +54 -0
- package/dist/esm/httpPull/integration.test.mjs.map +1 -0
- package/dist/esm/httpPull/integration.test.native.js +58 -0
- package/dist/esm/httpPull/integration.test.native.js.map +1 -0
- package/dist/esm/httpPull/rebase.test.mjs +361 -0
- package/dist/esm/httpPull/rebase.test.mjs.map +1 -0
- package/dist/esm/httpPull/rebase.test.native.js +418 -0
- package/dist/esm/httpPull/rebase.test.native.js.map +1 -0
- package/dist/esm/httpPull/relations.test.mjs +108 -0
- package/dist/esm/httpPull/relations.test.mjs.map +1 -0
- package/dist/esm/httpPull/relations.test.native.js +117 -0
- package/dist/esm/httpPull/relations.test.native.js.map +1 -0
- package/dist/esm/httpPull/testHarness.mjs +72 -0
- package/dist/esm/httpPull/testHarness.mjs.map +1 -0
- package/dist/esm/httpPull/testHarness.native.js +81 -0
- package/dist/esm/httpPull/testHarness.native.js.map +1 -0
- package/dist/esm/httpPull/transport.test.mjs +569 -0
- package/dist/esm/httpPull/transport.test.mjs.map +1 -0
- package/dist/esm/httpPull/transport.test.native.js +653 -0
- package/dist/esm/httpPull/transport.test.native.js.map +1 -0
- package/dist/esm/httpPullTransport.mjs +406 -0
- package/dist/esm/httpPullTransport.mjs.map +1 -0
- package/dist/esm/httpPullTransport.native.js +666 -0
- package/dist/esm/httpPullTransport.native.js.map +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +1 -0
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/multiInstanceNested.test.mjs +27 -1
- package/dist/esm/multiInstanceNested.test.mjs.map +1 -1
- package/dist/esm/multiInstanceNested.test.native.js +35 -1
- package/dist/esm/multiInstanceNested.test.native.js.map +1 -1
- package/package.json +2 -2
- package/src/createUseQuery.tsx +40 -22
- package/src/createZeroClient.tsx +19 -0
- package/src/httpPull/auth.test.ts +208 -0
- package/src/httpPull/churn.test.ts +147 -0
- package/src/httpPull/fixtureSchema.ts +82 -0
- package/src/httpPull/fixtureServer.ts +391 -0
- package/src/httpPull/integration.test.ts +57 -0
- package/src/httpPull/rebase.test.ts +368 -0
- package/src/httpPull/relations.test.ts +135 -0
- package/src/httpPull/testHarness.ts +95 -0
- package/src/httpPull/transport.test.ts +577 -0
- package/src/httpPullTransport.ts +559 -0
- package/src/index.ts +1 -0
- package/src/multiInstanceNested.test.tsx +25 -1
- package/types/createUseQuery.d.ts.map +1 -1
- package/types/createZeroClient.d.ts +3 -1
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/httpPull/auth.test.d.ts +2 -0
- package/types/httpPull/auth.test.d.ts.map +1 -0
- package/types/httpPull/churn.test.d.ts +2 -0
- package/types/httpPull/churn.test.d.ts.map +1 -0
- package/types/httpPull/fixtureSchema.d.ts +111 -0
- package/types/httpPull/fixtureSchema.d.ts.map +1 -0
- package/types/httpPull/fixtureServer.d.ts +14 -0
- package/types/httpPull/fixtureServer.d.ts.map +1 -0
- package/types/httpPull/integration.test.d.ts +2 -0
- package/types/httpPull/integration.test.d.ts.map +1 -0
- package/types/httpPull/rebase.test.d.ts +2 -0
- package/types/httpPull/rebase.test.d.ts.map +1 -0
- package/types/httpPull/relations.test.d.ts +2 -0
- package/types/httpPull/relations.test.d.ts.map +1 -0
- package/types/httpPull/testHarness.d.ts +32 -0
- package/types/httpPull/testHarness.d.ts.map +1 -0
- package/types/httpPull/transport.test.d.ts +2 -0
- package/types/httpPull/transport.test.d.ts.map +1 -0
- package/types/httpPullTransport.d.ts +13 -0
- package/types/httpPullTransport.d.ts.map +1 -0
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { ensureAuth, getAuth } from "./helpers/getAuth.mjs";
|
|
|
9
9
|
import { setAuthData, setEnvironment } from "./state.mjs";
|
|
10
10
|
export * from "./combineZeroClients.mjs";
|
|
11
11
|
export * from "./createZeroClient.mjs";
|
|
12
|
+
export * from "./httpPullTransport.mjs";
|
|
12
13
|
export * from "./createUseQuery.mjs";
|
|
13
14
|
export * from "./resolveQuery.mjs";
|
|
14
15
|
export * from "./run.mjs";
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ensureAuth","getAuth","setAuthData","setEnvironment","setRunner","defineQuery","defineQueries","clearZeroClientData","showZeroClientErrorOnce","resetShownZeroClientError"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASA,UAAA,EAAYC,OAAA,QAAe;AACpC,SAASC,WAAA,EAAaC,cAAA,QAAsB;AAE5C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,SAAA,QAAkC;AAC3C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,WAAA,EAAaC,aAAA,QAAqB;AAQ3C,SACEC,mBAAA,QAEK;AACP,SACEC,uBAAA,EACAC,yBAAA,QAGK","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["ensureAuth","getAuth","setAuthData","setEnvironment","setRunner","defineQuery","defineQueries","clearZeroClientData","showZeroClientErrorOnce","resetShownZeroClientError"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASA,UAAA,EAAYC,OAAA,QAAe;AACpC,SAASC,WAAA,EAAaC,cAAA,QAAsB;AAE5C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,SAAA,QAAkC;AAC3C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,WAAA,EAAaC,aAAA,QAAqB;AAQ3C,SACEC,mBAAA,QAEK;AACP,SACEC,uBAAA,EACAC,yBAAA,QAGK","ignoreList":[]}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import { ensureAuth, getAuth } from "./helpers/getAuth.mjs";
|
|
|
9
9
|
import { setAuthData, setEnvironment } from "./state.mjs";
|
|
10
10
|
export * from "./combineZeroClients.mjs";
|
|
11
11
|
export * from "./createZeroClient.mjs";
|
|
12
|
+
export * from "./httpPullTransport.mjs";
|
|
12
13
|
export * from "./createUseQuery.mjs";
|
|
13
14
|
export * from "./resolveQuery.mjs";
|
|
14
15
|
export * from "./run.mjs";
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ensureAuth","getAuth","setAuthData","setEnvironment","setRunner","defineQuery","defineQueries","clearZeroClientData","showZeroClientErrorOnce","resetShownZeroClientError"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASA,UAAA,EAAYC,OAAA,QAAe;AACpC,SAASC,WAAA,EAAaC,cAAA,QAAsB;AAE5C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,SAAA,QAAkC;AAC3C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,WAAA,EAAaC,aAAA,QAAqB;AAQ3C,SACEC,mBAAA,QAEK;AACP,SACEC,uBAAA,EACAC,yBAAA,QAGK","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["ensureAuth","getAuth","setAuthData","setEnvironment","setRunner","defineQuery","defineQueries","clearZeroClientData","showZeroClientErrorOnce","resetShownZeroClientError"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASA,UAAA,EAAYC,OAAA,QAAe;AACpC,SAASC,WAAA,EAAaC,cAAA,QAAsB;AAE5C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,SAAA,QAAkC;AAC3C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,WAAA,EAAaC,aAAA,QAAqB;AAQ3C,SACEC,mBAAA,QAEK;AACP,SACEC,uBAAA,EACAC,yBAAA,QAGK","ignoreList":[]}
|
package/dist/esm/index.native.js
CHANGED
|
@@ -9,6 +9,7 @@ import { ensureAuth, getAuth } from "./helpers/getAuth.native.js";
|
|
|
9
9
|
import { setAuthData, setEnvironment } from "./state.native.js";
|
|
10
10
|
export * from "./combineZeroClients.native.js";
|
|
11
11
|
export * from "./createZeroClient.native.js";
|
|
12
|
+
export * from "./httpPullTransport.native.js";
|
|
12
13
|
export * from "./createUseQuery.native.js";
|
|
13
14
|
export * from "./resolveQuery.native.js";
|
|
14
15
|
export * from "./run.native.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ensureAuth","getAuth","setAuthData","setEnvironment","setRunner","defineQuery","defineQueries","clearZeroClientData","showZeroClientErrorOnce","resetShownZeroClientError"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASA,UAAA,EAAYC,OAAA,QAAe;AACpC,SAASC,WAAA,EAAaC,cAAA,QAAsB;AAE5C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,SAAA,QAAkC;AAC3C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,WAAA,EAAaC,aAAA,QAAqB;AAQ3C,SAAAC,mBAAA;AAAA,SACEC,uBAAA,EAAAC,yBAAA;AAAA,SAGFF,mBAAA,EACED,aAAA,EACAD,WAAA,EAAAL,UAGK,E","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["ensureAuth","getAuth","setAuthData","setEnvironment","setRunner","defineQuery","defineQueries","clearZeroClientData","showZeroClientErrorOnce","resetShownZeroClientError"],"sources":["../../src/index.ts"],"sourcesContent":[null],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASA,UAAA,EAAYC,OAAA,QAAe;AACpC,SAASC,WAAA,EAAaC,cAAA,QAAsB;AAE5C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,SAAA,QAAkC;AAC3C,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,SAASC,WAAA,EAAaC,aAAA,QAAqB;AAQ3C,SAAAC,mBAAA;AAAA,SACEC,uBAAA,EAAAC,yBAAA;AAAA,SAGFF,mBAAA,EACED,aAAA,EACAD,WAAA,EAAAL,UAGK,E","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createSchema, string, table } from "@rocicorp/zero";
|
|
2
|
-
import { act } from "react";
|
|
2
|
+
import { act, StrictMode } from "react";
|
|
3
3
|
import { createRoot } from "react-dom/client";
|
|
4
4
|
import { afterEach, beforeEach, expect, test } from "vitest";
|
|
5
5
|
import { combineZeroClients } from "./combineZeroClients.mjs";
|
|
@@ -175,6 +175,32 @@ test("inner provider unmount/remount does not break outer-instance subscriptions
|
|
|
175
175
|
});
|
|
176
176
|
await waitFor(() => probe.data?.name === "v3", "v3 visible after inner remount");
|
|
177
177
|
});
|
|
178
|
+
test("StrictMode: direct views survive the effect double-invoke", async () => {
|
|
179
|
+
await render(/* @__PURE__ */jsx(StrictMode, {
|
|
180
|
+
children: /* @__PURE__ */jsx(control.ProvideZero, {
|
|
181
|
+
server: null,
|
|
182
|
+
userID: "t4-ctl",
|
|
183
|
+
children: /* @__PURE__ */jsx(project.ProvideZero, {
|
|
184
|
+
server: null,
|
|
185
|
+
userID: "t4-prj",
|
|
186
|
+
children: /* @__PURE__ */jsx(ControlUserProbe, {
|
|
187
|
+
id: "u4"
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
})
|
|
191
|
+
}));
|
|
192
|
+
await waitFor(() => probe.renders > 0, "probe mount");
|
|
193
|
+
await seedControl({
|
|
194
|
+
id: "u4",
|
|
195
|
+
name: "strict-v1"
|
|
196
|
+
});
|
|
197
|
+
await waitFor(() => probe.data?.name === "strict-v1", "update visible under StrictMode");
|
|
198
|
+
await seedControl({
|
|
199
|
+
id: "u4",
|
|
200
|
+
name: "strict-v2"
|
|
201
|
+
});
|
|
202
|
+
await waitFor(() => probe.data?.name === "strict-v2", "second update still live");
|
|
203
|
+
});
|
|
178
204
|
test("direct-path views re-materialize when the owning instance rotates", async () => {
|
|
179
205
|
const App = ({
|
|
180
206
|
userID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createSchema","string","table","act","createRoot","afterEach","beforeEach","expect","test","combineZeroClients","createZeroClient","zql","jsx","globalThis","IS_REACT_ACT_ENVIRONMENT","userTable","columns","id","name","primaryKey","taskTable","title","schema","tables","controlModels","user","mutate","seed","ctx","row","tx","upsert","ctlUserById","args","where","one","control","models","groupedQueries","ctlUser","byId","instanceName","projectModels","prjSeed","seedUser","prjTaskById","task","project","prjTask","combined","root","container","resetProbe","document","createElement","body","appendChild","unmount","remove","render","ui","waitFor","condition","what","i","Promise","resolve","setTimeout","Error","probe","data","renders","ControlUserProbe","useQuery","seedControl","zero","client","seedProject","ProvideZero","server","userID","children","toBe","App","showInner"],"sources":["../../src/multiInstanceNested.test.tsx"],"sourcesContent":[null],"mappings":"AAOA,SAASA,YAAA,EAAcC,MAAA,EAAQC,KAAA,QAAa;AAC5C,SAASC,GAAA,
|
|
1
|
+
{"version":3,"names":["createSchema","string","table","act","StrictMode","createRoot","afterEach","beforeEach","expect","test","combineZeroClients","createZeroClient","zql","jsx","globalThis","IS_REACT_ACT_ENVIRONMENT","userTable","columns","id","name","primaryKey","taskTable","title","schema","tables","controlModels","user","mutate","seed","ctx","row","tx","upsert","ctlUserById","args","where","one","control","models","groupedQueries","ctlUser","byId","instanceName","projectModels","prjSeed","seedUser","prjTaskById","task","project","prjTask","combined","root","container","resetProbe","document","createElement","body","appendChild","unmount","remove","render","ui","waitFor","condition","what","i","Promise","resolve","setTimeout","Error","probe","data","renders","ControlUserProbe","useQuery","seedControl","zero","client","seedProject","ProvideZero","server","userID","children","toBe","App","showInner"],"sources":["../../src/multiInstanceNested.test.tsx"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createSchema, string, table } from "@rocicorp/zero";
|
|
3
|
-
import { act } from "react";
|
|
3
|
+
import { act, StrictMode } from "react";
|
|
4
4
|
import { createRoot } from "react-dom/client";
|
|
5
5
|
import { afterEach, beforeEach, expect, test } from "vitest";
|
|
6
6
|
import { combineZeroClients } from "./combineZeroClients.native.js";
|
|
@@ -207,6 +207,40 @@ test("inner provider unmount/remount does not break outer-instance subscriptions
|
|
|
207
207
|
return ((_probe_data = probe.data) === null || _probe_data === void 0 ? void 0 : _probe_data.name) === "v3";
|
|
208
208
|
}, "v3 visible after inner remount");
|
|
209
209
|
});
|
|
210
|
+
test("StrictMode: direct views survive the effect double-invoke", async function () {
|
|
211
|
+
await render(/* @__PURE__ */_jsx(StrictMode, {
|
|
212
|
+
children: /* @__PURE__ */_jsx(control.ProvideZero, {
|
|
213
|
+
server: null,
|
|
214
|
+
userID: "t4-ctl",
|
|
215
|
+
children: /* @__PURE__ */_jsx(project.ProvideZero, {
|
|
216
|
+
server: null,
|
|
217
|
+
userID: "t4-prj",
|
|
218
|
+
children: /* @__PURE__ */_jsx(ControlUserProbe, {
|
|
219
|
+
id: "u4"
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
}));
|
|
224
|
+
await waitFor(function () {
|
|
225
|
+
return probe.renders > 0;
|
|
226
|
+
}, "probe mount");
|
|
227
|
+
await seedControl({
|
|
228
|
+
id: "u4",
|
|
229
|
+
name: "strict-v1"
|
|
230
|
+
});
|
|
231
|
+
await waitFor(function () {
|
|
232
|
+
var _probe_data;
|
|
233
|
+
return ((_probe_data = probe.data) === null || _probe_data === void 0 ? void 0 : _probe_data.name) === "strict-v1";
|
|
234
|
+
}, "update visible under StrictMode");
|
|
235
|
+
await seedControl({
|
|
236
|
+
id: "u4",
|
|
237
|
+
name: "strict-v2"
|
|
238
|
+
});
|
|
239
|
+
await waitFor(function () {
|
|
240
|
+
var _probe_data;
|
|
241
|
+
return ((_probe_data = probe.data) === null || _probe_data === void 0 ? void 0 : _probe_data.name) === "strict-v2";
|
|
242
|
+
}, "second update still live");
|
|
243
|
+
});
|
|
210
244
|
test("direct-path views re-materialize when the owning instance rotates", async function () {
|
|
211
245
|
var App = function (param) {
|
|
212
246
|
var {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["jsx","_jsx","createSchema","string","table","act","createRoot","afterEach","beforeEach","expect","test","combineZeroClients","createZeroClient","zql","globalThis","IS_REACT_ACT_ENVIRONMENT","userTable","columns","id","name","primaryKey","taskTable","title","schema","tables","controlModels","user","mutate","seed","ctx","row","tx","upsert","ctlUserById","args","where","one","control","models","groupedQueries","ctlUser","byId","instanceName","projectModels","prjSeed","seedUser","prjTaskById","task","project","prjTask","combined","root","container","resetProbe","document","createElement","body","appendChild","unmount","remove","render","ui","waitFor","condition","what","i","Promise","resolve","setTimeout","Error","probe","data","renders","ControlUserProbe","param","useQuery","seedControl","zero","client","seedProject"],"sources":["../../src/multiInstanceNested.test.tsx"],"sourcesContent":[null],"mappings":"AAOA,SAASA,GAAA,IAAAC,IAAA,QAAc,mBAAqB;AAC5C,SAASC,
|
|
1
|
+
{"version":3,"names":["jsx","_jsx","createSchema","string","table","act","StrictMode","createRoot","afterEach","beforeEach","expect","test","combineZeroClients","createZeroClient","zql","globalThis","IS_REACT_ACT_ENVIRONMENT","userTable","columns","id","name","primaryKey","taskTable","title","schema","tables","controlModels","user","mutate","seed","ctx","row","tx","upsert","ctlUserById","args","where","one","control","models","groupedQueries","ctlUser","byId","instanceName","projectModels","prjSeed","seedUser","prjTaskById","task","project","prjTask","combined","root","container","resetProbe","document","createElement","body","appendChild","unmount","remove","render","ui","waitFor","condition","what","i","Promise","resolve","setTimeout","Error","probe","data","renders","ControlUserProbe","param","useQuery","seedControl","zero","client","seedProject","_probe_data","ProvideZero","server","userID","children"],"sources":["../../src/multiInstanceNested.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.4.
|
|
3
|
+
"version": "0.4.27",
|
|
4
4
|
"description": "A typed layer over @rocicorp/zero with queries, mutations, and permissions",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"source": "src/index.ts",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@take-out/helpers": "0.4.
|
|
80
|
+
"@take-out/helpers": "0.4.27",
|
|
81
81
|
"chokidar": "^4.0.3",
|
|
82
82
|
"citty": "^0.1.6",
|
|
83
83
|
"valibot": "^1.1.0"
|
package/src/createUseQuery.tsx
CHANGED
|
@@ -151,45 +151,64 @@ type MaterializableZero = {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
function createDirectView(
|
|
154
|
-
|
|
154
|
+
getZero: () => MaterializableZero | null,
|
|
155
155
|
queryRequest: unknown,
|
|
156
156
|
ttl: UseQueryOptions['ttl'],
|
|
157
157
|
): DirectView {
|
|
158
158
|
let snapshot: readonly [unknown, { type: string }] = DISABLED_SNAPSHOT
|
|
159
159
|
const listeners = new Set<() => void>()
|
|
160
|
+
let view: { destroy(): void } | null = null
|
|
161
|
+
|
|
162
|
+
const materialize = () => {
|
|
163
|
+
const zero = getZero()
|
|
164
|
+
if (!zero) return
|
|
165
|
+
// zero.materialize accepts a QueryRequest (it applies the instance context
|
|
166
|
+
// itself) — the same public api the upstream ViewWrapper uses
|
|
167
|
+
const next = zero.materialize(queryRequest, ttl === undefined ? undefined : { ttl })
|
|
168
|
+
view = next
|
|
169
|
+
|
|
170
|
+
// addListener fires immediately with current data, so the snapshot is
|
|
171
|
+
// populated before react's first getSnapshot. data must be cloned: the
|
|
172
|
+
// underlying view mutates it in place, and useSyncExternalStore requires
|
|
173
|
+
// immutable snapshots to detect changes.
|
|
174
|
+
next.addListener((data, resultType) => {
|
|
175
|
+
snapshot = [
|
|
176
|
+
data === undefined ? undefined : structuredClone(data),
|
|
177
|
+
{ type: resultType },
|
|
178
|
+
]
|
|
179
|
+
for (const listener of listeners) {
|
|
180
|
+
listener()
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
}
|
|
160
184
|
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
const view = zero.materialize(queryRequest, ttl === undefined ? undefined : { ttl })
|
|
164
|
-
|
|
165
|
-
// addListener fires immediately with current data, so the snapshot is
|
|
166
|
-
// populated before react's first getSnapshot. data must be cloned: the
|
|
167
|
-
// underlying view mutates it in place, and useSyncExternalStore requires
|
|
168
|
-
// immutable snapshots to detect changes.
|
|
169
|
-
view.addListener((data, resultType) => {
|
|
170
|
-
snapshot = [
|
|
171
|
-
data === undefined ? undefined : structuredClone(data),
|
|
172
|
-
{ type: resultType },
|
|
173
|
-
]
|
|
174
|
-
for (const listener of listeners) {
|
|
175
|
-
listener()
|
|
176
|
-
}
|
|
177
|
-
})
|
|
185
|
+
// eager: snapshot is warm before react's first getSnapshot
|
|
186
|
+
materialize()
|
|
178
187
|
|
|
179
188
|
return {
|
|
180
189
|
subscribe: (notify) => {
|
|
181
190
|
listeners.add(notify)
|
|
191
|
+
// react runs effect cleanup + re-setup with unchanged deps under
|
|
192
|
+
// StrictMode double-invoke and suspense hide/reveal — the cleanup
|
|
193
|
+
// destroyed the view while this memoized store survived, so the
|
|
194
|
+
// resubscribe must re-materialize or the snapshot freezes forever
|
|
195
|
+
if (view === null) {
|
|
196
|
+
materialize()
|
|
197
|
+
}
|
|
182
198
|
return () => listeners.delete(notify)
|
|
183
199
|
},
|
|
184
200
|
getSnapshot: () => snapshot,
|
|
185
201
|
destroy: () => {
|
|
202
|
+
const current = view
|
|
203
|
+
view = null
|
|
204
|
+
if (!current) return
|
|
186
205
|
// identity rotation closes the owning zero before react runs this
|
|
187
206
|
// cleanup (the version bump that swaps the view is post-commit) — the
|
|
188
207
|
// closed instance already removed the view's ttl connection record, so
|
|
189
208
|
// zero's destroy asserts ("Connection not found"). destroy-after-close
|
|
190
209
|
// is semantically a no-op; swallow it instead of killing the route.
|
|
191
210
|
try {
|
|
192
|
-
|
|
211
|
+
current.destroy()
|
|
193
212
|
} catch {
|
|
194
213
|
// instance closed first — nothing left to tear down
|
|
195
214
|
}
|
|
@@ -233,10 +252,9 @@ export function createUseQueryDirect<Schema extends ZeroSchema>({
|
|
|
233
252
|
const paramsKey = params === undefined ? '' : JSON.stringify(params)
|
|
234
253
|
|
|
235
254
|
const view = useMemo((): DirectView | null => {
|
|
236
|
-
|
|
237
|
-
if (!enabled || !zero) return null
|
|
255
|
+
if (!enabled || !getZero()) return null
|
|
238
256
|
const queryRequest = resolveQuery({ customQueries, fn, params })
|
|
239
|
-
return createDirectView(
|
|
257
|
+
return createDirectView(getZero, queryRequest, ttl)
|
|
240
258
|
// params is keyed by paramsKey; version re-materializes on a new zero
|
|
241
259
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
242
260
|
}, [fn, paramsKey, enabled, ttl, version])
|
package/src/createZeroClient.tsx
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
} from 'react'
|
|
14
14
|
|
|
15
15
|
import { createPermissions } from './createPermissions'
|
|
16
|
+
import { ensureHttpPullTransport } from './httpPullTransport'
|
|
16
17
|
import {
|
|
17
18
|
createUseQuery,
|
|
18
19
|
createUseQueryDirect,
|
|
@@ -331,11 +332,20 @@ export function createZeroClient<
|
|
|
331
332
|
children,
|
|
332
333
|
authData: authDataIn,
|
|
333
334
|
disable,
|
|
335
|
+
transport,
|
|
336
|
+
pullIntervalMs = 30_000,
|
|
334
337
|
...props
|
|
335
338
|
}: Omit<ZeroOptions<Schema, ZeroMutators>, 'schema' | 'mutators'> & {
|
|
336
339
|
children: ReactNode
|
|
337
340
|
authData?: AuthData | null
|
|
338
341
|
disable?: boolean
|
|
342
|
+
// 'http-pull' runs the stock zero client over stateless HTTP pull/push
|
|
343
|
+
// (no websocket, no resident server state) by intercepting the sync
|
|
344
|
+
// socket for this instance's server origin. see httpPullTransport.ts.
|
|
345
|
+
transport?: 'http-pull'
|
|
346
|
+
// http-pull only: every open connection also pulls on this interval so
|
|
347
|
+
// server-initiated changes arrive without a client-side trigger
|
|
348
|
+
pullIntervalMs?: number
|
|
339
349
|
}) => {
|
|
340
350
|
const authData = (authDataIn ?? null) as AuthData
|
|
341
351
|
|
|
@@ -374,6 +384,7 @@ export function createZeroClient<
|
|
|
374
384
|
.sort(([a], [b]) => (a < b ? -1 : 1)),
|
|
375
385
|
hasAuth,
|
|
376
386
|
generation,
|
|
387
|
+
transport,
|
|
377
388
|
])
|
|
378
389
|
|
|
379
390
|
// create/rotate in an effect — commit-safe: a discarded concurrent render
|
|
@@ -391,6 +402,14 @@ export function createZeroClient<
|
|
|
391
402
|
ZeroOptions<Schema, ZeroMutators>,
|
|
392
403
|
'schema' | 'mutators'
|
|
393
404
|
>
|
|
405
|
+
// install before construction so the instance's first connect goes
|
|
406
|
+
// through HTTP. per-origin idempotent — rotation reuses the install.
|
|
407
|
+
if (transport === 'http-pull') {
|
|
408
|
+
if (typeof options.server !== 'string') {
|
|
409
|
+
throw new Error(`transport 'http-pull' requires a server URL`)
|
|
410
|
+
}
|
|
411
|
+
ensureHttpPullTransport({ origin: options.server, pullIntervalMs })
|
|
412
|
+
}
|
|
394
413
|
cached = {
|
|
395
414
|
key: instanceKey,
|
|
396
415
|
instance: new ZeroClient<Schema, ZeroMutators>({
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { afterEach, describe, expect, test } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
eventually,
|
|
5
|
+
sleep,
|
|
6
|
+
startZeroHttpHarness,
|
|
7
|
+
waitForComplete,
|
|
8
|
+
type ZeroHttpHarness,
|
|
9
|
+
} from './testHarness'
|
|
10
|
+
|
|
11
|
+
let harness: ZeroHttpHarness | undefined
|
|
12
|
+
|
|
13
|
+
type UserRow = { id: string; name: string }
|
|
14
|
+
type MemberRow = { id: string; projectId: string; userId: string }
|
|
15
|
+
type ProjectWithMembers = {
|
|
16
|
+
id: string
|
|
17
|
+
ownerId: string
|
|
18
|
+
name: string
|
|
19
|
+
members: MemberRow[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
afterEach(async () => {
|
|
23
|
+
await harness?.close()
|
|
24
|
+
harness = undefined
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe('zero-http auth parity', () => {
|
|
28
|
+
test('real clients only emit rows visible to their auth token', async () => {
|
|
29
|
+
harness = await startZeroHttpHarness({
|
|
30
|
+
seed: {
|
|
31
|
+
user: [
|
|
32
|
+
{ id: 'u1', name: 'ada' },
|
|
33
|
+
{ id: 'u2', name: 'ben' },
|
|
34
|
+
],
|
|
35
|
+
project: [
|
|
36
|
+
{ id: 'p-u1', ownerId: 'u1', name: 'u1 private' },
|
|
37
|
+
{ id: 'p-u2', ownerId: 'u2', name: 'u2 private' },
|
|
38
|
+
{ id: 'p-shared', ownerId: 'u2', name: 'shared' },
|
|
39
|
+
],
|
|
40
|
+
member: [
|
|
41
|
+
{ id: 'm-u1-owner', projectId: 'p-u1', userId: 'u1' },
|
|
42
|
+
{ id: 'm-u2-owner', projectId: 'p-u2', userId: 'u2' },
|
|
43
|
+
{ id: 'm-shared-u1', projectId: 'p-shared', userId: 'u1' },
|
|
44
|
+
{ id: 'm-shared-u2', projectId: 'p-shared', userId: 'u2' },
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
const u1 = harness.createZero('u1')
|
|
49
|
+
const u2 = harness.createZero('u2')
|
|
50
|
+
|
|
51
|
+
const u1Users = u1.query.user.materialize()
|
|
52
|
+
const u1Projects = u1.query.project.related('members').materialize()
|
|
53
|
+
const u2Users = u2.query.user.materialize()
|
|
54
|
+
const u2Projects = u2.query.project.related('members').materialize()
|
|
55
|
+
|
|
56
|
+
const u1UserEmissions: UserRow[][] = []
|
|
57
|
+
const u1ProjectEmissions: ProjectWithMembers[][] = []
|
|
58
|
+
const u2UserEmissions: UserRow[][] = []
|
|
59
|
+
const u2ProjectEmissions: ProjectWithMembers[][] = []
|
|
60
|
+
|
|
61
|
+
const stops = [
|
|
62
|
+
captureRows(u1Users, u1UserEmissions, normalizeUsers),
|
|
63
|
+
captureRows(u1Projects, u1ProjectEmissions, normalizeProjects),
|
|
64
|
+
captureRows(u2Users, u2UserEmissions, normalizeUsers),
|
|
65
|
+
captureRows(u2Projects, u2ProjectEmissions, normalizeProjects),
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const [u1UsersComplete, u1ProjectsComplete, u2UsersComplete, u2ProjectsComplete] =
|
|
70
|
+
await Promise.all([
|
|
71
|
+
waitForComplete<UserRow[]>(u1Users),
|
|
72
|
+
waitForComplete<ProjectWithMembers[]>(u1Projects),
|
|
73
|
+
waitForComplete<UserRow[]>(u2Users),
|
|
74
|
+
waitForComplete<ProjectWithMembers[]>(u2Projects),
|
|
75
|
+
])
|
|
76
|
+
|
|
77
|
+
expect(normalizeUsers(u1UsersComplete)).toEqual([{ id: 'u1', name: 'ada' }])
|
|
78
|
+
expect(normalizeProjects(u1ProjectsComplete)).toEqual([
|
|
79
|
+
{
|
|
80
|
+
id: 'p-shared',
|
|
81
|
+
ownerId: 'u2',
|
|
82
|
+
name: 'shared',
|
|
83
|
+
members: [
|
|
84
|
+
{ id: 'm-shared-u1', projectId: 'p-shared', userId: 'u1' },
|
|
85
|
+
{ id: 'm-shared-u2', projectId: 'p-shared', userId: 'u2' },
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'p-u1',
|
|
90
|
+
ownerId: 'u1',
|
|
91
|
+
name: 'u1 private',
|
|
92
|
+
members: [{ id: 'm-u1-owner', projectId: 'p-u1', userId: 'u1' }],
|
|
93
|
+
},
|
|
94
|
+
])
|
|
95
|
+
|
|
96
|
+
expect(normalizeUsers(u2UsersComplete)).toEqual([{ id: 'u2', name: 'ben' }])
|
|
97
|
+
expect(normalizeProjects(u2ProjectsComplete)).toEqual([
|
|
98
|
+
{
|
|
99
|
+
id: 'p-shared',
|
|
100
|
+
ownerId: 'u2',
|
|
101
|
+
name: 'shared',
|
|
102
|
+
members: [
|
|
103
|
+
{ id: 'm-shared-u1', projectId: 'p-shared', userId: 'u1' },
|
|
104
|
+
{ id: 'm-shared-u2', projectId: 'p-shared', userId: 'u2' },
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: 'p-u2',
|
|
109
|
+
ownerId: 'u2',
|
|
110
|
+
name: 'u2 private',
|
|
111
|
+
members: [{ id: 'm-u2-owner', projectId: 'p-u2', userId: 'u2' }],
|
|
112
|
+
},
|
|
113
|
+
])
|
|
114
|
+
|
|
115
|
+
assertNoUserEmission(u1UserEmissions, 'u2')
|
|
116
|
+
assertNoProjectEmission(u1ProjectEmissions, 'p-u2', 'm-u2-owner')
|
|
117
|
+
assertNoUserEmission(u2UserEmissions, 'u1')
|
|
118
|
+
assertNoProjectEmission(u2ProjectEmissions, 'p-u1', 'm-u1-owner')
|
|
119
|
+
|
|
120
|
+
await harness.transport.pull()
|
|
121
|
+
await sleep(50)
|
|
122
|
+
assertNoUserEmission(u1UserEmissions, 'u2')
|
|
123
|
+
assertNoProjectEmission(u1ProjectEmissions, 'p-u2', 'm-u2-owner')
|
|
124
|
+
assertNoUserEmission(u2UserEmissions, 'u1')
|
|
125
|
+
assertNoProjectEmission(u2ProjectEmissions, 'p-u1', 'm-u1-owner')
|
|
126
|
+
} finally {
|
|
127
|
+
for (const stop of stops) stop()
|
|
128
|
+
u1Users.destroy()
|
|
129
|
+
u1Projects.destroy()
|
|
130
|
+
u2Users.destroy()
|
|
131
|
+
u2Projects.destroy()
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
test('unknown token 401 reaches needs-auth without materializing data', async () => {
|
|
136
|
+
harness = await startZeroHttpHarness({
|
|
137
|
+
seed: {
|
|
138
|
+
user: [{ id: 'u1', name: 'ada' }],
|
|
139
|
+
project: [{ id: 'p-u1', ownerId: 'u1', name: 'u1 private' }],
|
|
140
|
+
member: [{ id: 'm-u1-owner', projectId: 'p-u1', userId: 'u1' }],
|
|
141
|
+
},
|
|
142
|
+
})
|
|
143
|
+
const unknown = harness.createZero('missing')
|
|
144
|
+
const projects = unknown.query.project.related('members').materialize()
|
|
145
|
+
const emissions: ProjectWithMembers[][] = []
|
|
146
|
+
const stop = captureRows(projects, emissions, normalizeProjects)
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
await eventually(() =>
|
|
150
|
+
expect(unknown.connection.state.current.name).toBe('needs-auth'),
|
|
151
|
+
)
|
|
152
|
+
await sleep(50)
|
|
153
|
+
|
|
154
|
+
expect(projects.data).toEqual([])
|
|
155
|
+
expect(emissions.every((emission) => emission.length === 0)).toBe(true)
|
|
156
|
+
} finally {
|
|
157
|
+
stop()
|
|
158
|
+
projects.destroy()
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// listener data is Immutable<T>; normalize maps to fresh mutable rows
|
|
164
|
+
function captureRows<T>(
|
|
165
|
+
view: { addListener(listener: (data: any, resultType: string) => void): () => void },
|
|
166
|
+
emissions: T[],
|
|
167
|
+
normalize: (data: T) => T,
|
|
168
|
+
) {
|
|
169
|
+
return view.addListener((data) => {
|
|
170
|
+
emissions.push(normalize(data))
|
|
171
|
+
})
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function assertNoUserEmission(emissions: UserRow[][], privateUserID: string) {
|
|
175
|
+
for (const emission of emissions) {
|
|
176
|
+
expect(emission.map((row) => row.id)).not.toContain(privateUserID)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function assertNoProjectEmission(
|
|
181
|
+
emissions: ProjectWithMembers[][],
|
|
182
|
+
privateProjectID: string,
|
|
183
|
+
privateMemberID: string,
|
|
184
|
+
) {
|
|
185
|
+
for (const emission of emissions) {
|
|
186
|
+
expect(emission.map((row) => row.id)).not.toContain(privateProjectID)
|
|
187
|
+
expect(
|
|
188
|
+
emission.flatMap((row) => row.members.map((member) => member.id)),
|
|
189
|
+
).not.toContain(privateMemberID)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function normalizeUsers(users: UserRow[]) {
|
|
194
|
+
return clone(users).sort((a, b) => a.id.localeCompare(b.id))
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function normalizeProjects(projects: ProjectWithMembers[]) {
|
|
198
|
+
return clone(projects)
|
|
199
|
+
.map((project) => ({
|
|
200
|
+
...project,
|
|
201
|
+
members: [...project.members].sort((a, b) => a.id.localeCompare(b.id)),
|
|
202
|
+
}))
|
|
203
|
+
.sort((a, b) => a.id.localeCompare(b.id))
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function clone<T>(value: T): T {
|
|
207
|
+
return JSON.parse(JSON.stringify(value)) as T
|
|
208
|
+
}
|