on-zero 0.4.22 → 0.4.24

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 (93) hide show
  1. package/dist/cjs/combineZeroClients.cjs +101 -0
  2. package/dist/cjs/combineZeroClients.native.js +150 -0
  3. package/dist/cjs/combineZeroClients.native.js.map +1 -0
  4. package/dist/cjs/createUseQuery.cjs +92 -4
  5. package/dist/cjs/createUseQuery.native.js +130 -4
  6. package/dist/cjs/createUseQuery.native.js.map +1 -1
  7. package/dist/cjs/createZeroClient.cjs +89 -12
  8. package/dist/cjs/createZeroClient.native.js +134 -43
  9. package/dist/cjs/createZeroClient.native.js.map +1 -1
  10. package/dist/cjs/index.cjs +1 -0
  11. package/dist/cjs/index.native.js +1 -0
  12. package/dist/cjs/index.native.js.map +1 -1
  13. package/dist/cjs/instanceRegistry.cjs +65 -0
  14. package/dist/cjs/instanceRegistry.native.js +111 -0
  15. package/dist/cjs/instanceRegistry.native.js.map +1 -0
  16. package/dist/cjs/multiInstance.test.cjs +322 -0
  17. package/dist/cjs/multiInstance.test.native.js +387 -0
  18. package/dist/cjs/multiInstance.test.native.js.map +1 -0
  19. package/dist/cjs/multiInstanceNested.test.cjs +206 -0
  20. package/dist/cjs/multiInstanceNested.test.native.js +254 -0
  21. package/dist/cjs/multiInstanceNested.test.native.js.map +1 -0
  22. package/dist/cjs/run.cjs +5 -5
  23. package/dist/cjs/run.native.js +6 -5
  24. package/dist/cjs/run.native.js.map +1 -1
  25. package/dist/cjs/zeroRunner.cjs +4 -1
  26. package/dist/cjs/zeroRunner.native.js +4 -1
  27. package/dist/cjs/zeroRunner.native.js.map +1 -1
  28. package/dist/esm/combineZeroClients.mjs +76 -0
  29. package/dist/esm/combineZeroClients.mjs.map +1 -0
  30. package/dist/esm/combineZeroClients.native.js +122 -0
  31. package/dist/esm/combineZeroClients.native.js.map +1 -0
  32. package/dist/esm/createUseQuery.mjs +92 -5
  33. package/dist/esm/createUseQuery.mjs.map +1 -1
  34. package/dist/esm/createUseQuery.native.js +130 -5
  35. package/dist/esm/createUseQuery.native.js.map +1 -1
  36. package/dist/esm/createZeroClient.mjs +93 -16
  37. package/dist/esm/createZeroClient.mjs.map +1 -1
  38. package/dist/esm/createZeroClient.native.js +138 -47
  39. package/dist/esm/createZeroClient.native.js.map +1 -1
  40. package/dist/esm/index.js +1 -0
  41. package/dist/esm/index.js.map +1 -1
  42. package/dist/esm/index.mjs +1 -0
  43. package/dist/esm/index.mjs.map +1 -1
  44. package/dist/esm/index.native.js +1 -0
  45. package/dist/esm/index.native.js.map +1 -1
  46. package/dist/esm/instanceRegistry.mjs +38 -0
  47. package/dist/esm/instanceRegistry.mjs.map +1 -0
  48. package/dist/esm/instanceRegistry.native.js +81 -0
  49. package/dist/esm/instanceRegistry.native.js.map +1 -0
  50. package/dist/esm/multiInstance.test.mjs +323 -0
  51. package/dist/esm/multiInstance.test.mjs.map +1 -0
  52. package/dist/esm/multiInstance.test.native.js +385 -0
  53. package/dist/esm/multiInstance.test.native.js.map +1 -0
  54. package/dist/esm/multiInstanceNested.test.mjs +207 -0
  55. package/dist/esm/multiInstanceNested.test.mjs.map +1 -0
  56. package/dist/esm/multiInstanceNested.test.native.js +252 -0
  57. package/dist/esm/multiInstanceNested.test.native.js.map +1 -0
  58. package/dist/esm/run.mjs +5 -5
  59. package/dist/esm/run.mjs.map +1 -1
  60. package/dist/esm/run.native.js +6 -5
  61. package/dist/esm/run.native.js.map +1 -1
  62. package/dist/esm/zeroRunner.mjs +4 -1
  63. package/dist/esm/zeroRunner.mjs.map +1 -1
  64. package/dist/esm/zeroRunner.native.js +4 -1
  65. package/dist/esm/zeroRunner.native.js.map +1 -1
  66. package/package.json +5 -3
  67. package/readme.md +59 -0
  68. package/src/combineZeroClients.tsx +186 -0
  69. package/src/createUseQuery.tsx +175 -12
  70. package/src/createZeroClient.tsx +227 -54
  71. package/src/index.ts +1 -0
  72. package/src/instanceRegistry.ts +75 -0
  73. package/src/multiInstance.test.tsx +284 -0
  74. package/src/multiInstanceNested.test.tsx +205 -0
  75. package/src/run.ts +7 -6
  76. package/src/zeroRunner.ts +7 -1
  77. package/types/combineZeroClients.d.ts +38 -0
  78. package/types/combineZeroClients.d.ts.map +1 -0
  79. package/types/createUseQuery.d.ts +15 -0
  80. package/types/createUseQuery.d.ts.map +1 -1
  81. package/types/createZeroClient.d.ts +10 -4
  82. package/types/createZeroClient.d.ts.map +1 -1
  83. package/types/index.d.ts +1 -0
  84. package/types/index.d.ts.map +1 -1
  85. package/types/instanceRegistry.d.ts +15 -0
  86. package/types/instanceRegistry.d.ts.map +1 -0
  87. package/types/multiInstance.test.d.ts +2 -0
  88. package/types/multiInstance.test.d.ts.map +1 -0
  89. package/types/multiInstanceNested.test.d.ts +5 -0
  90. package/types/multiInstanceNested.test.d.ts.map +1 -0
  91. package/types/run.d.ts.map +1 -1
  92. package/types/zeroRunner.d.ts +3 -1
  93. package/types/zeroRunner.d.ts.map +1 -1
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
+ get: () => from[key],
17
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
+ });
19
+ }
20
+ return to;
21
+ };
22
+ var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
23
+ value: true
24
+ }), mod);
25
+ var instanceRegistry_exports = {};
26
+ __export(instanceRegistry_exports, {
27
+ getInstanceForNamespace: () => getInstanceForNamespace,
28
+ getInstanceForQueryFn: () => getInstanceForQueryFn,
29
+ registerClientInstance: () => registerClientInstance
30
+ });
31
+ module.exports = __toCommonJS(instanceRegistry_exports);
32
+ var import_helpers = require("@take-out/helpers");
33
+ var import_queryRegistry = require("./queryRegistry.native.js");
34
+ var getInstancesByNamespace = function () {
35
+ return (0, import_helpers.globalValue)("on-zero:instances-by-namespace", function () {
36
+ return /* @__PURE__ */new Map();
37
+ });
38
+ };
39
+ function registerClientInstance(param) {
40
+ var {
41
+ name,
42
+ namespaces,
43
+ customQueries
44
+ } = param;
45
+ var instancesByNamespace = getInstancesByNamespace();
46
+ var _iteratorNormalCompletion = true,
47
+ _didIteratorError = false,
48
+ _iteratorError = void 0;
49
+ try {
50
+ for (var _iterator = instancesByNamespace[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
51
+ var [namespace, owner] = _step.value;
52
+ if (owner.name === name) {
53
+ instancesByNamespace.delete(namespace);
54
+ }
55
+ }
56
+ } catch (err) {
57
+ _didIteratorError = true;
58
+ _iteratorError = err;
59
+ } finally {
60
+ try {
61
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
62
+ _iterator.return();
63
+ }
64
+ } finally {
65
+ if (_didIteratorError) {
66
+ throw _iteratorError;
67
+ }
68
+ }
69
+ }
70
+ var instance = {
71
+ name,
72
+ customQueries,
73
+ runner: null
74
+ };
75
+ var _iteratorNormalCompletion1 = true,
76
+ _didIteratorError1 = false,
77
+ _iteratorError1 = void 0;
78
+ try {
79
+ for (var _iterator1 = namespaces[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
80
+ var namespace1 = _step1.value;
81
+ var existing = instancesByNamespace.get(namespace1);
82
+ if (existing) {
83
+ throw new Error(`[on-zero] namespace '${namespace1}' is already claimed by zero client instance '${existing.name}' (while creating instance '${name}'). Each query/mutator namespace must belong to exactly one createZeroClient instance.`);
84
+ }
85
+ instancesByNamespace.set(namespace1, instance);
86
+ }
87
+ } catch (err) {
88
+ _didIteratorError1 = true;
89
+ _iteratorError1 = err;
90
+ } finally {
91
+ try {
92
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
93
+ _iterator1.return();
94
+ }
95
+ } finally {
96
+ if (_didIteratorError1) {
97
+ throw _iteratorError1;
98
+ }
99
+ }
100
+ }
101
+ return instance;
102
+ }
103
+ function getInstanceForNamespace(namespace) {
104
+ return getInstancesByNamespace().get(namespace);
105
+ }
106
+ function getInstanceForQueryFn(fn) {
107
+ var queryName = (0, import_queryRegistry.getQueryName)(fn);
108
+ if (!queryName) return void 0;
109
+ return getInstanceForNamespace(queryName.split(".", 1)[0]);
110
+ }
111
+ //# sourceMappingURL=instanceRegistry.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["__toCommonJS","mod","__copyProps","__defProp","value","instanceRegistry_exports","__export","getInstanceForNamespace","getInstanceForQueryFn","registerClientInstance","module","exports","import_helpers","require","import_queryRegistry","getInstancesByNamespace","globalValue","Map","param","name","namespaces","customQueries","instancesByNamespace","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_iterator","Symbol","iterator","_step","next","done","namespace","owner","delete","err","return","instance","runner"],"sources":["../../src/instanceRegistry.ts"],"sourcesContent":[null],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,GAAA,IAAAC,WAAA,CAAAC,SAAA;EAAAC,KAAA;AAAA,IAAAH,GAAA;AAAA,IAAAI,wBAAA;AAAAC,QAAA,CAAAD,wBAAA;EAAAE,uBAAA,EAAAA,CAAA,KAAAA,uBAAA;EAAAC,qBAAA,EAAAA,CAAA,KAAAA,qBAAA;EAAAC,sBAAA,EAAAA,CAAA,KAAAA;AAAA;AASAC,MAAA,CAAAC,OAAA,GAAAX,YAA4B,CAAAK,wBAAA;AAE5B,IAAAO,cAAA,GAAAC,OAA6B;AAa7B,IAAAC,oBAAM,GAAAD,OAA0B,4BAC9B;AAAA,IACEE,uBAAA,YAAAA,CAAA;EACA,OAAM,IAAAH,cAAA,CAAII,WAAI;IAChB,0BAAAC,GAAA;EAEK;AAAgC;AACrC,SACAR,uBAAAS,KAAA;EACA;IAAAC,IAAA;IAAAC,UAAA;IAAAC;EAAA,IAAAH,KAAA;EACF,IAIuBI,oBAAA,GAAAP,uBAAA;EACrB,IAAAQ,yBAA6B;IAAAC,iBAAwB;IAAAC,cAAA;EAGrD;IACE,KAAI,IAAAC,SAAM,GAASJ,oBAAM,CAAAK,MAAA,CAAAC,QAAA,KAAAC,KAAA,IAAAN,yBAAA,IAAAM,KAAA,GAAAH,SAAA,CAAAI,IAAA,IAAAC,IAAA,GAAAR,yBAAA;MACvB,KAAAS,SAAA,EAAAC,KAAqB,IAAAJ,KAAO,CAAAzB,KAAA;MAC9B,IAAA6B,KAAA,CAAAd,IAAA,KAAAA,IAAA;QACFG,oBAAA,CAAAY,MAAA,CAAAF,SAAA;MAEA;IAEA;EACE,SAAMG,GAAA;IACNX,iBAAc;IACZC,cAAU,GAAAU,GAAA;EAAA,UACR;IACmC,IACrC;MACF,KAAAZ,yBAAA,IAAAG,SAAA,CAAAU,MAAA;QACAV,SAAA,CAAAU,MAAA,CAAqB;MACvB;IAEA,UAAO;MACT,IAAAZ,iBAAA;QAEO,MAASC,cAAA;MAGd;IACF;EAEO;EACL,IAAAY,QAAM;IACNlB,IAAK;IACLE,aAAO;IACTiB,MAAA","ignoreList":[]}
@@ -0,0 +1,322 @@
1
+ var import_zero = require("@rocicorp/zero");
2
+ var import_helpers = require("@take-out/helpers");
3
+ var import_vitest = require("vitest");
4
+ var import_combineZeroClients = require("./combineZeroClients.cjs");
5
+ var import_createZeroClient = require("./createZeroClient.cjs");
6
+ var import_instanceRegistry = require("./instanceRegistry.cjs");
7
+ var import_queryRegistry = require("./queryRegistry.cjs");
8
+ var import_run = require("./run.cjs");
9
+ var import_zeroRunner = require("./zeroRunner.cjs");
10
+ const userTable = (0, import_zero.table)("user").columns({
11
+ id: (0, import_zero.string)(),
12
+ name: (0, import_zero.string)()
13
+ }).primaryKey("id");
14
+ const taskTable = (0, import_zero.table)("task").columns({
15
+ id: (0, import_zero.string)(),
16
+ title: (0, import_zero.string)()
17
+ }).primaryKey("id");
18
+ const schema = (0, import_zero.createSchema)({
19
+ tables: [userTable, taskTable]
20
+ });
21
+ const makeQueryFn = () => args => args;
22
+ function makeClient(instanceName, namespace) {
23
+ const byId = makeQueryFn();
24
+ return {
25
+ byId,
26
+ client: (0, import_createZeroClient.createZeroClient)({
27
+ schema,
28
+ models: {},
29
+ groupedQueries: {
30
+ [namespace]: {
31
+ byId
32
+ }
33
+ },
34
+ instanceName
35
+ })
36
+ };
37
+ }
38
+ function fakeClient(name, namespaces, zeroStub) {
39
+ (0, import_instanceRegistry.registerClientInstance)({
40
+ name,
41
+ namespaces,
42
+ // boundary stub: dispatch tests never resolve queries through it
43
+ customQueries: {}
44
+ });
45
+ return {
46
+ instanceName: name,
47
+ useQuery: import_vitest.vi.fn(() => `${name}-useQuery`),
48
+ useQueryDirect: import_vitest.vi.fn(() => `${name}-useQueryDirect`),
49
+ usePermission: import_vitest.vi.fn(() => `${name}-usePermission`),
50
+ usePermissionDirect: import_vitest.vi.fn(() => `${name}-usePermissionDirect`),
51
+ zero: zeroStub,
52
+ preload: import_vitest.vi.fn(() => `${name}-preload`),
53
+ getQuery: import_vitest.vi.fn(() => `${name}-getQuery`),
54
+ zeroEvents: (0, import_helpers.createEmitter)(`zero:test-${name}`, null),
55
+ ControlQueries: ({
56
+ children
57
+ }) => children
58
+ };
59
+ }
60
+ (0, import_vitest.describe)("multi-instance namespace dispatch", () => {
61
+ (0, import_vitest.test)("run() dispatches named queries to the owning instance runner", async () => {
62
+ const control = makeClient("run-control", "runUser");
63
+ const project = makeClient("run-project", "runTask");
64
+ const controlRunner = import_vitest.vi.fn(async (..._args) => ({
65
+ from: "control"
66
+ }));
67
+ const projectRunner = import_vitest.vi.fn(async (..._args) => ({
68
+ from: "project"
69
+ }));
70
+ (0, import_instanceRegistry.getInstanceForNamespace)("runUser").runner = controlRunner;
71
+ (0, import_instanceRegistry.getInstanceForNamespace)("runTask").runner = projectRunner;
72
+ const ambientRunner = import_vitest.vi.fn(async (..._args) => ({
73
+ from: "ambient"
74
+ }));
75
+ (0, import_zeroRunner.setRunner)(ambientRunner);
76
+ await (0, import_vitest.expect)((0, import_run.run)(control.byId, {
77
+ id: "1"
78
+ })).resolves.toEqual({
79
+ from: "control"
80
+ });
81
+ await (0, import_vitest.expect)((0, import_run.run)(project.byId, {
82
+ id: "2"
83
+ })).resolves.toEqual({
84
+ from: "project"
85
+ });
86
+ (0, import_vitest.expect)(ambientRunner).not.toHaveBeenCalled();
87
+ const request = controlRunner.mock.calls[0][0];
88
+ (0, import_vitest.expect)(request.query.queryName).toBe("runUser.byId");
89
+ });
90
+ (0, import_vitest.test)("a claimed namespace with an unmounted instance uses the ambient runner (server path)", async () => {
91
+ const {
92
+ byId
93
+ } = makeClient("srv-instance", "srvThing");
94
+ const ambient = import_vitest.vi.fn(async (..._args) => ({
95
+ from: "ambient"
96
+ }));
97
+ (0, import_zeroRunner.setRunner)(ambient);
98
+ await (0, import_vitest.expect)((0, import_run.run)(byId, {
99
+ id: "1"
100
+ })).resolves.toEqual({
101
+ from: "ambient"
102
+ });
103
+ (0, import_vitest.expect)(ambient).toHaveBeenCalledTimes(1);
104
+ });
105
+ (0, import_vitest.test)("duplicate namespace claim throws at create time", () => {
106
+ makeClient("dup-a", "dupNs");
107
+ (0, import_vitest.expect)(() => makeClient("dup-b", "dupNs")).toThrow(/already claimed/);
108
+ });
109
+ (0, import_vitest.test)("re-creating an instance under the same name re-claims without throwing (hmr)", () => {
110
+ makeClient("hmr", "hmrNs");
111
+ (0, import_vitest.expect)(() => makeClient("hmr", "hmrNs")).not.toThrow();
112
+ (0, import_vitest.expect)((0, import_instanceRegistry.getInstanceForNamespace)("hmrNs")?.name).toBe("hmr");
113
+ });
114
+ (0, import_vitest.test)("model namespaces are claimed too", () => {
115
+ const models = {
116
+ mdlThing: {
117
+ mutate: {
118
+ insert: async () => {}
119
+ }
120
+ }
121
+ };
122
+ (0, import_createZeroClient.createZeroClient)({
123
+ schema,
124
+ models,
125
+ groupedQueries: {},
126
+ instanceName: "mdl-a"
127
+ });
128
+ (0, import_vitest.expect)((0, import_instanceRegistry.getInstanceForNamespace)("mdlThing")?.name).toBe("mdl-a");
129
+ (0, import_vitest.expect)(() => (0, import_createZeroClient.createZeroClient)({
130
+ schema,
131
+ models,
132
+ groupedQueries: {},
133
+ instanceName: "mdl-b"
134
+ })).toThrow(/already claimed/);
135
+ });
136
+ });
137
+ (0, import_vitest.describe)("multi-instance isolation", () => {
138
+ (0, import_vitest.test)("each instance has an isolated zeroEvents emitter", () => {
139
+ const {
140
+ client: a
141
+ } = makeClient("emit-a", "emitA");
142
+ const {
143
+ client: b
144
+ } = makeClient("emit-b", "emitB");
145
+ (0, import_vitest.expect)(a.zeroEvents).not.toBe(b.zeroEvents);
146
+ (0, import_vitest.expect)(a.zeroEvents.options?.name).toBe("zero:emit-a");
147
+ (0, import_vitest.expect)(b.zeroEvents.options?.name).toBe("zero:emit-b");
148
+ const seenByB = [];
149
+ b.zeroEvents.listen(event => seenByB.push(event));
150
+ a.zeroEvents.emit({
151
+ type: "error",
152
+ message: "a-only"
153
+ });
154
+ (0, import_vitest.expect)(seenByB).toEqual([]);
155
+ (0, import_vitest.expect)(a.zeroEvents.value).toEqual({
156
+ type: "error",
157
+ message: "a-only"
158
+ });
159
+ (0, import_vitest.expect)(b.zeroEvents.value).toBe(null);
160
+ });
161
+ (0, import_vitest.test)("the default instance keeps the legacy emitter name", () => {
162
+ const {
163
+ client
164
+ } = makeClient("default", "defaultNs");
165
+ (0, import_vitest.expect)(client.zeroEvents.options?.name).toBe("zero");
166
+ });
167
+ (0, import_vitest.test)("each instance has its own unmounted zero proxy", () => {
168
+ const {
169
+ client: a
170
+ } = makeClient("proxy-a", "proxyA");
171
+ const {
172
+ client: b
173
+ } = makeClient("proxy-b", "proxyB");
174
+ (0, import_vitest.expect)(a.zero === b.zero).toBe(false);
175
+ (0, import_vitest.expect)(() => a.zero.clientID).toThrow(/not initialized/);
176
+ (0, import_vitest.expect)(() => b.zero.clientID).toThrow(/not initialized/);
177
+ });
178
+ });
179
+ (0, import_vitest.describe)("combineZeroClients facade", () => {
180
+ (0, import_vitest.test)("zero.mutate dispatches by model namespace, rest forwards to primary", () => {
181
+ const insertSpy = import_vitest.vi.fn();
182
+ const updateSpy = import_vitest.vi.fn();
183
+ const control = fakeClient("fz-control", ["fzUser"], {
184
+ mutate: {
185
+ fzUser: {
186
+ insert: insertSpy
187
+ }
188
+ },
189
+ userID: "primary-user"
190
+ });
191
+ const project = fakeClient("fz-project", ["fzTask"], {
192
+ mutate: {
193
+ fzTask: {
194
+ update: updateSpy
195
+ }
196
+ },
197
+ userID: "project-user"
198
+ });
199
+ const combined = (0, import_combineZeroClients.combineZeroClients)(control, project);
200
+ const zero = combined.zero;
201
+ zero.mutate.fzUser.insert({
202
+ id: "1"
203
+ });
204
+ zero.mutate.fzTask.update({
205
+ id: "2"
206
+ });
207
+ (0, import_vitest.expect)(insertSpy).toHaveBeenCalledWith({
208
+ id: "1"
209
+ });
210
+ (0, import_vitest.expect)(updateSpy).toHaveBeenCalledWith({
211
+ id: "2"
212
+ });
213
+ (0, import_vitest.expect)(zero.userID).toBe("primary-user");
214
+ (0, import_vitest.expect)(zero.mutate.unknownNs).toBe(void 0);
215
+ });
216
+ (0, import_vitest.test)("useQuery/preload/getQuery/usePermission dispatch by namespace", () => {
217
+ const control = fakeClient("fq-control", ["fqUser"], {});
218
+ const project = fakeClient("fq-project", ["fqTask"], {});
219
+ const userQuery = makeQueryFn();
220
+ const taskQuery = makeQueryFn();
221
+ (0, import_queryRegistry.registerQuery)(userQuery, "fqUser.byId");
222
+ (0, import_queryRegistry.registerQuery)(taskQuery, "fqTask.byId");
223
+ const combined = (0, import_combineZeroClients.combineZeroClients)(control, project);
224
+ const useQuery = combined.useQuery;
225
+ const preload = combined.preload;
226
+ const getQuery = combined.getQuery;
227
+ const usePermission = combined.usePermission;
228
+ useQuery(userQuery, {
229
+ id: "1"
230
+ });
231
+ (0, import_vitest.expect)(control.useQueryDirect).toHaveBeenCalledWith(userQuery, {
232
+ id: "1"
233
+ });
234
+ (0, import_vitest.expect)(control.useQuery).not.toHaveBeenCalled();
235
+ (0, import_vitest.expect)(project.useQuery).not.toHaveBeenCalled();
236
+ useQuery(taskQuery, {
237
+ id: "2"
238
+ });
239
+ (0, import_vitest.expect)(project.useQuery).toHaveBeenCalledWith(taskQuery, {
240
+ id: "2"
241
+ });
242
+ (0, import_vitest.expect)(project.useQueryDirect).not.toHaveBeenCalled();
243
+ preload(taskQuery, {
244
+ id: "3"
245
+ });
246
+ (0, import_vitest.expect)(project.preload).toHaveBeenCalledWith(taskQuery, {
247
+ id: "3"
248
+ });
249
+ (0, import_vitest.expect)(control.preload).not.toHaveBeenCalled();
250
+ getQuery(userQuery, {
251
+ id: "4"
252
+ });
253
+ (0, import_vitest.expect)(control.getQuery).toHaveBeenCalledWith(userQuery, {
254
+ id: "4"
255
+ });
256
+ (0, import_vitest.expect)(project.getQuery).not.toHaveBeenCalled();
257
+ const anonymous = makeQueryFn();
258
+ useQuery(anonymous, {
259
+ id: "5"
260
+ });
261
+ (0, import_vitest.expect)(control.useQueryDirect).toHaveBeenCalledWith(anonymous, {
262
+ id: "5"
263
+ });
264
+ usePermission("fqTask", "row-1");
265
+ (0, import_vitest.expect)(project.usePermission).toHaveBeenCalledWith("fqTask", "row-1");
266
+ (0, import_vitest.expect)(project.usePermissionDirect).not.toHaveBeenCalled();
267
+ usePermission("fqUser", "row-2");
268
+ (0, import_vitest.expect)(control.usePermissionDirect).toHaveBeenCalledWith("fqUser", "row-2");
269
+ (0, import_vitest.expect)(control.usePermission).not.toHaveBeenCalled();
270
+ });
271
+ (0, import_vitest.test)("the inner option overrides which client uses the context path", () => {
272
+ const a = fakeClient("inner-a", ["innerA"], {});
273
+ const b = fakeClient("inner-b", ["innerB"], {});
274
+ const aQuery = makeQueryFn();
275
+ const bQuery = makeQueryFn();
276
+ (0, import_queryRegistry.registerQuery)(aQuery, "innerA.byId");
277
+ (0, import_queryRegistry.registerQuery)(bQuery, "innerB.byId");
278
+ const combined = (0, import_combineZeroClients.combineZeroClients)(a, b, {
279
+ inner: "inner-a"
280
+ });
281
+ const useQuery = combined.useQuery;
282
+ useQuery(aQuery, {
283
+ id: "1"
284
+ });
285
+ (0, import_vitest.expect)(a.useQuery).toHaveBeenCalledWith(aQuery, {
286
+ id: "1"
287
+ });
288
+ (0, import_vitest.expect)(a.useQueryDirect).not.toHaveBeenCalled();
289
+ useQuery(bQuery, {
290
+ id: "2"
291
+ });
292
+ (0, import_vitest.expect)(b.useQueryDirect).toHaveBeenCalledWith(bQuery, {
293
+ id: "2"
294
+ });
295
+ (0, import_vitest.expect)(b.useQuery).not.toHaveBeenCalled();
296
+ (0, import_vitest.expect)(() => (0, import_combineZeroClients.combineZeroClients)(a, b, {
297
+ inner: "nope"
298
+ })).toThrow(/not one of the passed clients/);
299
+ });
300
+ (0, import_vitest.test)("combined zeroEvents relays every instance", () => {
301
+ const {
302
+ client: a
303
+ } = makeClient("relay-a", "relayA");
304
+ const {
305
+ client: b
306
+ } = makeClient("relay-b", "relayB");
307
+ const combined = (0, import_combineZeroClients.combineZeroClients)(a, b);
308
+ const seen = [];
309
+ combined.zeroEvents.listen(event => seen.push(event));
310
+ a.zeroEvents.emit({
311
+ type: "error",
312
+ message: "from-a"
313
+ });
314
+ b.zeroEvents.emit({
315
+ type: "error",
316
+ message: "from-b"
317
+ });
318
+ (0, import_vitest.expect)(seen.map(event => event?.message)).toEqual(["from-a", "from-b"]);
319
+ (0, import_vitest.expect)(a.zeroEvents.value?.message).toBe("from-a");
320
+ (0, import_vitest.expect)(b.zeroEvents.value?.message).toBe("from-b");
321
+ });
322
+ });