use-abcd 1.4.3 → 1.6.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 +225 -406
- package/dist/chunks/client-lHRDCo64.js +30 -0
- package/dist/chunks/client-lHRDCo64.js.map +1 -0
- package/dist/chunks/utils-DL5mgkvm.js +828 -0
- package/dist/chunks/utils-DL5mgkvm.js.map +1 -0
- package/dist/collection.d.ts +13 -5
- package/dist/examples/Benchmark.d.ts +2 -0
- package/dist/examples/LocalNotes.d.ts +2 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +1071 -1789
- package/dist/index.js.map +1 -1
- package/dist/item.d.ts +3 -2
- package/dist/mocks/handlers.d.ts +0 -1
- package/dist/node.d.ts +5 -1
- package/dist/runtime/client.d.ts +10 -48
- package/dist/runtime/client.js +5 -13
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/index.d.ts +5 -5
- package/dist/runtime/local.d.ts +32 -0
- package/dist/runtime/server.d.ts +25 -35
- package/dist/runtime/server.js +59 -108
- package/dist/runtime/server.js.map +1 -1
- package/dist/runtime/types.d.ts +28 -63
- package/dist/sync-queue.d.ts +7 -44
- package/dist/types.d.ts +22 -18
- package/dist/useCrud.d.ts +5 -3
- package/dist/useCrudTree.d.ts +3 -3
- package/dist/useItem.d.ts +3 -1
- package/dist/useNode.d.ts +3 -0
- package/dist/useSyncState.d.ts +2 -2
- package/dist/utils.d.ts +3 -4
- package/package.json +4 -2
- package/dist/cache.test.d.ts +0 -1
- package/dist/chunks/client-BfugfaiH.js +0 -144
- package/dist/chunks/client-BfugfaiH.js.map +0 -1
- package/dist/chunks/types-Dy4rYb2N.js +0 -19
- package/dist/chunks/types-Dy4rYb2N.js.map +0 -1
- package/dist/collection.e2e.test.d.ts +0 -1
- package/dist/fetch-handler.test.d.ts +0 -1
- package/dist/item-cache.test.d.ts +0 -1
- package/dist/node.test.d.ts +0 -1
- package/dist/runtime/client.test.d.ts +0 -1
- package/dist/runtime/server.test.d.ts +0 -1
- package/dist/sync-queue.test.d.ts +0 -1
- package/dist/useCrud.test.d.ts +0 -1
- package/dist/useCrudTree.test.d.ts +0 -1
- /package/dist/{App.d.ts → examples/App.d.ts} +0 -0
- /package/dist/{main.d.ts → examples/main.d.ts} +0 -0
package/dist/item.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Draft } from 'mutative';
|
|
2
2
|
import { Collection } from './collection';
|
|
3
3
|
import { ItemStatus } from './types';
|
|
4
|
-
export declare class Item<T extends
|
|
4
|
+
export declare class Item<T extends {
|
|
5
|
+
id: string;
|
|
6
|
+
}, C = unknown> {
|
|
5
7
|
private _collection;
|
|
6
8
|
private _id;
|
|
7
9
|
private _cachedStatus;
|
|
@@ -13,5 +15,4 @@ export declare class Item<T extends object, C = unknown> {
|
|
|
13
15
|
getStatus(): ItemStatus;
|
|
14
16
|
exists(): boolean;
|
|
15
17
|
get collection(): Collection<T, C>;
|
|
16
|
-
_updateId(newId: string): void;
|
|
17
18
|
}
|
package/dist/mocks/handlers.d.ts
CHANGED
package/dist/node.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export type TreeNode<T, NodeType = string> = {
|
|
|
6
6
|
position: number;
|
|
7
7
|
value: T;
|
|
8
8
|
type: NodeType;
|
|
9
|
+
clientUpdatedAt?: number;
|
|
9
10
|
};
|
|
10
11
|
export declare class Node<T extends object, C = unknown, NodeType = string> {
|
|
11
12
|
private _id;
|
|
@@ -19,9 +20,13 @@ export declare class Node<T extends object, C = unknown, NodeType = string> {
|
|
|
19
20
|
get depth(): number;
|
|
20
21
|
exists(): boolean;
|
|
21
22
|
getStatus(): ItemStatus;
|
|
23
|
+
private _touch;
|
|
22
24
|
getParent(): Node<T, C, NodeType> | null;
|
|
23
25
|
getChildren(): Node<T, C, NodeType>[];
|
|
24
26
|
private _generateChildId;
|
|
27
|
+
moveUp(): void;
|
|
28
|
+
moveDown(): void;
|
|
29
|
+
setPosition(targetIndex: number): void;
|
|
25
30
|
append(value: T, type?: NodeType): string;
|
|
26
31
|
prepend(value: T, type?: NodeType): string;
|
|
27
32
|
/**
|
|
@@ -46,5 +51,4 @@ export declare class Node<T extends object, C = unknown, NodeType = string> {
|
|
|
46
51
|
updateProp(mutate: (draft: Draft<T>) => void): void;
|
|
47
52
|
remove(): void;
|
|
48
53
|
select(): void;
|
|
49
|
-
_updateId(newId: string): void;
|
|
50
54
|
}
|
package/dist/runtime/client.d.ts
CHANGED
|
@@ -1,52 +1,14 @@
|
|
|
1
|
-
import { Change
|
|
2
|
-
import {
|
|
3
|
-
export type {
|
|
4
|
-
export
|
|
5
|
-
export type CreateHandler<T> = (data: T, signal: AbortSignal) => Promise<SyncHandlerResult>;
|
|
6
|
-
export type UpdateHandler<T> = (id: string, data: T, signal: AbortSignal) => Promise<SyncHandlerResult>;
|
|
7
|
-
export type DeleteHandler<T> = (id: string, data: T, signal: AbortSignal) => Promise<SyncHandlerResult>;
|
|
8
|
-
export type SyncBuilderConfig<T> = {
|
|
9
|
-
create?: CreateHandler<T>;
|
|
10
|
-
update?: UpdateHandler<T>;
|
|
11
|
-
delete?: DeleteHandler<T>;
|
|
12
|
-
};
|
|
13
|
-
export type SyncBuilder<T, C = unknown> = {
|
|
14
|
-
onSync: (changes: Change<T>[], context: C, signal: AbortSignal) => Promise<SyncResult[]>;
|
|
15
|
-
handlers: {
|
|
16
|
-
create?: CreateHandler<T>;
|
|
17
|
-
update?: UpdateHandler<T>;
|
|
18
|
-
delete?: DeleteHandler<T>;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
export type FetchToSyncResultOptions = {
|
|
22
|
-
fetch: Promise<Response>;
|
|
23
|
-
parseResponse?: (response: Response) => Promise<{
|
|
24
|
-
newId?: string;
|
|
25
|
-
}>;
|
|
26
|
-
parseError?: string | ((error: unknown) => string);
|
|
27
|
-
};
|
|
28
|
-
export declare function createSyncClient<T, C = unknown>(config: SyncBuilderConfig<T>): SyncBuilder<T, C>;
|
|
29
|
-
export declare function createSyncClientWithStats<T, C = unknown>(config: SyncBuilderConfig<T>): {
|
|
30
|
-
onSync: (changes: Change<T>[], context: C, signal: AbortSignal) => Promise<SyncResult[]>;
|
|
31
|
-
onSyncWithStats: (changes: Change<T>[], context: C, signal: AbortSignal) => Promise<SyncBatchResult>;
|
|
32
|
-
handlers: {
|
|
33
|
-
create?: CreateHandler<T>;
|
|
34
|
-
update?: UpdateHandler<T>;
|
|
35
|
-
delete?: DeleteHandler<T>;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
export declare function syncSuccess(options?: {
|
|
39
|
-
newId?: string;
|
|
40
|
-
}): SyncHandlerResult;
|
|
41
|
-
export declare function syncError(error: string): SyncHandlerResult;
|
|
42
|
-
export type EndpointSyncClientConfig = {
|
|
1
|
+
import { Change } from '../types';
|
|
2
|
+
import { SyncRequestBody, SyncResponseBody } from './types';
|
|
3
|
+
export type { SyncRequestBody, SyncResponseBody };
|
|
4
|
+
export type SyncClientConfig = {
|
|
43
5
|
endpoint: string;
|
|
44
6
|
headers?: Record<string, string>;
|
|
45
7
|
scope?: string;
|
|
46
8
|
};
|
|
47
|
-
export
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
9
|
+
export declare function createSyncClient<T extends {
|
|
10
|
+
id: string;
|
|
11
|
+
}, Q = unknown>(config: string | SyncClientConfig): (params: {
|
|
12
|
+
query?: Q;
|
|
13
|
+
changes?: Change<T>[];
|
|
14
|
+
}, signal: AbortSignal) => Promise<SyncResponseBody<T>>;
|
package/dist/runtime/client.js
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import { c } from "../chunks/
|
|
2
|
-
import {
|
|
3
|
-
import { createSyncServer as f, serverSyncError as l, serverSyncSuccess as m } from "./server.js";
|
|
1
|
+
import { c } from "../chunks/client-lHRDCo64.js";
|
|
2
|
+
import { createCrudHandler as a, createSyncServer as n } from "./server.js";
|
|
4
3
|
export {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
n as createSyncClientWithStats,
|
|
9
|
-
f as createSyncServer,
|
|
10
|
-
o as fetchToSyncResult,
|
|
11
|
-
l as serverSyncError,
|
|
12
|
-
m as serverSyncSuccess,
|
|
13
|
-
S as syncError,
|
|
14
|
-
y as syncSuccess
|
|
4
|
+
a as createCrudHandler,
|
|
5
|
+
c as createSyncClient,
|
|
6
|
+
n as createSyncServer
|
|
15
7
|
};
|
|
16
8
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { createSyncClient
|
|
3
|
-
export type {
|
|
4
|
-
export { createSyncServer,
|
|
5
|
-
export type {
|
|
1
|
+
export type { SyncRequestBody, SyncResponseBody, ServerRecord } from './types';
|
|
2
|
+
export { createSyncClient } from './client';
|
|
3
|
+
export type { SyncClientConfig } from './client';
|
|
4
|
+
export { createSyncServer, createCrudHandler } from './server';
|
|
5
|
+
export type { CrudHandler, SyncServerConfig, FetchResult } from './server';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Change, SyncResponse, SyncQueueState } from '../types';
|
|
2
|
+
import { LocalSyncClientConfig } from './types';
|
|
3
|
+
export type { LocalSyncClientConfig };
|
|
4
|
+
export declare function createLocalSyncClient<T extends {
|
|
5
|
+
id: string;
|
|
6
|
+
}>(config: LocalSyncClientConfig): {
|
|
7
|
+
handler: (params: {
|
|
8
|
+
query?: unknown;
|
|
9
|
+
changes?: Change<T>[];
|
|
10
|
+
}, signal: AbortSignal) => Promise<SyncResponse<T>>;
|
|
11
|
+
subscribe: (cb: () => void) => () => void;
|
|
12
|
+
getState: () => SyncQueueState<T>;
|
|
13
|
+
pauseSync: () => void;
|
|
14
|
+
resumeSync: () => void;
|
|
15
|
+
retrySync: (id?: string) => void;
|
|
16
|
+
resetDatabase: () => Promise<void>;
|
|
17
|
+
destroy: () => Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
export declare function useLocalSyncState<T extends {
|
|
20
|
+
id: string;
|
|
21
|
+
}>(collectionId: string, localClient: ReturnType<typeof createLocalSyncClient<T>>): {
|
|
22
|
+
isSyncing: boolean;
|
|
23
|
+
isPaused: boolean;
|
|
24
|
+
queue: Map<string, Change<T>>;
|
|
25
|
+
inFlight: Map<string, Change<T>>;
|
|
26
|
+
errors: Map<string, import('..').SyncError<T>>;
|
|
27
|
+
pauseSync: () => void;
|
|
28
|
+
resumeSync: () => void;
|
|
29
|
+
retrySync: (id?: string) => void;
|
|
30
|
+
resetDatabase: () => Promise<void>;
|
|
31
|
+
refetch: () => void;
|
|
32
|
+
};
|
package/dist/runtime/server.d.ts
CHANGED
|
@@ -1,37 +1,27 @@
|
|
|
1
|
-
import { Change
|
|
2
|
-
import {
|
|
3
|
-
export type {
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Change } from '../types';
|
|
2
|
+
import { SyncRequestBody, SyncResponseBody, ServerRecord } from './types';
|
|
3
|
+
export type { SyncRequestBody, SyncResponseBody, ServerRecord };
|
|
4
|
+
export type CrudHandler<T, Q = unknown> = (request: {
|
|
5
|
+
scope?: string;
|
|
6
|
+
query?: Q;
|
|
7
|
+
changes?: Change<T>[];
|
|
8
|
+
}) => Promise<SyncResponseBody<T>> | SyncResponseBody<T>;
|
|
9
|
+
export type FetchResult<T, S = unknown> = T[] | {
|
|
10
|
+
items: T[];
|
|
11
|
+
serverState?: S;
|
|
8
12
|
};
|
|
9
|
-
export type
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
delete?: ServerDeleteHandler<T, Q>;
|
|
13
|
+
export type SyncServerConfig<T extends {
|
|
14
|
+
id: string;
|
|
15
|
+
}, Q = unknown, S = unknown> = {
|
|
16
|
+
fetch: (params: {
|
|
17
|
+
scope?: string;
|
|
18
|
+
query: Q;
|
|
19
|
+
}) => Promise<FetchResult<T, S>> | FetchResult<T, S>;
|
|
20
|
+
create: (record: ServerRecord<T>) => Promise<void> | void;
|
|
21
|
+
update: (record: ServerRecord<T>) => Promise<void> | void;
|
|
22
|
+
remove: (record: ServerRecord<T>) => Promise<void> | void;
|
|
20
23
|
};
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
processChangesWithStats: (changes: Change<T>[], ctx: ServerHandlerContext<T, Q>) => Promise<SyncBatchResult>;
|
|
26
|
-
handlers: {
|
|
27
|
-
fetch?: ServerFetchHandler<T, Q>;
|
|
28
|
-
create?: ServerCreateHandler<T, Q>;
|
|
29
|
-
update?: ServerUpdateHandler<T, Q>;
|
|
30
|
-
delete?: ServerDeleteHandler<T, Q>;
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
export declare function serverSyncSuccess(options?: {
|
|
34
|
-
newId?: string;
|
|
35
|
-
}): SyncHandlerResult;
|
|
36
|
-
export declare function serverSyncError(error: string): SyncHandlerResult;
|
|
37
|
-
export declare function createSyncServer<T, Q = unknown>(config: ServerSyncHandlerConfig<T, Q>): ServerSyncHandler<T, Q>;
|
|
24
|
+
export declare function createCrudHandler<T extends {
|
|
25
|
+
id: string;
|
|
26
|
+
}, Q = unknown, S = unknown>(config: SyncServerConfig<T, Q, S>): CrudHandler<T, Q>;
|
|
27
|
+
export declare function createSyncServer<T, Q = unknown>(handler: CrudHandler<T, Q>): (request: Request) => Promise<Response>;
|
package/dist/runtime/server.js
CHANGED
|
@@ -1,121 +1,72 @@
|
|
|
1
|
-
import { c as
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
success: (r) => d(r, 200),
|
|
7
|
-
methodNotAllowed: () => d({ error: "Method not allowed. Use POST." }, 405),
|
|
8
|
-
invalidJson: () => d({ error: "Invalid JSON body" }, 400),
|
|
9
|
-
invalidPayload: () => d({ error: "Request body must contain 'query' and/or 'changes'" }, 400),
|
|
10
|
-
validationError: (r) => d({ error: `Validation error: ${r}` }, 400),
|
|
11
|
-
notConfigured: (r) => d({ error: `${r} handler not configured` }, 501),
|
|
12
|
-
serverError: (r) => d({ error: r instanceof Error ? r.message : "Internal server error" }, 500)
|
|
1
|
+
import { g as i, m as c, i as d } from "../chunks/utils-DL5mgkvm.js";
|
|
2
|
+
const y = {
|
|
3
|
+
create: "create",
|
|
4
|
+
update: "update",
|
|
5
|
+
delete: "remove"
|
|
13
6
|
};
|
|
14
|
-
function p() {
|
|
15
|
-
return {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
7
|
+
function p(a) {
|
|
8
|
+
return async (t) => {
|
|
9
|
+
const r = i(), s = { serverSyncedAt: r };
|
|
10
|
+
if (t.changes && (s.syncResults = await Promise.all(
|
|
11
|
+
c(t.changes, async (e) => {
|
|
12
|
+
try {
|
|
13
|
+
const n = {
|
|
14
|
+
id: e.data.id,
|
|
15
|
+
data: e.data,
|
|
16
|
+
serverSyncedAt: r,
|
|
17
|
+
deleted: e.type === "delete"
|
|
18
|
+
};
|
|
19
|
+
return await a[y[e.type]](n), { status: "success", id: e.data.id, type: e.type, serverSyncedAt: r };
|
|
20
|
+
} catch (n) {
|
|
21
|
+
return {
|
|
22
|
+
status: "error",
|
|
23
|
+
id: e.data.id,
|
|
24
|
+
type: e.type,
|
|
25
|
+
serverSyncedAt: r,
|
|
26
|
+
error: n instanceof Error ? n.message : "Unknown error"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
)), t.query !== void 0) {
|
|
31
|
+
const e = await a.fetch({ scope: t.scope, query: t.query });
|
|
32
|
+
d(e) ? s.items = e : (s.items = e.items, s.serverState = e.serverState);
|
|
33
33
|
}
|
|
34
|
+
return s;
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
async
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (!n.guard(e))
|
|
46
|
-
return { id: r.id, status: "error", error: n.notConfiguredError };
|
|
47
|
-
const i = y(r.data, e.schema);
|
|
48
|
-
if (i.valid === !1)
|
|
49
|
-
return { id: r.id, status: "error", error: `Validation failed: ${i.error}` };
|
|
50
|
-
try {
|
|
51
|
-
const o = await n.execute({ ...r, data: i.data }, e, s);
|
|
52
|
-
return n.toResult(r, o);
|
|
53
|
-
} catch (o) {
|
|
54
|
-
return {
|
|
55
|
-
id: r.id,
|
|
56
|
-
status: "error",
|
|
57
|
-
error: o instanceof Error ? o.message : "Unknown error"
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function m(r) {
|
|
62
|
-
return { success: !0, ...r };
|
|
63
|
-
}
|
|
64
|
-
function C(r) {
|
|
65
|
-
return { success: !1, error: r };
|
|
66
|
-
}
|
|
67
|
-
function E(r) {
|
|
68
|
-
const e = async (o, t) => {
|
|
69
|
-
if (!r.fetch) throw new Error("Fetch handler not configured");
|
|
70
|
-
return r.fetch(o, t);
|
|
71
|
-
}, s = async (o, t) => Promise.all(o.map((u) => v(u, r, t))), f = async (o, t) => {
|
|
72
|
-
const u = await s(o, t);
|
|
73
|
-
return h(u);
|
|
74
|
-
}, n = async (o) => {
|
|
75
|
-
let t;
|
|
37
|
+
const o = (a, t) => new Response(JSON.stringify(a), {
|
|
38
|
+
status: t,
|
|
39
|
+
headers: { "Content-Type": "application/json" }
|
|
40
|
+
});
|
|
41
|
+
function l(a) {
|
|
42
|
+
return async (t) => {
|
|
43
|
+
if (t.method !== "POST")
|
|
44
|
+
return o({ error: "Method not allowed. Use POST." }, 405);
|
|
45
|
+
let r;
|
|
76
46
|
try {
|
|
77
|
-
|
|
47
|
+
r = await t.json();
|
|
78
48
|
} catch {
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
if (!t.query && !t.changes)
|
|
82
|
-
return a.invalidPayload();
|
|
83
|
-
const u = { body: t }, c = {};
|
|
84
|
-
if (t.query !== void 0) {
|
|
85
|
-
if (!r.fetch) return a.notConfigured("Fetch");
|
|
86
|
-
const l = y(t.query, r.querySchema);
|
|
87
|
-
if (l.valid === !1) return a.validationError(l.error);
|
|
88
|
-
c.results = await e(l.data, u);
|
|
89
|
-
}
|
|
90
|
-
if (t.changes !== void 0) {
|
|
91
|
-
if (!Array.isArray(t.changes)) return a.invalidPayload();
|
|
92
|
-
c.syncResults = await s(t.changes, u);
|
|
49
|
+
return o({ error: "Invalid JSON body" }, 400);
|
|
93
50
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
fetch: r.fetch,
|
|
109
|
-
create: r.create,
|
|
110
|
-
update: r.update,
|
|
111
|
-
delete: r.delete
|
|
51
|
+
if (r.query === void 0 && !r.changes)
|
|
52
|
+
return o({ error: "Request body must contain 'query' and/or 'changes'" }, 400);
|
|
53
|
+
try {
|
|
54
|
+
const s = await a({
|
|
55
|
+
scope: r.scope,
|
|
56
|
+
query: r.query,
|
|
57
|
+
changes: r.changes
|
|
58
|
+
});
|
|
59
|
+
return o(s, 200);
|
|
60
|
+
} catch (s) {
|
|
61
|
+
return o(
|
|
62
|
+
{ error: s instanceof Error ? s.message : "Internal server error" },
|
|
63
|
+
500
|
|
64
|
+
);
|
|
112
65
|
}
|
|
113
66
|
};
|
|
114
67
|
}
|
|
115
68
|
export {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
C as serverSyncError,
|
|
119
|
-
m as serverSyncSuccess
|
|
69
|
+
p as createCrudHandler,
|
|
70
|
+
l as createSyncServer
|
|
120
71
|
};
|
|
121
72
|
//# sourceMappingURL=server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sources":["../../src/runtime/server.ts"],"sourcesContent":["import type { Change, SyncResult } from \"../types\";\nimport {\n type SyncHandlerResult,\n type SyncBatchResult,\n type Schema,\n type SyncRequestBody,\n type SyncResponseBody,\n categorizeResults,\n} from \"./types\";\n\n// Re-export shared types for server module consumers\nexport type { SyncHandlerResult, SyncBatchResult, Schema, SyncRequestBody, SyncResponseBody };\nexport { categorizeResults };\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Context passed to all handlers containing the parsed request body */\nexport type ServerHandlerContext<T, Q = unknown> = {\n body: SyncRequestBody<T, Q>;\n};\n\nexport type ServerFetchHandler<T, Q> = (\n query: Q,\n ctx: ServerHandlerContext<T, Q>,\n) => Promise<T[]> | T[];\nexport type ServerCreateHandler<T, Q = unknown> = (\n data: T,\n ctx: ServerHandlerContext<T, Q>,\n) => Promise<SyncHandlerResult> | SyncHandlerResult;\nexport type ServerUpdateHandler<T, Q = unknown> = (\n id: string,\n data: T,\n ctx: ServerHandlerContext<T, Q>,\n) => Promise<SyncHandlerResult> | SyncHandlerResult;\nexport type ServerDeleteHandler<T, Q = unknown> = (\n id: string,\n data: T,\n ctx: ServerHandlerContext<T, Q>,\n) => Promise<SyncHandlerResult> | SyncHandlerResult;\n\nexport type ServerSyncHandlerConfig<T, Q = unknown> = {\n schema?: Schema<T>;\n querySchema?: Schema<Q>;\n fetch?: ServerFetchHandler<T, Q>;\n create?: ServerCreateHandler<T, Q>;\n update?: ServerUpdateHandler<T, Q>;\n delete?: ServerDeleteHandler<T, Q>;\n};\n\nexport type ServerSyncHandler<T, Q = unknown> = {\n handler: (request: Request) => Promise<Response>;\n fetchItems: (query: Q, ctx: ServerHandlerContext<T, Q>) => Promise<T[]>;\n processChanges: (changes: Change<T>[], ctx: ServerHandlerContext<T, Q>) => Promise<SyncResult[]>;\n processChangesWithStats: (\n changes: Change<T>[],\n ctx: ServerHandlerContext<T, Q>,\n ) => Promise<SyncBatchResult>;\n handlers: {\n fetch?: ServerFetchHandler<T, Q>;\n create?: ServerCreateHandler<T, Q>;\n update?: ServerUpdateHandler<T, Q>;\n delete?: ServerDeleteHandler<T, Q>;\n };\n};\n\n// ============================================================================\n// Response Helpers\n// ============================================================================\n\nconst jsonResponse = (body: unknown, status: number): Response =>\n new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n\nconst responses = {\n success: (data: unknown) => jsonResponse(data, 200),\n methodNotAllowed: () => jsonResponse({ error: \"Method not allowed. Use POST.\" }, 405),\n invalidJson: () => jsonResponse({ error: \"Invalid JSON body\" }, 400),\n invalidPayload: () =>\n jsonResponse({ error: \"Request body must contain 'query' and/or 'changes'\" }, 400),\n validationError: (message: string) =>\n jsonResponse({ error: `Validation error: ${message}` }, 400),\n notConfigured: (handler: string) =>\n jsonResponse({ error: `${handler} handler not configured` }, 501),\n serverError: (error: unknown) =>\n jsonResponse({ error: error instanceof Error ? error.message : \"Internal server error\" }, 500),\n} as const;\n\n// ============================================================================\n// Change Processing\n// ============================================================================\n\ntype ChangeProcessor<T, Q> = {\n guard: (config: ServerSyncHandlerConfig<T, Q>) => boolean;\n execute: (\n change: Change<T>,\n config: ServerSyncHandlerConfig<T, Q>,\n ctx: ServerHandlerContext<T, Q>,\n ) => Promise<SyncHandlerResult> | SyncHandlerResult;\n toResult: (change: Change<T>, result: SyncHandlerResult) => SyncResult;\n notConfiguredError: string;\n};\n\nfunction createChangeProcessors<T, Q>(): Record<string, ChangeProcessor<T, Q>> {\n return {\n create: {\n guard: (config) => !!config.create,\n execute: (change, config, ctx) => config.create!(change.data, ctx),\n toResult: (change, result) =>\n result.success === true\n ? { id: change.id, status: \"success\" as const, newId: result.newId }\n : { id: change.id, status: \"error\" as const, error: result.error },\n notConfiguredError: \"Create handler not configured\",\n },\n\n update: {\n guard: (config) => !!config.update,\n execute: (change, config, ctx) => config.update!(change.id, change.data, ctx),\n toResult: (change, result) =>\n result.success === true\n ? { id: change.id, status: \"success\" as const }\n : { id: change.id, status: \"error\" as const, error: result.error },\n notConfiguredError: \"Update handler not configured\",\n },\n\n delete: {\n guard: (config) => !!config.delete,\n execute: (change, config, ctx) => config.delete!(change.id, change.data, ctx),\n toResult: (change, result) =>\n result.success === true\n ? { id: change.id, status: \"success\" as const }\n : { id: change.id, status: \"error\" as const, error: result.error },\n notConfiguredError: \"Delete handler not configured\",\n },\n };\n}\n\nfunction validateData<T>(\n data: unknown,\n schema?: Schema<T>,\n): { valid: true; data: T } | { valid: false; error: string } {\n if (!schema) return { valid: true, data: data as T };\n\n const result = schema.safeParse(data);\n return result.success === true\n ? { valid: true, data: result.data }\n : { valid: false, error: result.error.message };\n}\n\nasync function processServerChange<T, Q>(\n change: Change<T>,\n config: ServerSyncHandlerConfig<T, Q>,\n ctx: ServerHandlerContext<T, Q>,\n): Promise<SyncResult> {\n const processors = createChangeProcessors<T, Q>();\n const processor = processors[change.type];\n\n if (!processor) {\n return { id: change.id, status: \"error\", error: `Unknown change type: ${change.type}` };\n }\n\n if (!processor.guard(config)) {\n return { id: change.id, status: \"error\", error: processor.notConfiguredError };\n }\n\n const validation = validateData(change.data, config.schema);\n if (validation.valid === false) {\n return { id: change.id, status: \"error\", error: `Validation failed: ${validation.error}` };\n }\n\n try {\n const result = await processor.execute({ ...change, data: validation.data }, config, ctx);\n return processor.toResult(change, result);\n } catch (error) {\n return {\n id: change.id,\n status: \"error\",\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\nexport function serverSyncSuccess(options?: { newId?: string }): SyncHandlerResult {\n return { success: true, ...options };\n}\n\nexport function serverSyncError(error: string): SyncHandlerResult {\n return { success: false, error };\n}\n\nexport function createSyncServer<T, Q = unknown>(\n config: ServerSyncHandlerConfig<T, Q>,\n): ServerSyncHandler<T, Q> {\n const fetchItems = async (query: Q, ctx: ServerHandlerContext<T, Q>): Promise<T[]> => {\n if (!config.fetch) throw new Error(\"Fetch handler not configured\");\n return config.fetch(query, ctx);\n };\n\n const processChanges = async (\n changes: Change<T>[],\n ctx: ServerHandlerContext<T, Q>,\n ): Promise<SyncResult[]> => {\n return Promise.all(changes.map((change) => processServerChange(change, config, ctx)));\n };\n\n const processChangesWithStats = async (\n changes: Change<T>[],\n ctx: ServerHandlerContext<T, Q>,\n ): Promise<SyncBatchResult> => {\n const results = await processChanges(changes, ctx);\n return categorizeResults(results);\n };\n\n const handlePost = async (request: Request): Promise<Response> => {\n let body: SyncRequestBody<T, Q>;\n try {\n body = await request.json();\n } catch {\n return responses.invalidJson();\n }\n\n if (!body.query && !body.changes) {\n return responses.invalidPayload();\n }\n\n const ctx: ServerHandlerContext<T, Q> = { body };\n const responseBody: SyncResponseBody<T> = {};\n\n if (body.query !== undefined) {\n if (!config.fetch) return responses.notConfigured(\"Fetch\");\n\n const validation = validateData<Q>(body.query, config.querySchema);\n if (validation.valid === false) return responses.validationError(validation.error);\n\n responseBody.results = await fetchItems(validation.data, ctx);\n }\n\n if (body.changes !== undefined) {\n if (!Array.isArray(body.changes)) return responses.invalidPayload();\n responseBody.syncResults = await processChanges(body.changes, ctx);\n }\n\n return responses.success(responseBody);\n };\n\n const handler = async (request: Request): Promise<Response> => {\n try {\n if (request.method !== \"POST\") return responses.methodNotAllowed();\n return await handlePost(request);\n } catch (error) {\n return responses.serverError(error);\n }\n };\n\n return {\n handler,\n fetchItems,\n processChanges,\n processChangesWithStats,\n handlers: {\n fetch: config.fetch,\n create: config.create,\n update: config.update,\n delete: config.delete,\n },\n };\n}\n"],"names":["jsonResponse","body","status","responses","data","message","handler","error","createChangeProcessors","config","change","ctx","result","validateData","schema","processServerChange","processor","validation","serverSyncSuccess","options","serverSyncError","createSyncServer","fetchItems","query","processChanges","changes","processChangesWithStats","results","categorizeResults","handlePost","request","responseBody"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sources":["../../src/runtime/server.ts"],"sourcesContent":["import { isArray, map } from \"lodash-es\";\nimport type { Change, Result } from \"../types\";\nimport type { SyncRequestBody, SyncResponseBody, ServerRecord } from \"./types\";\nimport { getIdFromTime } from \"../utils\";\n\nexport type { SyncRequestBody, SyncResponseBody, ServerRecord };\n\nexport type CrudHandler<T, Q = unknown> = (request: {\n scope?: string;\n query?: Q;\n changes?: Change<T>[];\n}) => Promise<SyncResponseBody<T>> | SyncResponseBody<T>;\n\nexport type FetchResult<T, S = unknown> = T[] | { items: T[]; serverState?: S };\n\nexport type SyncServerConfig<T extends { id: string }, Q = unknown, S = unknown> = {\n fetch: (params: { scope?: string; query: Q }) => Promise<FetchResult<T, S>> | FetchResult<T, S>;\n create: (record: ServerRecord<T>) => Promise<void> | void;\n update: (record: ServerRecord<T>) => Promise<void> | void;\n remove: (record: ServerRecord<T>) => Promise<void> | void;\n};\n\nconst operations: Record<string, \"create\" | \"update\" | \"remove\"> = {\n create: \"create\",\n update: \"update\",\n delete: \"remove\",\n};\n\nexport function createCrudHandler<T extends { id: string }, Q = unknown, S = unknown>(\n config: SyncServerConfig<T, Q, S>,\n): CrudHandler<T, Q> {\n return async (request) => {\n const serverSyncedAt = getIdFromTime();\n const response: SyncResponseBody<T> = { serverSyncedAt };\n\n // Process all changes in parallel\n if (request.changes) {\n response.syncResults = await Promise.all(\n map(request.changes, async (change): Promise<Result> => {\n try {\n const record: ServerRecord<T> = {\n id: change.data.id,\n data: change.data,\n serverSyncedAt,\n deleted: change.type === \"delete\",\n };\n\n await config[operations[change.type]](record);\n return { status: \"success\", id: change.data.id, type: change.type, serverSyncedAt };\n } catch (error) {\n return {\n status: \"error\",\n id: change.data.id,\n type: change.type,\n serverSyncedAt,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }),\n );\n }\n\n if (request.query !== undefined) {\n const result = await config.fetch({ scope: request.scope, query: request.query });\n if (isArray(result)) {\n response.items = result;\n } else {\n response.items = result.items;\n response.serverState = result.serverState;\n }\n }\n\n return response;\n };\n}\n\nconst jsonResponse = (body: unknown, status: number): Response =>\n new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n\nexport function createSyncServer<T, Q = unknown>(handler: CrudHandler<T, Q>) {\n return async (request: Request): Promise<Response> => {\n if (request.method !== \"POST\") {\n return jsonResponse({ error: \"Method not allowed. Use POST.\" }, 405);\n }\n\n let body: SyncRequestBody<T, Q>;\n try {\n body = await request.json();\n } catch {\n return jsonResponse({ error: \"Invalid JSON body\" }, 400);\n }\n\n if (body.query === undefined && !body.changes) {\n return jsonResponse({ error: \"Request body must contain 'query' and/or 'changes'\" }, 400);\n }\n\n try {\n const result = await handler({\n scope: body.scope,\n query: body.query,\n changes: body.changes,\n });\n return jsonResponse(result, 200);\n } catch (error) {\n return jsonResponse(\n { error: error instanceof Error ? error.message : \"Internal server error\" },\n 500,\n );\n }\n };\n}\n"],"names":["operations","createCrudHandler","config","request","serverSyncedAt","getIdFromTime","response","map","change","record","error","result","isArray","jsonResponse","body","status","createSyncServer","handler"],"mappings":";AAsBA,MAAMA,IAA6D;AAAA,EACjE,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,SAASC,EACdC,GACmB;AACnB,SAAO,OAAOC,MAAY;AACxB,UAAMC,IAAiBC,EAAA,GACjBC,IAAgC,EAAE,gBAAAF,EAAA;AA6BxC,QA1BID,EAAQ,YACVG,EAAS,cAAc,MAAM,QAAQ;AAAA,MACnCC,EAAIJ,EAAQ,SAAS,OAAOK,MAA4B;AACtD,YAAI;AACF,gBAAMC,IAA0B;AAAA,YAC9B,IAAID,EAAO,KAAK;AAAA,YAChB,MAAMA,EAAO;AAAA,YACb,gBAAAJ;AAAA,YACA,SAASI,EAAO,SAAS;AAAA,UAAA;AAG3B,uBAAMN,EAAOF,EAAWQ,EAAO,IAAI,CAAC,EAAEC,CAAM,GACrC,EAAE,QAAQ,WAAW,IAAID,EAAO,KAAK,IAAI,MAAMA,EAAO,MAAM,gBAAAJ,EAAA;AAAA,QACrE,SAASM,GAAO;AACd,iBAAO;AAAA,YACL,QAAQ;AAAA,YACR,IAAIF,EAAO,KAAK;AAAA,YAChB,MAAMA,EAAO;AAAA,YACb,gBAAAJ;AAAA,YACA,OAAOM,aAAiB,QAAQA,EAAM,UAAU;AAAA,UAAA;AAAA,QAEpD;AAAA,MACF,CAAC;AAAA,IAAA,IAIDP,EAAQ,UAAU,QAAW;AAC/B,YAAMQ,IAAS,MAAMT,EAAO,MAAM,EAAE,OAAOC,EAAQ,OAAO,OAAOA,EAAQ,MAAA,CAAO;AAChF,MAAIS,EAAQD,CAAM,IAChBL,EAAS,QAAQK,KAEjBL,EAAS,QAAQK,EAAO,OACxBL,EAAS,cAAcK,EAAO;AAAA,IAElC;AAEA,WAAOL;AAAA,EACT;AACF;AAEA,MAAMO,IAAe,CAACC,GAAeC,MACnC,IAAI,SAAS,KAAK,UAAUD,CAAI,GAAG;AAAA,EACjC,QAAAC;AAAA,EACA,SAAS,EAAE,gBAAgB,mBAAA;AAC7B,CAAC;AAEI,SAASC,EAAiCC,GAA4B;AAC3E,SAAO,OAAOd,MAAwC;AACpD,QAAIA,EAAQ,WAAW;AACrB,aAAOU,EAAa,EAAE,OAAO,gCAAA,GAAmC,GAAG;AAGrE,QAAIC;AACJ,QAAI;AACF,MAAAA,IAAO,MAAMX,EAAQ,KAAA;AAAA,IACvB,QAAQ;AACN,aAAOU,EAAa,EAAE,OAAO,oBAAA,GAAuB,GAAG;AAAA,IACzD;AAEA,QAAIC,EAAK,UAAU,UAAa,CAACA,EAAK;AACpC,aAAOD,EAAa,EAAE,OAAO,qDAAA,GAAwD,GAAG;AAG1F,QAAI;AACF,YAAMF,IAAS,MAAMM,EAAQ;AAAA,QAC3B,OAAOH,EAAK;AAAA,QACZ,OAAOA,EAAK;AAAA,QACZ,SAASA,EAAK;AAAA,MAAA,CACf;AACD,aAAOD,EAAaF,GAAQ,GAAG;AAAA,IACjC,SAASD,GAAO;AACd,aAAOG;AAAA,QACL,EAAE,OAAOH,aAAiB,QAAQA,EAAM,UAAU,wBAAA;AAAA,QAClD;AAAA,MAAA;AAAA,IAEJ;AAAA,EACF;AACF;"}
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -1,72 +1,37 @@
|
|
|
1
|
-
import { Change,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
success: true;
|
|
8
|
-
newId?: string;
|
|
9
|
-
} | {
|
|
10
|
-
success: false;
|
|
11
|
-
error: string;
|
|
1
|
+
import { Change, ChangeType, SyncResponse } from '../types';
|
|
2
|
+
export type ServerRecord<T> = {
|
|
3
|
+
id: string;
|
|
4
|
+
data: T;
|
|
5
|
+
serverSyncedAt: string;
|
|
6
|
+
deleted: boolean;
|
|
12
7
|
};
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
data: T;
|
|
20
|
-
} | {
|
|
21
|
-
success: false;
|
|
22
|
-
error: {
|
|
23
|
-
message: string;
|
|
24
|
-
};
|
|
25
|
-
};
|
|
8
|
+
export type LocalRecord<T> = {
|
|
9
|
+
id: string;
|
|
10
|
+
data: T;
|
|
11
|
+
serverSyncedAt: string;
|
|
12
|
+
deleted: boolean;
|
|
13
|
+
lastOperation: ChangeType;
|
|
26
14
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
export type
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
anySucceeded: boolean;
|
|
42
|
-
/** Summary counts */
|
|
43
|
-
summary: {
|
|
44
|
-
total: number;
|
|
45
|
-
succeeded: number;
|
|
46
|
-
failed: number;
|
|
47
|
-
};
|
|
15
|
+
export type MetadataRecord = {
|
|
16
|
+
id: string;
|
|
17
|
+
value: string;
|
|
18
|
+
};
|
|
19
|
+
export type LocalSyncClientConfig = {
|
|
20
|
+
dbName: string;
|
|
21
|
+
version?: number;
|
|
22
|
+
remoteSyncEndpoint?: string;
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
scope?: string;
|
|
25
|
+
collectionId?: string;
|
|
26
|
+
debounce?: number;
|
|
27
|
+
maxRetries?: number;
|
|
28
|
+
batchSize?: number;
|
|
48
29
|
};
|
|
49
|
-
/**
|
|
50
|
-
* Categorize sync results into successful and failed
|
|
51
|
-
*/
|
|
52
|
-
export declare function categorizeResults(results: SyncResult[]): SyncBatchResult;
|
|
53
|
-
/**
|
|
54
|
-
* Request body for the unified POST endpoint
|
|
55
|
-
*/
|
|
56
30
|
export type SyncRequestBody<T, Q = unknown> = {
|
|
57
|
-
/** Optional scope identifier for selecting storage on the backend */
|
|
58
31
|
scope?: string;
|
|
59
|
-
/** Query parameters for fetching items */
|
|
60
32
|
query?: Q;
|
|
61
|
-
/** Changes to sync */
|
|
62
33
|
changes?: Change<T>[];
|
|
63
34
|
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
*/
|
|
67
|
-
export type SyncResponseBody<T> = {
|
|
68
|
-
/** Fetched items (when query was provided) */
|
|
69
|
-
results?: T[];
|
|
70
|
-
/** Sync results (when changes were provided) */
|
|
71
|
-
syncResults?: SyncResult[];
|
|
35
|
+
export type SyncResponseBody<T, S = unknown> = SyncResponse<T> & {
|
|
36
|
+
serverState?: S;
|
|
72
37
|
};
|