@comapeo/core-react 2.0.1 → 3.1.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/dist/commonjs/contexts/ClientApi.d.ts +5 -5
- package/dist/commonjs/contexts/ClientApi.js +3 -3
- package/dist/commonjs/hooks/documents.d.ts +6 -6
- package/dist/commonjs/hooks/projects.d.ts +72 -0
- package/dist/commonjs/hooks/projects.js +83 -0
- package/dist/commonjs/index.d.ts +3 -7
- package/dist/commonjs/index.js +6 -29
- package/dist/commonjs/lib/react-query/documents.d.ts +1 -8
- package/dist/commonjs/lib/react-query/projects.d.ts +16 -0
- package/dist/commonjs/lib/react-query/projects.js +20 -0
- package/dist/commonjs/lib/sync.d.ts +10 -0
- package/dist/commonjs/lib/sync.js +119 -0
- package/dist/commonjs/lib/types.d.ts +9 -0
- package/dist/commonjs/lib/types.js +2 -0
- package/dist/esm/contexts/ClientApi.d.ts +5 -5
- package/dist/esm/contexts/ClientApi.js +3 -3
- package/dist/esm/hooks/documents.d.ts +6 -6
- package/dist/esm/hooks/projects.d.ts +72 -0
- package/dist/esm/hooks/projects.js +79 -1
- package/dist/esm/index.d.ts +3 -7
- package/dist/esm/index.js +1 -7
- package/dist/esm/lib/react-query/documents.d.ts +1 -8
- package/dist/esm/lib/react-query/projects.d.ts +16 -0
- package/dist/esm/lib/react-query/projects.js +18 -0
- package/dist/esm/lib/sync.d.ts +10 -0
- package/dist/esm/lib/sync.js +114 -0
- package/dist/esm/lib/types.d.ts +9 -0
- package/dist/esm/lib/types.js +1 -0
- package/docs/API.md +109 -2
- package/package.json +25 -29
- package/CHANGELOG.md +0 -23
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { MapeoClientApi } from '@comapeo/ipc' with { 'resolution-mode': 'import' };
|
|
2
|
-
import { type ReactNode } from 'react';
|
|
2
|
+
import { type JSX, type ReactNode } from 'react';
|
|
3
3
|
export declare const ClientApiContext: import("react").Context<import("@comapeo/ipc/dist/client.js", { with: { "resolution-mode": "import" } }).MapeoClientApi | null>;
|
|
4
4
|
/**
|
|
5
5
|
* Create a context provider that holds a CoMapeo API client instance.
|
|
6
6
|
*
|
|
7
|
-
* @param opts
|
|
8
|
-
* @param
|
|
9
|
-
*
|
|
7
|
+
* @param opts.children React children node
|
|
8
|
+
* @param opts.clientApi Client API instance
|
|
9
|
+
*
|
|
10
10
|
*/
|
|
11
11
|
export declare function ClientApiProvider({ children, clientApi, }: {
|
|
12
12
|
children: ReactNode;
|
|
13
13
|
clientApi: MapeoClientApi;
|
|
14
|
-
}):
|
|
14
|
+
}): JSX.Element;
|
|
@@ -7,9 +7,9 @@ exports.ClientApiContext = (0, react_1.createContext)(null);
|
|
|
7
7
|
/**
|
|
8
8
|
* Create a context provider that holds a CoMapeo API client instance.
|
|
9
9
|
*
|
|
10
|
-
* @param opts
|
|
11
|
-
* @param
|
|
12
|
-
*
|
|
10
|
+
* @param opts.children React children node
|
|
11
|
+
* @param opts.clientApi Client API instance
|
|
12
|
+
*
|
|
13
13
|
*/
|
|
14
14
|
function ClientApiProvider({ children, clientApi, }) {
|
|
15
15
|
return (0, react_1.createElement)(exports.ClientApiContext.Provider, { value: clientApi }, children);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MapeoDoc } from '@comapeo/schema' with { 'resolution-mode': 'import' };
|
|
2
|
-
import {
|
|
2
|
+
import type { WriteableDocumentType } from '../lib/types.js';
|
|
3
3
|
type ReadHookResult<D> = {
|
|
4
4
|
data: D;
|
|
5
5
|
error: Error | null;
|
|
@@ -119,10 +119,10 @@ export declare function useCreateDocument<D extends WriteableDocumentType>({ doc
|
|
|
119
119
|
docType: D;
|
|
120
120
|
projectId: string;
|
|
121
121
|
}): {
|
|
122
|
-
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/
|
|
122
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/types.js").WriteableDocument<D> & {
|
|
123
123
|
forks: Array<string>;
|
|
124
124
|
}, Error, {
|
|
125
|
-
value: Omit<import("../lib/
|
|
125
|
+
value: Omit<import("../lib/types.js").WriteableValue<D>, "schemaName">;
|
|
126
126
|
}, unknown>;
|
|
127
127
|
reset: () => void;
|
|
128
128
|
status: "pending" | "error" | "success" | "idle";
|
|
@@ -137,11 +137,11 @@ export declare function useUpdateDocument<D extends WriteableDocumentType>({ doc
|
|
|
137
137
|
docType: D;
|
|
138
138
|
projectId: string;
|
|
139
139
|
}): {
|
|
140
|
-
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/
|
|
140
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/types.js").WriteableDocument<D> & {
|
|
141
141
|
forks: Array<string>;
|
|
142
142
|
}, Error, {
|
|
143
143
|
versionId: string;
|
|
144
|
-
value: Omit<import("../lib/
|
|
144
|
+
value: Omit<import("../lib/types.js").WriteableValue<D>, "schemaName">;
|
|
145
145
|
}, unknown>;
|
|
146
146
|
reset: () => void;
|
|
147
147
|
status: "pending" | "error" | "success" | "idle";
|
|
@@ -156,7 +156,7 @@ export declare function useDeleteDocument<D extends WriteableDocumentType>({ doc
|
|
|
156
156
|
docType: D;
|
|
157
157
|
projectId: string;
|
|
158
158
|
}): {
|
|
159
|
-
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/
|
|
159
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/types.js").WriteableDocument<D> & {
|
|
160
160
|
forks: Array<string>;
|
|
161
161
|
}, Error, {
|
|
162
162
|
docId: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BitmapOpts, SvgOpts } from '@comapeo/core/dist/icon-api.js' with { 'resolution-mode': 'import' };
|
|
2
2
|
import type { BlobId } from '@comapeo/core/dist/types.js' with { 'resolution-mode': 'import' };
|
|
3
|
+
import { type SyncState } from '../lib/sync.js';
|
|
3
4
|
/**
|
|
4
5
|
* Retrieve the project settings for a project.
|
|
5
6
|
*
|
|
@@ -249,6 +250,28 @@ export declare function useDocumentCreatedBy({ projectId, originalVersionId, }:
|
|
|
249
250
|
error: Error | null;
|
|
250
251
|
isRefetching: boolean;
|
|
251
252
|
};
|
|
253
|
+
/**
|
|
254
|
+
* Get the role for the current device in a specified project.
|
|
255
|
+
* This is a more convenient alternative to using the `useOwnDeviceInfo` and `useManyMembers` hooks.
|
|
256
|
+
*
|
|
257
|
+
* @param opts.projectId Project public ID
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```tsx
|
|
261
|
+
* function BasicExample() {
|
|
262
|
+
* const { data } = useOwnRoleInProject({
|
|
263
|
+
* projectId: '...',
|
|
264
|
+
* })
|
|
265
|
+
* }
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
export declare function useOwnRoleInProject({ projectId }: {
|
|
269
|
+
projectId: string;
|
|
270
|
+
}): {
|
|
271
|
+
data: import("@comapeo/core/dist/roles.js", { with: { "resolution-mode": "import" } }).Role<"a12a6702b93bd7ff" | "f7c150f5a3a9a855" | "012fd2d431c0bf60" | "9e6d29263cba36c9" | "8ced989b1904606b" | "08e4251e36f6e7ed">;
|
|
272
|
+
error: Error | null;
|
|
273
|
+
isRefetching: boolean;
|
|
274
|
+
};
|
|
252
275
|
export declare function useAddServerPeer({ projectId }: {
|
|
253
276
|
projectId: string;
|
|
254
277
|
}): {
|
|
@@ -332,3 +355,52 @@ export declare function useCreateBlob({ projectId }: {
|
|
|
332
355
|
reset: () => void;
|
|
333
356
|
status: "pending" | "error" | "success" | "idle";
|
|
334
357
|
};
|
|
358
|
+
/**
|
|
359
|
+
* Hook to subscribe to the current sync state.
|
|
360
|
+
*
|
|
361
|
+
* Creates a global singleton for each project, to minimize traffic over IPC -
|
|
362
|
+
* this hook can safely be used in more than one place without attaching
|
|
363
|
+
* additional listeners across the IPC channel.
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```ts
|
|
367
|
+
* function Example() {
|
|
368
|
+
* const syncState = useSyncState({ projectId });
|
|
369
|
+
*
|
|
370
|
+
* if (!syncState) {
|
|
371
|
+
* // Sync information hasn't been loaded yet
|
|
372
|
+
* }
|
|
373
|
+
*
|
|
374
|
+
* // Actual info about sync state is available...
|
|
375
|
+
* }
|
|
376
|
+
* ```
|
|
377
|
+
*
|
|
378
|
+
* @param opts.projectId Project public ID
|
|
379
|
+
*/
|
|
380
|
+
export declare function useSyncState({ projectId, }: {
|
|
381
|
+
projectId: string;
|
|
382
|
+
}): SyncState | null;
|
|
383
|
+
/**
|
|
384
|
+
* Provides the progress of data sync for sync-enabled connected peers
|
|
385
|
+
*
|
|
386
|
+
* @returns `null` if no sync state events have been received. Otherwise returns a value between 0 and 1 (inclusive)
|
|
387
|
+
*/
|
|
388
|
+
export declare function useDataSyncProgress({ projectId, }: {
|
|
389
|
+
projectId: string;
|
|
390
|
+
}): number | null;
|
|
391
|
+
export declare function useStartSync({ projectId }: {
|
|
392
|
+
projectId: string;
|
|
393
|
+
}): {
|
|
394
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<void, Error, {
|
|
395
|
+
autostopDataSyncAfter: number | null;
|
|
396
|
+
} | undefined, unknown>;
|
|
397
|
+
reset: () => void;
|
|
398
|
+
status: "pending" | "error" | "success" | "idle";
|
|
399
|
+
};
|
|
400
|
+
export declare function useStopSync({ projectId }: {
|
|
401
|
+
projectId: string;
|
|
402
|
+
}): {
|
|
403
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<void, Error, void, unknown>;
|
|
404
|
+
reset: () => void;
|
|
405
|
+
status: "pending" | "error" | "success" | "idle";
|
|
406
|
+
};
|
|
@@ -8,14 +8,21 @@ exports.useManyMembers = useManyMembers;
|
|
|
8
8
|
exports.useIconUrl = useIconUrl;
|
|
9
9
|
exports.useAttachmentUrl = useAttachmentUrl;
|
|
10
10
|
exports.useDocumentCreatedBy = useDocumentCreatedBy;
|
|
11
|
+
exports.useOwnRoleInProject = useOwnRoleInProject;
|
|
11
12
|
exports.useAddServerPeer = useAddServerPeer;
|
|
12
13
|
exports.useCreateProject = useCreateProject;
|
|
13
14
|
exports.useLeaveProject = useLeaveProject;
|
|
14
15
|
exports.useImportProjectConfig = useImportProjectConfig;
|
|
15
16
|
exports.useUpdateProjectSettings = useUpdateProjectSettings;
|
|
16
17
|
exports.useCreateBlob = useCreateBlob;
|
|
18
|
+
exports.useSyncState = useSyncState;
|
|
19
|
+
exports.useDataSyncProgress = useDataSyncProgress;
|
|
20
|
+
exports.useStartSync = useStartSync;
|
|
21
|
+
exports.useStopSync = useStopSync;
|
|
17
22
|
const react_query_1 = require("@tanstack/react-query");
|
|
23
|
+
const react_1 = require("react");
|
|
18
24
|
const projects_js_1 = require("../lib/react-query/projects.js");
|
|
25
|
+
const sync_js_1 = require("../lib/sync.js");
|
|
19
26
|
const client_js_1 = require("./client.js");
|
|
20
27
|
/**
|
|
21
28
|
* Retrieve the project settings for a project.
|
|
@@ -262,6 +269,26 @@ function useDocumentCreatedBy({ projectId, originalVersionId, }) {
|
|
|
262
269
|
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)((0, projects_js_1.documentCreatedByQueryOptions)({ projectApi, projectId, originalVersionId }));
|
|
263
270
|
return { data, error, isRefetching };
|
|
264
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Get the role for the current device in a specified project.
|
|
274
|
+
* This is a more convenient alternative to using the `useOwnDeviceInfo` and `useManyMembers` hooks.
|
|
275
|
+
*
|
|
276
|
+
* @param opts.projectId Project public ID
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```tsx
|
|
280
|
+
* function BasicExample() {
|
|
281
|
+
* const { data } = useOwnRoleInProject({
|
|
282
|
+
* projectId: '...',
|
|
283
|
+
* })
|
|
284
|
+
* }
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
function useOwnRoleInProject({ projectId }) {
|
|
288
|
+
const { data: projectApi } = useSingleProject({ projectId });
|
|
289
|
+
const { data, error, isRefetching } = (0, react_query_1.useSuspenseQuery)((0, projects_js_1.projectOwnRoleQueryOptions)({ projectApi, projectId }));
|
|
290
|
+
return { data, error, isRefetching };
|
|
291
|
+
}
|
|
265
292
|
function useAddServerPeer({ projectId }) {
|
|
266
293
|
const queryClient = (0, react_query_1.useQueryClient)();
|
|
267
294
|
const { data: projectApi } = useSingleProject({ projectId });
|
|
@@ -318,3 +345,59 @@ function useCreateBlob({ projectId }) {
|
|
|
318
345
|
const { mutate, reset, status } = (0, react_query_1.useMutation)((0, projects_js_1.createBlobMutationOptions)({ projectApi }));
|
|
319
346
|
return { mutate, reset, status };
|
|
320
347
|
}
|
|
348
|
+
const PROJECT_SYNC_STORE_MAP = new WeakMap();
|
|
349
|
+
function useSyncStore({ projectId }) {
|
|
350
|
+
const { data: projectApi } = useSingleProject({ projectId });
|
|
351
|
+
let syncStore = PROJECT_SYNC_STORE_MAP.get(projectApi);
|
|
352
|
+
if (!syncStore) {
|
|
353
|
+
syncStore = new sync_js_1.SyncStore(projectApi);
|
|
354
|
+
PROJECT_SYNC_STORE_MAP.set(projectApi, syncStore);
|
|
355
|
+
}
|
|
356
|
+
return syncStore;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Hook to subscribe to the current sync state.
|
|
360
|
+
*
|
|
361
|
+
* Creates a global singleton for each project, to minimize traffic over IPC -
|
|
362
|
+
* this hook can safely be used in more than one place without attaching
|
|
363
|
+
* additional listeners across the IPC channel.
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```ts
|
|
367
|
+
* function Example() {
|
|
368
|
+
* const syncState = useSyncState({ projectId });
|
|
369
|
+
*
|
|
370
|
+
* if (!syncState) {
|
|
371
|
+
* // Sync information hasn't been loaded yet
|
|
372
|
+
* }
|
|
373
|
+
*
|
|
374
|
+
* // Actual info about sync state is available...
|
|
375
|
+
* }
|
|
376
|
+
* ```
|
|
377
|
+
*
|
|
378
|
+
* @param opts.projectId Project public ID
|
|
379
|
+
*/
|
|
380
|
+
function useSyncState({ projectId, }) {
|
|
381
|
+
const syncStore = useSyncStore({ projectId });
|
|
382
|
+
const { subscribe, getStateSnapshot } = syncStore;
|
|
383
|
+
return (0, react_1.useSyncExternalStore)(subscribe, getStateSnapshot);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Provides the progress of data sync for sync-enabled connected peers
|
|
387
|
+
*
|
|
388
|
+
* @returns `null` if no sync state events have been received. Otherwise returns a value between 0 and 1 (inclusive)
|
|
389
|
+
*/
|
|
390
|
+
function useDataSyncProgress({ projectId, }) {
|
|
391
|
+
const { subscribe, getDataProgressSnapshot } = useSyncStore({ projectId });
|
|
392
|
+
return (0, react_1.useSyncExternalStore)(subscribe, getDataProgressSnapshot);
|
|
393
|
+
}
|
|
394
|
+
function useStartSync({ projectId }) {
|
|
395
|
+
const { data: projectApi } = useSingleProject({ projectId });
|
|
396
|
+
const { mutate, reset, status } = (0, react_query_1.useMutation)((0, projects_js_1.startSyncMutationOptions)({ projectApi }));
|
|
397
|
+
return { mutate, reset, status };
|
|
398
|
+
}
|
|
399
|
+
function useStopSync({ projectId }) {
|
|
400
|
+
const { data: projectApi } = useSingleProject({ projectId });
|
|
401
|
+
const { mutate, reset, status } = (0, react_query_1.useMutation)((0, projects_js_1.stopSyncMutationOptions)({ projectApi }));
|
|
402
|
+
return { mutate, reset, status };
|
|
403
|
+
}
|
package/dist/commonjs/index.d.ts
CHANGED
|
@@ -3,10 +3,6 @@ export { useClientApi, useIsArchiveDevice, useOwnDeviceInfo, useSetIsArchiveDevi
|
|
|
3
3
|
export { useCreateDocument, useDeleteDocument, useManyDocs, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
|
|
4
4
|
export { useAcceptInvite, useRejectInvite, useRequestCancelInvite, useSendInvite, } from './hooks/invites.js';
|
|
5
5
|
export { useMapStyleUrl } from './hooks/maps.js';
|
|
6
|
-
export { useAddServerPeer, useAttachmentUrl, useCreateBlob, useCreateProject, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useProjectSettings, useSingleMember, useSingleProject, useUpdateProjectSettings, } from './hooks/projects.js';
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
9
|
-
export { getInvitesQueryKey, getPendingInvitesQueryKey, } from './lib/react-query/invites.js';
|
|
10
|
-
export { getMapsQueryKey, getStyleJsonUrlQueryKey, } from './lib/react-query/maps.js';
|
|
11
|
-
export { getAttachmentUrlQueryKey, getDocumentCreatedByQueryKey, getIconUrlQueryKey, getMemberByIdQueryKey, getMembersQueryKey, getProjectByIdQueryKey, getProjectRoleQueryKey, getProjectSettingsQueryKey, getProjectsQueryKey, } from './lib/react-query/projects.js';
|
|
12
|
-
export { ROOT_QUERY_KEY } from './lib/react-query/shared.js';
|
|
6
|
+
export { useAddServerPeer, useAttachmentUrl, useCreateBlob, useCreateProject, useDataSyncProgress, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, } from './hooks/projects.js';
|
|
7
|
+
export { type SyncState } from './lib/sync.js';
|
|
8
|
+
export { type WriteableDocument, type WriteableDocumentType, type WriteableValue, } from './lib/types.js';
|
package/dist/commonjs/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.ROOT_QUERY_KEY = exports.getProjectsQueryKey = exports.getProjectSettingsQueryKey = void 0;
|
|
3
|
+
exports.useUpdateProjectSettings = exports.useSyncState = exports.useStopSync = exports.useStartSync = exports.useSingleProject = exports.useSingleMember = exports.useProjectSettings = exports.useOwnRoleInProject = exports.useManyProjects = exports.useManyMembers = exports.useLeaveProject = exports.useImportProjectConfig = exports.useIconUrl = exports.useDocumentCreatedBy = exports.useDataSyncProgress = exports.useCreateProject = exports.useCreateBlob = exports.useAttachmentUrl = exports.useAddServerPeer = exports.useMapStyleUrl = exports.useSendInvite = exports.useRequestCancelInvite = exports.useRejectInvite = exports.useAcceptInvite = exports.useUpdateDocument = exports.useSingleDocByVersionId = exports.useSingleDocByDocId = exports.useManyDocs = exports.useDeleteDocument = exports.useCreateDocument = exports.useSetOwnDeviceInfo = exports.useSetIsArchiveDevice = exports.useOwnDeviceInfo = exports.useIsArchiveDevice = exports.useClientApi = exports.ClientApiProvider = exports.ClientApiContext = void 0;
|
|
5
4
|
var ClientApi_js_1 = require("./contexts/ClientApi.js");
|
|
6
5
|
Object.defineProperty(exports, "ClientApiContext", { enumerable: true, get: function () { return ClientApi_js_1.ClientApiContext; } });
|
|
7
6
|
Object.defineProperty(exports, "ClientApiProvider", { enumerable: true, get: function () { return ClientApi_js_1.ClientApiProvider; } });
|
|
@@ -30,40 +29,18 @@ Object.defineProperty(exports, "useAddServerPeer", { enumerable: true, get: func
|
|
|
30
29
|
Object.defineProperty(exports, "useAttachmentUrl", { enumerable: true, get: function () { return projects_js_1.useAttachmentUrl; } });
|
|
31
30
|
Object.defineProperty(exports, "useCreateBlob", { enumerable: true, get: function () { return projects_js_1.useCreateBlob; } });
|
|
32
31
|
Object.defineProperty(exports, "useCreateProject", { enumerable: true, get: function () { return projects_js_1.useCreateProject; } });
|
|
32
|
+
Object.defineProperty(exports, "useDataSyncProgress", { enumerable: true, get: function () { return projects_js_1.useDataSyncProgress; } });
|
|
33
33
|
Object.defineProperty(exports, "useDocumentCreatedBy", { enumerable: true, get: function () { return projects_js_1.useDocumentCreatedBy; } });
|
|
34
34
|
Object.defineProperty(exports, "useIconUrl", { enumerable: true, get: function () { return projects_js_1.useIconUrl; } });
|
|
35
35
|
Object.defineProperty(exports, "useImportProjectConfig", { enumerable: true, get: function () { return projects_js_1.useImportProjectConfig; } });
|
|
36
36
|
Object.defineProperty(exports, "useLeaveProject", { enumerable: true, get: function () { return projects_js_1.useLeaveProject; } });
|
|
37
37
|
Object.defineProperty(exports, "useManyMembers", { enumerable: true, get: function () { return projects_js_1.useManyMembers; } });
|
|
38
38
|
Object.defineProperty(exports, "useManyProjects", { enumerable: true, get: function () { return projects_js_1.useManyProjects; } });
|
|
39
|
+
Object.defineProperty(exports, "useOwnRoleInProject", { enumerable: true, get: function () { return projects_js_1.useOwnRoleInProject; } });
|
|
39
40
|
Object.defineProperty(exports, "useProjectSettings", { enumerable: true, get: function () { return projects_js_1.useProjectSettings; } });
|
|
40
41
|
Object.defineProperty(exports, "useSingleMember", { enumerable: true, get: function () { return projects_js_1.useSingleMember; } });
|
|
41
42
|
Object.defineProperty(exports, "useSingleProject", { enumerable: true, get: function () { return projects_js_1.useSingleProject; } });
|
|
43
|
+
Object.defineProperty(exports, "useStartSync", { enumerable: true, get: function () { return projects_js_1.useStartSync; } });
|
|
44
|
+
Object.defineProperty(exports, "useStopSync", { enumerable: true, get: function () { return projects_js_1.useStopSync; } });
|
|
45
|
+
Object.defineProperty(exports, "useSyncState", { enumerable: true, get: function () { return projects_js_1.useSyncState; } });
|
|
42
46
|
Object.defineProperty(exports, "useUpdateProjectSettings", { enumerable: true, get: function () { return projects_js_1.useUpdateProjectSettings; } });
|
|
43
|
-
var client_js_2 = require("./lib/react-query/client.js");
|
|
44
|
-
Object.defineProperty(exports, "getClientQueryKey", { enumerable: true, get: function () { return client_js_2.getClientQueryKey; } });
|
|
45
|
-
Object.defineProperty(exports, "getDeviceInfoQueryKey", { enumerable: true, get: function () { return client_js_2.getDeviceInfoQueryKey; } });
|
|
46
|
-
Object.defineProperty(exports, "getIsArchiveDeviceQueryKey", { enumerable: true, get: function () { return client_js_2.getIsArchiveDeviceQueryKey; } });
|
|
47
|
-
var documents_js_2 = require("./lib/react-query/documents.js");
|
|
48
|
-
Object.defineProperty(exports, "getDocumentByDocIdQueryKey", { enumerable: true, get: function () { return documents_js_2.getDocumentByDocIdQueryKey; } });
|
|
49
|
-
Object.defineProperty(exports, "getDocumentByVersionIdQueryKey", { enumerable: true, get: function () { return documents_js_2.getDocumentByVersionIdQueryKey; } });
|
|
50
|
-
Object.defineProperty(exports, "getDocumentsQueryKey", { enumerable: true, get: function () { return documents_js_2.getDocumentsQueryKey; } });
|
|
51
|
-
Object.defineProperty(exports, "getManyDocumentsQueryKey", { enumerable: true, get: function () { return documents_js_2.getManyDocumentsQueryKey; } });
|
|
52
|
-
var invites_js_2 = require("./lib/react-query/invites.js");
|
|
53
|
-
Object.defineProperty(exports, "getInvitesQueryKey", { enumerable: true, get: function () { return invites_js_2.getInvitesQueryKey; } });
|
|
54
|
-
Object.defineProperty(exports, "getPendingInvitesQueryKey", { enumerable: true, get: function () { return invites_js_2.getPendingInvitesQueryKey; } });
|
|
55
|
-
var maps_js_2 = require("./lib/react-query/maps.js");
|
|
56
|
-
Object.defineProperty(exports, "getMapsQueryKey", { enumerable: true, get: function () { return maps_js_2.getMapsQueryKey; } });
|
|
57
|
-
Object.defineProperty(exports, "getStyleJsonUrlQueryKey", { enumerable: true, get: function () { return maps_js_2.getStyleJsonUrlQueryKey; } });
|
|
58
|
-
var projects_js_2 = require("./lib/react-query/projects.js");
|
|
59
|
-
Object.defineProperty(exports, "getAttachmentUrlQueryKey", { enumerable: true, get: function () { return projects_js_2.getAttachmentUrlQueryKey; } });
|
|
60
|
-
Object.defineProperty(exports, "getDocumentCreatedByQueryKey", { enumerable: true, get: function () { return projects_js_2.getDocumentCreatedByQueryKey; } });
|
|
61
|
-
Object.defineProperty(exports, "getIconUrlQueryKey", { enumerable: true, get: function () { return projects_js_2.getIconUrlQueryKey; } });
|
|
62
|
-
Object.defineProperty(exports, "getMemberByIdQueryKey", { enumerable: true, get: function () { return projects_js_2.getMemberByIdQueryKey; } });
|
|
63
|
-
Object.defineProperty(exports, "getMembersQueryKey", { enumerable: true, get: function () { return projects_js_2.getMembersQueryKey; } });
|
|
64
|
-
Object.defineProperty(exports, "getProjectByIdQueryKey", { enumerable: true, get: function () { return projects_js_2.getProjectByIdQueryKey; } });
|
|
65
|
-
Object.defineProperty(exports, "getProjectRoleQueryKey", { enumerable: true, get: function () { return projects_js_2.getProjectRoleQueryKey; } });
|
|
66
|
-
Object.defineProperty(exports, "getProjectSettingsQueryKey", { enumerable: true, get: function () { return projects_js_2.getProjectSettingsQueryKey; } });
|
|
67
|
-
Object.defineProperty(exports, "getProjectsQueryKey", { enumerable: true, get: function () { return projects_js_2.getProjectsQueryKey; } });
|
|
68
|
-
var shared_js_1 = require("./lib/react-query/shared.js");
|
|
69
|
-
Object.defineProperty(exports, "ROOT_QUERY_KEY", { enumerable: true, get: function () { return shared_js_1.ROOT_QUERY_KEY; } });
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import type { MapeoProjectApi } from '@comapeo/ipc' with { 'resolution-mode': 'import' };
|
|
2
|
-
import type { MapeoDoc, MapeoValue } from '@comapeo/schema' with { 'resolution-mode': 'import' };
|
|
3
2
|
import { type QueryClient } from '@tanstack/react-query';
|
|
4
|
-
|
|
5
|
-
export type WriteableValue<D extends WriteableDocumentType> = Extract<MapeoValue, {
|
|
6
|
-
schemaName: D;
|
|
7
|
-
}>;
|
|
8
|
-
export type WriteableDocument<D extends WriteableDocumentType> = Extract<MapeoDoc, {
|
|
9
|
-
schemaName: D;
|
|
10
|
-
}>;
|
|
3
|
+
import { WriteableDocument, WriteableDocumentType, WriteableValue } from '../types.js';
|
|
11
4
|
export declare function getDocumentsQueryKey<D extends WriteableDocumentType>({ projectId, docType, }: {
|
|
12
5
|
projectId: string;
|
|
13
6
|
docType: D;
|
|
@@ -330,3 +330,19 @@ export declare function createBlobMutationOptions({ projectApi, }: {
|
|
|
330
330
|
networkMode: "always";
|
|
331
331
|
retry: false;
|
|
332
332
|
};
|
|
333
|
+
export declare function startSyncMutationOptions({ projectApi, }: {
|
|
334
|
+
projectApi: MapeoProjectApi;
|
|
335
|
+
}): {
|
|
336
|
+
mutationFn: (opts: {
|
|
337
|
+
autostopDataSyncAfter: number | null;
|
|
338
|
+
} | undefined) => Promise<void>;
|
|
339
|
+
networkMode: "always";
|
|
340
|
+
retry: false;
|
|
341
|
+
};
|
|
342
|
+
export declare function stopSyncMutationOptions({ projectApi, }: {
|
|
343
|
+
projectApi: MapeoProjectApi;
|
|
344
|
+
}): {
|
|
345
|
+
mutationFn: () => Promise<void>;
|
|
346
|
+
networkMode: "always";
|
|
347
|
+
retry: false;
|
|
348
|
+
};
|
|
@@ -24,6 +24,8 @@ exports.leaveProjectMutationOptions = leaveProjectMutationOptions;
|
|
|
24
24
|
exports.importProjectConfigMutationOptions = importProjectConfigMutationOptions;
|
|
25
25
|
exports.updateProjectSettingsMutationOptions = updateProjectSettingsMutationOptions;
|
|
26
26
|
exports.createBlobMutationOptions = createBlobMutationOptions;
|
|
27
|
+
exports.startSyncMutationOptions = startSyncMutationOptions;
|
|
28
|
+
exports.stopSyncMutationOptions = stopSyncMutationOptions;
|
|
27
29
|
const react_query_1 = require("@tanstack/react-query");
|
|
28
30
|
const shared_js_1 = require("./shared.js");
|
|
29
31
|
function getProjectsQueryKey() {
|
|
@@ -233,3 +235,21 @@ function createBlobMutationOptions({ projectApi, }) {
|
|
|
233
235
|
},
|
|
234
236
|
};
|
|
235
237
|
}
|
|
238
|
+
function startSyncMutationOptions({ projectApi, }) {
|
|
239
|
+
return {
|
|
240
|
+
...(0, shared_js_1.baseMutationOptions)(),
|
|
241
|
+
mutationFn: async (opts) => {
|
|
242
|
+
// Have to avoid passing `undefined` explicitly
|
|
243
|
+
// See https://github.com/digidem/rpc-reflector/issues/21
|
|
244
|
+
return opts ? projectApi.$sync.start(opts) : projectApi.$sync.start();
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function stopSyncMutationOptions({ projectApi, }) {
|
|
249
|
+
return {
|
|
250
|
+
...(0, shared_js_1.baseMutationOptions)(),
|
|
251
|
+
mutationFn: async () => {
|
|
252
|
+
return projectApi.$sync.stop();
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MapeoProjectApi } from '@comapeo/ipc' with { 'resolution-mode': 'import' };
|
|
2
|
+
export type SyncState = Awaited<ReturnType<MapeoProjectApi['$sync']['getState']>>;
|
|
3
|
+
export declare function getDataSyncCountForDevice(syncStateForDevice: SyncState['remoteDeviceSyncState'][string]): number;
|
|
4
|
+
export declare class SyncStore {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(project: MapeoProjectApi);
|
|
7
|
+
subscribe: (listener: () => void) => () => void;
|
|
8
|
+
getStateSnapshot: () => import("@comapeo/core/dist/sync/sync-api.js", { with: { "resolution-mode": "import" } }).State | null;
|
|
9
|
+
getDataProgressSnapshot: () => number | null;
|
|
10
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SyncStore = void 0;
|
|
4
|
+
exports.getDataSyncCountForDevice = getDataSyncCountForDevice;
|
|
5
|
+
function getDataSyncCountForDevice(syncStateForDevice) {
|
|
6
|
+
const { data } = syncStateForDevice;
|
|
7
|
+
return data.want + data.wanted;
|
|
8
|
+
}
|
|
9
|
+
class SyncStore {
|
|
10
|
+
#project;
|
|
11
|
+
#listeners = new Set();
|
|
12
|
+
#isSubscribedInternal = false;
|
|
13
|
+
#error = null;
|
|
14
|
+
#state = null;
|
|
15
|
+
// Used for calculating sync progress
|
|
16
|
+
#perDeviceMaxSyncCount = new Map();
|
|
17
|
+
constructor(project) {
|
|
18
|
+
this.#project = project;
|
|
19
|
+
}
|
|
20
|
+
subscribe = (listener) => {
|
|
21
|
+
this.#listeners.add(listener);
|
|
22
|
+
if (!this.#isSubscribedInternal)
|
|
23
|
+
this.#startSubscription();
|
|
24
|
+
return () => {
|
|
25
|
+
this.#listeners.delete(listener);
|
|
26
|
+
if (this.#listeners.size === 0)
|
|
27
|
+
this.#stopSubscription();
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
getStateSnapshot = () => {
|
|
31
|
+
if (this.#error)
|
|
32
|
+
throw this.#error;
|
|
33
|
+
return this.#state;
|
|
34
|
+
};
|
|
35
|
+
getDataProgressSnapshot = () => {
|
|
36
|
+
if (this.#state === null) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
let currentSyncCount = 0;
|
|
40
|
+
let totalMaxSyncCount = 0;
|
|
41
|
+
let otherEnabledDevicesExist = false;
|
|
42
|
+
for (const [deviceId, deviceSyncState] of Object.entries(this.#state.remoteDeviceSyncState)) {
|
|
43
|
+
if (deviceSyncState.data.isSyncEnabled) {
|
|
44
|
+
otherEnabledDevicesExist = true;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const existingMaxCount = this.#perDeviceMaxSyncCount.get(deviceId);
|
|
50
|
+
if (typeof existingMaxCount === 'number' && existingMaxCount > 0) {
|
|
51
|
+
currentSyncCount = getDataSyncCountForDevice(deviceSyncState);
|
|
52
|
+
totalMaxSyncCount += existingMaxCount;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!otherEnabledDevicesExist) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
if (totalMaxSyncCount === 0) {
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
const ratio = (totalMaxSyncCount - currentSyncCount) / totalMaxSyncCount;
|
|
62
|
+
if (ratio <= 0)
|
|
63
|
+
return 0;
|
|
64
|
+
if (ratio >= 1)
|
|
65
|
+
return 1;
|
|
66
|
+
return clamp(ratio, 0.01, 0.99);
|
|
67
|
+
};
|
|
68
|
+
#notifyListeners() {
|
|
69
|
+
for (const listener of this.#listeners) {
|
|
70
|
+
listener();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
#onSyncState = (state) => {
|
|
74
|
+
const dataSyncWasEnabled = this.#state
|
|
75
|
+
? this.#state.data.isSyncEnabled
|
|
76
|
+
: false;
|
|
77
|
+
// Reset map keeping track of counts used for progress if data sync is toggled
|
|
78
|
+
if (dataSyncWasEnabled !== state.data.isSyncEnabled) {
|
|
79
|
+
this.#perDeviceMaxSyncCount.clear();
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
// Remove devices from #perDeviceMaxSyncCount that are no longer found in the new sync state
|
|
83
|
+
for (const deviceId of this.#perDeviceMaxSyncCount.keys()) {
|
|
84
|
+
if (!Object.hasOwn(state.remoteDeviceSyncState, deviceId)) {
|
|
85
|
+
this.#perDeviceMaxSyncCount.delete(deviceId);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (const [deviceId, stateForDevice] of Object.entries(state.remoteDeviceSyncState)) {
|
|
90
|
+
const existingCount = this.#perDeviceMaxSyncCount.get(deviceId);
|
|
91
|
+
const newCount = getDataSyncCountForDevice(stateForDevice);
|
|
92
|
+
if (existingCount === undefined || existingCount < newCount) {
|
|
93
|
+
this.#perDeviceMaxSyncCount.set(deviceId, newCount);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
this.#state = state;
|
|
97
|
+
this.#error = null;
|
|
98
|
+
this.#notifyListeners();
|
|
99
|
+
};
|
|
100
|
+
#startSubscription = () => {
|
|
101
|
+
this.#project.$sync.on('sync-state', this.#onSyncState);
|
|
102
|
+
this.#isSubscribedInternal = true;
|
|
103
|
+
this.#project.$sync
|
|
104
|
+
.getState()
|
|
105
|
+
.then(this.#onSyncState)
|
|
106
|
+
.catch((e) => {
|
|
107
|
+
this.#error = e;
|
|
108
|
+
this.#notifyListeners();
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
#stopSubscription = () => {
|
|
112
|
+
this.#isSubscribedInternal = false;
|
|
113
|
+
this.#project.$sync.off('sync-state', this.#onSyncState);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
exports.SyncStore = SyncStore;
|
|
117
|
+
function clamp(value, min, max) {
|
|
118
|
+
return Math.max(min, Math.min(value, max));
|
|
119
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MapeoDoc, MapeoValue } from '@comapeo/schema' with { 'resolution-mode': 'import' };
|
|
2
|
+
export type WriteableDocumentType = Extract<MapeoDoc['schemaName'], 'field' | 'observation' | 'preset' | 'track' | 'remoteDetectionAlert'>;
|
|
3
|
+
export type WriteableValue<D extends WriteableDocumentType> = Extract<MapeoValue, {
|
|
4
|
+
schemaName: D;
|
|
5
|
+
}>;
|
|
6
|
+
export type WriteableDocument<D extends WriteableDocumentType> = Extract<MapeoDoc, {
|
|
7
|
+
schemaName: D;
|
|
8
|
+
}>;
|
|
9
|
+
export {};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { MapeoClientApi } from '@comapeo/ipc' with { 'resolution-mode': 'import' };
|
|
2
|
-
import { type ReactNode } from 'react';
|
|
2
|
+
import { type JSX, type ReactNode } from 'react';
|
|
3
3
|
export declare const ClientApiContext: import("react").Context<import("@comapeo/ipc/dist/client.js").MapeoClientApi | null>;
|
|
4
4
|
/**
|
|
5
5
|
* Create a context provider that holds a CoMapeo API client instance.
|
|
6
6
|
*
|
|
7
|
-
* @param opts
|
|
8
|
-
* @param
|
|
9
|
-
*
|
|
7
|
+
* @param opts.children React children node
|
|
8
|
+
* @param opts.clientApi Client API instance
|
|
9
|
+
*
|
|
10
10
|
*/
|
|
11
11
|
export declare function ClientApiProvider({ children, clientApi, }: {
|
|
12
12
|
children: ReactNode;
|
|
13
13
|
clientApi: MapeoClientApi;
|
|
14
|
-
}):
|
|
14
|
+
}): JSX.Element;
|
|
@@ -3,9 +3,9 @@ export const ClientApiContext = createContext(null);
|
|
|
3
3
|
/**
|
|
4
4
|
* Create a context provider that holds a CoMapeo API client instance.
|
|
5
5
|
*
|
|
6
|
-
* @param opts
|
|
7
|
-
* @param
|
|
8
|
-
*
|
|
6
|
+
* @param opts.children React children node
|
|
7
|
+
* @param opts.clientApi Client API instance
|
|
8
|
+
*
|
|
9
9
|
*/
|
|
10
10
|
export function ClientApiProvider({ children, clientApi, }) {
|
|
11
11
|
return createElement(ClientApiContext.Provider, { value: clientApi }, children);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MapeoDoc } from '@comapeo/schema' with { 'resolution-mode': 'import' };
|
|
2
|
-
import {
|
|
2
|
+
import type { WriteableDocumentType } from '../lib/types.js';
|
|
3
3
|
type ReadHookResult<D> = {
|
|
4
4
|
data: D;
|
|
5
5
|
error: Error | null;
|
|
@@ -119,10 +119,10 @@ export declare function useCreateDocument<D extends WriteableDocumentType>({ doc
|
|
|
119
119
|
docType: D;
|
|
120
120
|
projectId: string;
|
|
121
121
|
}): {
|
|
122
|
-
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/
|
|
122
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/types.js").WriteableDocument<D> & {
|
|
123
123
|
forks: Array<string>;
|
|
124
124
|
}, Error, {
|
|
125
|
-
value: Omit<import("../lib/
|
|
125
|
+
value: Omit<import("../lib/types.js").WriteableValue<D>, "schemaName">;
|
|
126
126
|
}, unknown>;
|
|
127
127
|
reset: () => void;
|
|
128
128
|
status: "pending" | "error" | "success" | "idle";
|
|
@@ -137,11 +137,11 @@ export declare function useUpdateDocument<D extends WriteableDocumentType>({ doc
|
|
|
137
137
|
docType: D;
|
|
138
138
|
projectId: string;
|
|
139
139
|
}): {
|
|
140
|
-
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/
|
|
140
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/types.js").WriteableDocument<D> & {
|
|
141
141
|
forks: Array<string>;
|
|
142
142
|
}, Error, {
|
|
143
143
|
versionId: string;
|
|
144
|
-
value: Omit<import("../lib/
|
|
144
|
+
value: Omit<import("../lib/types.js").WriteableValue<D>, "schemaName">;
|
|
145
145
|
}, unknown>;
|
|
146
146
|
reset: () => void;
|
|
147
147
|
status: "pending" | "error" | "success" | "idle";
|
|
@@ -156,7 +156,7 @@ export declare function useDeleteDocument<D extends WriteableDocumentType>({ doc
|
|
|
156
156
|
docType: D;
|
|
157
157
|
projectId: string;
|
|
158
158
|
}): {
|
|
159
|
-
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/
|
|
159
|
+
mutate: import("@tanstack/react-query").UseMutateFunction<import("../lib/types.js").WriteableDocument<D> & {
|
|
160
160
|
forks: Array<string>;
|
|
161
161
|
}, Error, {
|
|
162
162
|
docId: string;
|