@comapeo/core-react 9.0.2 → 10.0.0
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 +1 -1
- package/dist/commonjs/contexts/ClientApi.d.ts +1 -3
- package/dist/commonjs/contexts/ClientApi.js +2 -2
- package/dist/commonjs/hooks/client.d.ts +74 -33
- package/dist/commonjs/hooks/client.js +40 -11
- package/dist/commonjs/hooks/documents.d.ts +41 -429
- package/dist/commonjs/hooks/documents.js +101 -51
- package/dist/commonjs/hooks/invites.d.ts +153 -55
- package/dist/commonjs/hooks/invites.js +69 -20
- package/dist/commonjs/hooks/maps.d.ts +96 -225
- package/dist/commonjs/hooks/maps.js +104 -37
- package/dist/commonjs/hooks/projects.d.ts +666 -223
- package/dist/commonjs/hooks/projects.js +264 -131
- package/dist/commonjs/index.d.ts +2 -2
- package/dist/commonjs/lib/map-shares-stores.d.ts +1 -1
- package/dist/commonjs/lib/map-shares-stores.js +2 -2
- package/dist/commonjs/lib/presets.d.ts +1 -3
- package/dist/commonjs/lib/react-query.d.ts +103 -0
- package/dist/commonjs/lib/react-query.js +187 -0
- package/dist/commonjs/lib/sync.d.ts +2 -5
- package/dist/commonjs/lib/sync.js +0 -1
- package/dist/commonjs/lib/types.d.ts +4 -6
- package/dist/esm/contexts/ClientApi.d.ts +1 -3
- package/dist/esm/contexts/ClientApi.js +1 -1
- package/dist/esm/hooks/client.d.ts +74 -33
- package/dist/esm/hooks/client.js +40 -11
- package/dist/esm/hooks/documents.d.ts +41 -429
- package/dist/esm/hooks/documents.js +101 -51
- package/dist/esm/hooks/invites.d.ts +153 -55
- package/dist/esm/hooks/invites.js +69 -20
- package/dist/esm/hooks/maps.d.ts +96 -225
- package/dist/esm/hooks/maps.js +105 -38
- package/dist/esm/hooks/projects.d.ts +666 -223
- package/dist/esm/hooks/projects.js +262 -129
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/lib/map-shares-stores.d.ts +1 -1
- package/dist/esm/lib/map-shares-stores.js +1 -1
- package/dist/esm/lib/presets.d.ts +1 -3
- package/dist/esm/lib/react-query.d.ts +103 -0
- package/dist/esm/lib/react-query.js +162 -0
- package/dist/esm/lib/sync.d.ts +2 -5
- package/dist/esm/lib/sync.js +1 -1
- package/dist/esm/lib/types.d.ts +4 -6
- package/docs/API.md +137 -81
- package/package.json +39 -35
- package/dist/commonjs/lib/react-query/client.d.ts +0 -65
- package/dist/commonjs/lib/react-query/client.js +0 -68
- package/dist/commonjs/lib/react-query/documents.d.ts +0 -1484
- package/dist/commonjs/lib/react-query/documents.js +0 -149
- package/dist/commonjs/lib/react-query/invites.d.ts +0 -88
- package/dist/commonjs/lib/react-query/invites.js +0 -95
- package/dist/commonjs/lib/react-query/maps.d.ts +0 -104
- package/dist/commonjs/lib/react-query/maps.js +0 -129
- package/dist/commonjs/lib/react-query/mutation-result.d.ts +0 -8
- package/dist/commonjs/lib/react-query/mutation-result.js +0 -22
- package/dist/commonjs/lib/react-query/projects.d.ts +0 -316
- package/dist/commonjs/lib/react-query/projects.js +0 -359
- package/dist/commonjs/lib/react-query/shared.d.ts +0 -9
- package/dist/commonjs/lib/react-query/shared.js +0 -23
- package/dist/esm/lib/react-query/client.d.ts +0 -65
- package/dist/esm/lib/react-query/client.js +0 -59
- package/dist/esm/lib/react-query/documents.d.ts +0 -1484
- package/dist/esm/lib/react-query/documents.js +0 -137
- package/dist/esm/lib/react-query/invites.d.ts +0 -88
- package/dist/esm/lib/react-query/invites.js +0 -85
- package/dist/esm/lib/react-query/maps.d.ts +0 -104
- package/dist/esm/lib/react-query/maps.js +0 -119
- package/dist/esm/lib/react-query/mutation-result.d.ts +0 -8
- package/dist/esm/lib/react-query/mutation-result.js +0 -19
- package/dist/esm/lib/react-query/projects.d.ts +0 -316
- package/dist/esm/lib/react-query/projects.js +0 -324
- package/dist/esm/lib/react-query/shared.d.ts +0 -9
- package/dist/esm/lib/react-query/shared.js +0 -18
|
@@ -31,7 +31,7 @@ exports.useExportGeoJSON = useExportGeoJSON;
|
|
|
31
31
|
exports.useExportZipFile = useExportZipFile;
|
|
32
32
|
const react_query_1 = require("@tanstack/react-query");
|
|
33
33
|
const react_1 = require("react");
|
|
34
|
-
const
|
|
34
|
+
const react_query_js_1 = require("../lib/react-query.js");
|
|
35
35
|
const sync_js_1 = require("../lib/sync.js");
|
|
36
36
|
const urls_js_1 = require("../lib/urls.js");
|
|
37
37
|
const client_js_1 = require("./client.js");
|
|
@@ -49,16 +49,15 @@ const client_js_1 = require("./client.js");
|
|
|
49
49
|
* }
|
|
50
50
|
* ```
|
|
51
51
|
*/
|
|
52
|
-
function useProjectSettings({ projectId }) {
|
|
53
|
-
const
|
|
54
|
-
const { data
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}));
|
|
52
|
+
function useProjectSettings({ projectId, }) {
|
|
53
|
+
const { data: projectApi } = useSingleProject({ projectId });
|
|
54
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
55
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
56
|
+
queryKey: (0, react_query_js_1.getProjectSettingsQueryKey)({ projectId }),
|
|
57
|
+
queryFn: async () => {
|
|
58
|
+
return projectApi.$getProjectSettings();
|
|
59
|
+
},
|
|
60
|
+
});
|
|
62
61
|
return { data, error, isRefetching };
|
|
63
62
|
}
|
|
64
63
|
/**
|
|
@@ -75,13 +74,14 @@ function useProjectSettings({ projectId }) {
|
|
|
75
74
|
* }
|
|
76
75
|
* ```
|
|
77
76
|
*/
|
|
78
|
-
function useSingleProject({ projectId }) {
|
|
77
|
+
function useSingleProject({ projectId, }) {
|
|
79
78
|
const clientApi = (0, client_js_1.useClientApi)();
|
|
80
79
|
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
81
|
-
...(0,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
81
|
+
queryKey: (0, react_query_js_1.getProjectByIdQueryKey)({ projectId }),
|
|
82
|
+
queryFn: async () => {
|
|
83
|
+
return clientApi.getProject(projectId);
|
|
84
|
+
},
|
|
85
85
|
// Keep project instances around indefinitely - shouldn't be a memory
|
|
86
86
|
// problem because these are only lightweight proxy objects, and project
|
|
87
87
|
// references are kept indefinitely on the backend anyway once they are
|
|
@@ -105,9 +105,13 @@ function useSingleProject({ projectId }) {
|
|
|
105
105
|
*/
|
|
106
106
|
function useManyProjects() {
|
|
107
107
|
const clientApi = (0, client_js_1.useClientApi)();
|
|
108
|
-
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)(
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
109
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
110
|
+
queryKey: (0, react_query_js_1.getProjectsQueryKey)(),
|
|
111
|
+
queryFn: async () => {
|
|
112
|
+
return clientApi.listProjects();
|
|
113
|
+
},
|
|
114
|
+
});
|
|
111
115
|
return { data, error, isRefetching };
|
|
112
116
|
}
|
|
113
117
|
/**
|
|
@@ -127,11 +131,13 @@ function useManyProjects() {
|
|
|
127
131
|
*/
|
|
128
132
|
function useSingleMember({ projectId, deviceId, }) {
|
|
129
133
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
130
|
-
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)(
|
|
131
|
-
|
|
132
|
-
projectId,
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
135
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
136
|
+
queryKey: (0, react_query_js_1.getMemberByIdQueryKey)({ projectId, deviceId }),
|
|
137
|
+
queryFn: async () => {
|
|
138
|
+
return projectApi.$member.getById(deviceId);
|
|
139
|
+
},
|
|
140
|
+
});
|
|
135
141
|
return { data, error, isRefetching };
|
|
136
142
|
}
|
|
137
143
|
/**
|
|
@@ -142,15 +148,22 @@ function useSingleMember({ projectId, deviceId, }) {
|
|
|
142
148
|
* @example
|
|
143
149
|
* ```tsx
|
|
144
150
|
* function BasicExample() {
|
|
145
|
-
* const
|
|
151
|
+
* const activeMembers1 = useManyMembers({ projectId: '...' })
|
|
152
|
+
* const activeMembers2 = useManyMembers({ projectId: '...', includeLeft: false })
|
|
146
153
|
*
|
|
147
|
-
*
|
|
154
|
+
* const allMembers = useManyMembers({ projectId: '...', includeLeft: true })
|
|
148
155
|
* }
|
|
149
156
|
* ```
|
|
150
157
|
*/
|
|
151
|
-
function useManyMembers({ projectId }) {
|
|
158
|
+
function useManyMembers({ projectId, includeLeft, }) {
|
|
152
159
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
153
|
-
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)(
|
|
160
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
161
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
162
|
+
queryKey: (0, react_query_js_1.getMembersQueryKey)({ projectId, includeLeft }),
|
|
163
|
+
queryFn: async () => {
|
|
164
|
+
return projectApi.$member.getMany({ includeLeft });
|
|
165
|
+
},
|
|
166
|
+
});
|
|
154
167
|
return { data, error, isRefetching };
|
|
155
168
|
}
|
|
156
169
|
/**
|
|
@@ -256,14 +269,32 @@ function useAttachmentUrl({ projectId, blobId, }) {
|
|
|
256
269
|
const blobUrl = (0, urls_js_1.getBlobUrl)({ serverOrigin, projectId, blobId });
|
|
257
270
|
return { data: blobUrl, error, isRefetching };
|
|
258
271
|
}
|
|
272
|
+
// Used as a placeholder so that we can read the server port from the $blobs.getUrl() method
|
|
273
|
+
const FAKE_BLOB_ID = {
|
|
274
|
+
type: 'photo',
|
|
275
|
+
variant: 'original',
|
|
276
|
+
name: 'name',
|
|
277
|
+
driveId: 'drive-id',
|
|
278
|
+
};
|
|
259
279
|
/**
|
|
260
280
|
* @internal
|
|
261
281
|
* Hack to retrieve the media server origin (protocol + host).
|
|
262
282
|
*/
|
|
263
283
|
function useMediaServerOrigin({ projectApi }) {
|
|
264
|
-
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)(
|
|
265
|
-
|
|
266
|
-
|
|
284
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
285
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
286
|
+
// HACK: The server doesn't yet expose a method to get its origin, so we use
|
|
287
|
+
// the existing $blobs.getUrl() to get the origin with a fake BlobId. The origin
|
|
288
|
+
// is the same regardless of the blobId, so it's not necessary to include it
|
|
289
|
+
// as a dep for the query key.
|
|
290
|
+
queryKey: (0, react_query_js_1.getMediaServerOriginQueryKey)(),
|
|
291
|
+
queryFn: async () => {
|
|
292
|
+
const url = await projectApi.$blobs.getUrl(FAKE_BLOB_ID);
|
|
293
|
+
return new URL(url).origin;
|
|
294
|
+
},
|
|
295
|
+
staleTime: 'static',
|
|
296
|
+
gcTime: Infinity,
|
|
297
|
+
});
|
|
267
298
|
return { data, error, isRefetching };
|
|
268
299
|
}
|
|
269
300
|
// TODO: Eventually remove in favor of this information being provided by the backend when retrieving documents
|
|
@@ -287,7 +318,18 @@ function useMediaServerOrigin({ projectApi }) {
|
|
|
287
318
|
*/
|
|
288
319
|
function useDocumentCreatedBy({ projectId, originalVersionId, }) {
|
|
289
320
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
290
|
-
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)(
|
|
321
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
322
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
323
|
+
queryKey: (0, react_query_js_1.getDocumentCreatedByQueryKey)({
|
|
324
|
+
projectId,
|
|
325
|
+
originalVersionId,
|
|
326
|
+
}),
|
|
327
|
+
queryFn: async () => {
|
|
328
|
+
return projectApi.$originalVersionIdToDeviceId(originalVersionId);
|
|
329
|
+
},
|
|
330
|
+
staleTime: 'static',
|
|
331
|
+
gcTime: Infinity,
|
|
332
|
+
});
|
|
291
333
|
return { data, error, isRefetching };
|
|
292
334
|
}
|
|
293
335
|
/**
|
|
@@ -305,26 +347,50 @@ function useDocumentCreatedBy({ projectId, originalVersionId, }) {
|
|
|
305
347
|
* }
|
|
306
348
|
* ```
|
|
307
349
|
*/
|
|
308
|
-
function useOwnRoleInProject({ projectId }) {
|
|
350
|
+
function useOwnRoleInProject({ projectId, }) {
|
|
309
351
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
310
|
-
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)(
|
|
352
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)({
|
|
353
|
+
...(0, react_query_js_1.baseQueryOptions)(),
|
|
354
|
+
queryKey: (0, react_query_js_1.getProjectRoleQueryKey)({ projectId }),
|
|
355
|
+
queryFn: async () => {
|
|
356
|
+
return projectApi.$getOwnRole();
|
|
357
|
+
},
|
|
358
|
+
});
|
|
311
359
|
return { data, error, isRefetching };
|
|
312
360
|
}
|
|
313
361
|
function useAddServerPeer({ projectId }) {
|
|
314
362
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
315
363
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
364
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
365
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
366
|
+
mutationFn: async ({ baseUrl, dangerouslyAllowInsecureConnections, }) => {
|
|
367
|
+
return projectApi.$member.addServerPeer(baseUrl, {
|
|
368
|
+
dangerouslyAllowInsecureConnections,
|
|
369
|
+
});
|
|
370
|
+
},
|
|
371
|
+
onSuccess: () => {
|
|
372
|
+
queryClient.invalidateQueries({
|
|
373
|
+
queryKey: (0, react_query_js_1.getMembersQueryKey)({ projectId }),
|
|
374
|
+
});
|
|
375
|
+
},
|
|
376
|
+
}));
|
|
320
377
|
}
|
|
321
378
|
function useRemoveServerPeer({ projectId }) {
|
|
322
379
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
323
380
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
381
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
382
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
383
|
+
mutationFn: async ({ serverDeviceId, dangerouslyAllowInsecureConnections, }) => {
|
|
384
|
+
return projectApi.$member.removeServerPeer(serverDeviceId, {
|
|
385
|
+
dangerouslyAllowInsecureConnections,
|
|
386
|
+
});
|
|
387
|
+
},
|
|
388
|
+
onSuccess: () => {
|
|
389
|
+
queryClient.invalidateQueries({
|
|
390
|
+
queryKey: (0, react_query_js_1.getMembersQueryKey)({ projectId }),
|
|
391
|
+
});
|
|
392
|
+
},
|
|
393
|
+
}));
|
|
328
394
|
}
|
|
329
395
|
/**
|
|
330
396
|
* Create a new project.
|
|
@@ -332,10 +398,19 @@ function useRemoveServerPeer({ projectId }) {
|
|
|
332
398
|
function useCreateProject() {
|
|
333
399
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
334
400
|
const clientApi = (0, client_js_1.useClientApi)();
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
401
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
402
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
403
|
+
mutationFn: async (opts) => {
|
|
404
|
+
// Have to avoid passing `undefined` explicitly
|
|
405
|
+
// See https://github.com/digidem/rpc-reflector/issues/21
|
|
406
|
+
return opts ? clientApi.createProject(opts) : clientApi.createProject();
|
|
407
|
+
},
|
|
408
|
+
onSuccess: () => {
|
|
409
|
+
queryClient.invalidateQueries({
|
|
410
|
+
queryKey: (0, react_query_js_1.getProjectsQueryKey)(),
|
|
411
|
+
});
|
|
412
|
+
},
|
|
413
|
+
}));
|
|
339
414
|
}
|
|
340
415
|
/**
|
|
341
416
|
* Leave an existing project.
|
|
@@ -343,10 +418,17 @@ function useCreateProject() {
|
|
|
343
418
|
function useLeaveProject() {
|
|
344
419
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
345
420
|
const clientApi = (0, client_js_1.useClientApi)();
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
421
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
422
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
423
|
+
mutationFn: async ({ projectId }) => {
|
|
424
|
+
return clientApi.leaveProject(projectId);
|
|
425
|
+
},
|
|
426
|
+
onSuccess: () => {
|
|
427
|
+
queryClient.invalidateQueries({
|
|
428
|
+
queryKey: (0, react_query_js_1.getProjectsQueryKey)(),
|
|
429
|
+
});
|
|
430
|
+
},
|
|
431
|
+
}));
|
|
350
432
|
}
|
|
351
433
|
/**
|
|
352
434
|
* Update the categories of a project using an external file.
|
|
@@ -356,14 +438,17 @@ function useLeaveProject() {
|
|
|
356
438
|
function useImportProjectCategories({ projectId, }) {
|
|
357
439
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
358
440
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
441
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
442
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
443
|
+
mutationFn: ({ filePath }) => {
|
|
444
|
+
return projectApi.$importCategories({ filePath });
|
|
445
|
+
},
|
|
446
|
+
onSuccess: () => {
|
|
447
|
+
queryClient.invalidateQueries({
|
|
448
|
+
queryKey: (0, react_query_js_1.getProjectByIdQueryKey)({ projectId }),
|
|
449
|
+
});
|
|
450
|
+
},
|
|
363
451
|
}));
|
|
364
|
-
return status === 'error'
|
|
365
|
-
? { error, mutate, mutateAsync, reset, status }
|
|
366
|
-
: { error: null, mutate, mutateAsync, reset, status };
|
|
367
452
|
}
|
|
368
453
|
/**
|
|
369
454
|
* Update the configuration of a project using an external file.
|
|
@@ -374,23 +459,37 @@ function useImportProjectCategories({ projectId, }) {
|
|
|
374
459
|
function useImportProjectConfig({ projectId }) {
|
|
375
460
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
376
461
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
462
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
463
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
464
|
+
mutationFn: ({ configPath }) => {
|
|
465
|
+
return projectApi.importConfig({ configPath });
|
|
466
|
+
},
|
|
467
|
+
onSuccess: () => {
|
|
468
|
+
queryClient.invalidateQueries({
|
|
469
|
+
queryKey: (0, react_query_js_1.getProjectByIdQueryKey)({ projectId }),
|
|
470
|
+
});
|
|
471
|
+
},
|
|
472
|
+
}));
|
|
381
473
|
}
|
|
382
474
|
/**
|
|
383
475
|
* Update the settings of a project.
|
|
384
476
|
*
|
|
385
477
|
* @param opts.projectId Public ID of the project to apply changes to.
|
|
386
478
|
*/
|
|
387
|
-
function useUpdateProjectSettings({ projectId }) {
|
|
479
|
+
function useUpdateProjectSettings({ projectId, }) {
|
|
388
480
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
389
481
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
482
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
483
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
484
|
+
mutationFn: async (value) => {
|
|
485
|
+
return projectApi.$setProjectSettings(value);
|
|
486
|
+
},
|
|
487
|
+
onSuccess: () => {
|
|
488
|
+
queryClient.invalidateQueries({
|
|
489
|
+
queryKey: (0, react_query_js_1.getProjectsQueryKey)(),
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
}));
|
|
394
493
|
}
|
|
395
494
|
/**
|
|
396
495
|
* Change a project member's role.
|
|
@@ -409,10 +508,20 @@ function useUpdateProjectSettings({ projectId }) {
|
|
|
409
508
|
function useChangeMemberRole({ projectId }) {
|
|
410
509
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
411
510
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
511
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
512
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
513
|
+
mutationFn: async ({ deviceId, roleId, }) => {
|
|
514
|
+
return projectApi.$member.assignRole(deviceId, roleId);
|
|
515
|
+
},
|
|
516
|
+
onSuccess: () => {
|
|
517
|
+
queryClient.invalidateQueries({
|
|
518
|
+
queryKey: (0, react_query_js_1.getMembersQueryKey)({ projectId }),
|
|
519
|
+
});
|
|
520
|
+
queryClient.invalidateQueries({
|
|
521
|
+
queryKey: (0, react_query_js_1.getProjectRoleQueryKey)({ projectId }),
|
|
522
|
+
});
|
|
523
|
+
},
|
|
524
|
+
}));
|
|
416
525
|
}
|
|
417
526
|
/**
|
|
418
527
|
* Remove a member from a project, providing an optional reason for removal.
|
|
@@ -436,48 +545,64 @@ function useChangeMemberRole({ projectId }) {
|
|
|
436
545
|
function useRemoveMember({ projectId }) {
|
|
437
546
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
438
547
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
548
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
549
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
550
|
+
mutationFn: async ({ deviceId, reason, }) => {
|
|
551
|
+
// Have to avoid passing `undefined` explicitly
|
|
552
|
+
// See https://github.com/digidem/rpc-reflector/issues/21
|
|
553
|
+
return reason
|
|
554
|
+
? projectApi.$member.remove(deviceId, { reason })
|
|
555
|
+
: projectApi.$member.remove(deviceId);
|
|
556
|
+
},
|
|
557
|
+
onSuccess: () => {
|
|
558
|
+
queryClient.invalidateQueries({
|
|
559
|
+
queryKey: (0, react_query_js_1.getMembersQueryKey)({ projectId }),
|
|
560
|
+
});
|
|
561
|
+
},
|
|
562
|
+
}));
|
|
443
563
|
}
|
|
444
564
|
/**
|
|
445
565
|
* Set up listener for changes to your own role in a project.
|
|
446
566
|
* It is necessary to use this if you want the project role-related read hooks to update
|
|
447
567
|
* based on role change events that are received in the background.
|
|
448
568
|
*
|
|
449
|
-
*
|
|
569
|
+
*
|
|
450
570
|
*
|
|
451
571
|
* @example
|
|
452
572
|
* ```tsx
|
|
453
|
-
* function
|
|
573
|
+
* function ListenerComponent({ projectId }: { projectId: string }) {
|
|
574
|
+
* // Set up the listener
|
|
454
575
|
* useProjectOwnRoleChangeListener({ projectId })
|
|
455
576
|
* }
|
|
456
|
-
* ```
|
|
457
577
|
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
* console.log('New role:', event.role)
|
|
578
|
+
* // Handle role change events separately
|
|
579
|
+
* function EventHandlerComponent() {
|
|
580
|
+
* const { data: projectApi } = useSingleProject({ projectId })
|
|
581
|
+
*
|
|
582
|
+
* useEffect(() => {
|
|
583
|
+
* function handleRoleChangeEvent(event) {
|
|
584
|
+
* // Do something with event...
|
|
466
585
|
* }
|
|
467
|
-
*
|
|
586
|
+
*
|
|
587
|
+
* projectApi.addListener('own-role-change', handleRoleChangeEvent)
|
|
588
|
+
*
|
|
589
|
+
* return () => {
|
|
590
|
+
* projectApi.removeListener('own-role-change', handleRoleChangeEvent)
|
|
591
|
+
* }
|
|
592
|
+
* }, [projectApi])
|
|
468
593
|
* }
|
|
469
594
|
* ```
|
|
470
595
|
*/
|
|
471
|
-
function useProjectOwnRoleChangeListener({ projectId,
|
|
596
|
+
function useProjectOwnRoleChangeListener({ projectId, }) {
|
|
472
597
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
473
598
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
474
599
|
(0, react_1.useEffect)(() => {
|
|
475
600
|
function invalidateCache() {
|
|
476
601
|
queryClient.invalidateQueries({
|
|
477
|
-
queryKey: (0,
|
|
602
|
+
queryKey: (0, react_query_js_1.getMembersQueryKey)({ projectId }),
|
|
478
603
|
});
|
|
479
604
|
queryClient.invalidateQueries({
|
|
480
|
-
queryKey: (0,
|
|
605
|
+
queryKey: (0, react_query_js_1.getProjectRoleQueryKey)({ projectId }),
|
|
481
606
|
});
|
|
482
607
|
}
|
|
483
608
|
projectApi.addListener('own-role-change', invalidateCache);
|
|
@@ -485,16 +610,6 @@ function useProjectOwnRoleChangeListener({ projectId, listener, }) {
|
|
|
485
610
|
projectApi.removeListener('own-role-change', invalidateCache);
|
|
486
611
|
};
|
|
487
612
|
}, [projectApi, queryClient, projectId]);
|
|
488
|
-
(0, react_1.useEffect)(() => {
|
|
489
|
-
if (listener) {
|
|
490
|
-
projectApi.addListener('own-role-change', listener);
|
|
491
|
-
}
|
|
492
|
-
return () => {
|
|
493
|
-
if (listener) {
|
|
494
|
-
projectApi.removeListener('own-role-change', listener);
|
|
495
|
-
}
|
|
496
|
-
};
|
|
497
|
-
}, [projectApi, listener]);
|
|
498
613
|
}
|
|
499
614
|
/**
|
|
500
615
|
* Create a blob for a project.
|
|
@@ -503,10 +618,12 @@ function useProjectOwnRoleChangeListener({ projectId, listener, }) {
|
|
|
503
618
|
*/
|
|
504
619
|
function useCreateBlob({ projectId }) {
|
|
505
620
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
621
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
622
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
623
|
+
mutationFn: async ({ original, preview, thumbnail, metadata, }) => {
|
|
624
|
+
return projectApi.$blobs.create({ original, preview, thumbnail }, metadata);
|
|
625
|
+
},
|
|
626
|
+
}));
|
|
510
627
|
}
|
|
511
628
|
const PROJECT_SYNC_STORE_MAP = new WeakMap();
|
|
512
629
|
function useSyncStore({ projectId }) {
|
|
@@ -556,38 +673,50 @@ function useDataSyncProgress({ projectId, }) {
|
|
|
556
673
|
}
|
|
557
674
|
function useStartSync({ projectId }) {
|
|
558
675
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
676
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
677
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
678
|
+
mutationFn: async (opts) => {
|
|
679
|
+
// Have to avoid passing `undefined` explicitly
|
|
680
|
+
// See https://github.com/digidem/rpc-reflector/issues/21
|
|
681
|
+
return opts ? projectApi.$sync.start(opts) : projectApi.$sync.start();
|
|
682
|
+
},
|
|
683
|
+
}));
|
|
563
684
|
}
|
|
564
685
|
function useStopSync({ projectId }) {
|
|
565
686
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
687
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
688
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
689
|
+
mutationFn: async () => {
|
|
690
|
+
return projectApi.$sync.stop();
|
|
691
|
+
},
|
|
692
|
+
}));
|
|
570
693
|
}
|
|
571
694
|
function useConnectSyncServers({ projectId }) {
|
|
572
695
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
696
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
697
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
698
|
+
mutationFn: async () => {
|
|
699
|
+
return projectApi.$sync.connectServers();
|
|
700
|
+
},
|
|
701
|
+
}));
|
|
577
702
|
}
|
|
578
703
|
function useDisconnectSyncServers({ projectId }) {
|
|
579
704
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
705
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
706
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
707
|
+
mutationFn: async () => {
|
|
708
|
+
return projectApi.$sync.disconnectServers();
|
|
709
|
+
},
|
|
710
|
+
}));
|
|
584
711
|
}
|
|
585
712
|
function useSetAutostopDataSyncTimeout({ projectId, }) {
|
|
586
713
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
714
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
715
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
716
|
+
mutationFn: async ({ after }) => {
|
|
717
|
+
return projectApi.$sync.setAutostopDataSyncTimeout(after);
|
|
718
|
+
},
|
|
719
|
+
}));
|
|
591
720
|
}
|
|
592
721
|
/**
|
|
593
722
|
* Creates a GeoJson file with all the observations and/or tracks in the project.
|
|
@@ -596,10 +725,12 @@ function useSetAutostopDataSyncTimeout({ projectId, }) {
|
|
|
596
725
|
*/
|
|
597
726
|
function useExportGeoJSON({ projectId }) {
|
|
598
727
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
728
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
729
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
730
|
+
mutationFn: async (opts) => {
|
|
731
|
+
return projectApi.exportGeoJSONFile(opts.path, opts.exportOptions);
|
|
732
|
+
},
|
|
733
|
+
}));
|
|
603
734
|
}
|
|
604
735
|
/**
|
|
605
736
|
* Creates a zip file containing a GeoJson file with all the observations and/or tracks in the project and all associated attachments (photos and audio).
|
|
@@ -608,8 +739,10 @@ function useExportGeoJSON({ projectId }) {
|
|
|
608
739
|
*/
|
|
609
740
|
function useExportZipFile({ projectId }) {
|
|
610
741
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
742
|
+
return (0, react_query_js_1.filterMutationResult)((0, react_query_1.useMutation)({
|
|
743
|
+
...(0, react_query_js_1.baseMutationOptions)(),
|
|
744
|
+
mutationFn: async (opts) => {
|
|
745
|
+
return projectApi.exportZipFile(opts.path, opts.exportOptions);
|
|
746
|
+
},
|
|
747
|
+
}));
|
|
615
748
|
}
|
package/dist/commonjs/index.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export { useMapStyleUrl, useImportCustomMapFile, useRemoveCustomMapFile, useGetC
|
|
|
6
6
|
export type { SentMapShareState, ReceivedMapShareState, AbortMapShareOptions, CancelMapShareOptions, DeclineMapShareOptions, DownloadMapShareOptions, CreateAndSendMapShareOptions, } from './lib/map-shares-stores.js';
|
|
7
7
|
export { DeclineReason } from './lib/map-shares-stores.js';
|
|
8
8
|
export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectCategories, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectOwnRoleChangeListener, useProjectSettings, useRemoveServerPeer, useRemoveMember, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useChangeMemberRole, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
9
|
+
export type { SyncState } from './lib/sync.js';
|
|
10
|
+
export type { WriteableDocument, WriteableDocumentType, WriteableValue, } from './lib/types.js';
|
|
11
11
|
export { HTTPError, isHTTPError } from './lib/http.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MapShare } from '@comapeo/core';
|
|
2
2
|
import type { MapeoClientApi } from '@comapeo/ipc';
|
|
3
3
|
import { type MapShareState as ServerMapShareState } from '@comapeo/map-server';
|
|
4
|
-
import {
|
|
4
|
+
import type { QueryClient } from '@tanstack/react-query';
|
|
5
5
|
import type { Simplify } from 'type-fest';
|
|
6
6
|
import type { MapServerApi } from '../contexts/MapServer.js';
|
|
7
7
|
type DistributedIntersection<T, U> = U extends unknown ? Simplify<T & U> : never;
|
|
@@ -9,7 +9,7 @@ exports.createSentMapSharesStore = createSentMapSharesStore;
|
|
|
9
9
|
const constants_js_1 = require("@comapeo/map-server/constants.js");
|
|
10
10
|
const errors_js_1 = require("@comapeo/map-server/errors.js");
|
|
11
11
|
const ensure_error_1 = __importDefault(require("ensure-error"));
|
|
12
|
-
const
|
|
12
|
+
const react_query_js_1 = require("./react-query.js");
|
|
13
13
|
// ============================================
|
|
14
14
|
// ACTION OPTIONS TYPES
|
|
15
15
|
// These are defined here so that VSCode tooltips work for the mutation
|
|
@@ -169,7 +169,7 @@ function createReceivedMapSharesStore({ clientApi, mapServerApi, queryClient, })
|
|
|
169
169
|
downloads.delete(shareId);
|
|
170
170
|
// Invalidate map queries when download completes to trigger reload of map
|
|
171
171
|
if (stateUpdate.status === 'completed') {
|
|
172
|
-
return (0,
|
|
172
|
+
return (0, react_query_js_1.invalidateMapQueries)(queryClient, {
|
|
173
173
|
mapId: mapShare.mapId,
|
|
174
174
|
});
|
|
175
175
|
}
|