@interncom/diplomatic 0.3.3 → 0.4.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/web/batch.d.ts +7 -0
- package/dist/web/client.d.ts +14 -20
- package/dist/web/index.mjs +1 -1
- package/dist/web/openClient.d.ts +11 -0
- package/dist/web/progress.d.ts +1 -1
- package/dist/web/react/useClient.d.ts +6 -1
- package/dist/web/sync.d.ts +36 -16
- package/dist/web/worker/client.d.ts +20 -1
- package/dist/web/worker/runtime.d.ts +6 -0
- package/dist/web/worker.mjs +1 -1
- package/package.json +1 -1
package/dist/web/openClient.d.ts
CHANGED
|
@@ -13,6 +13,16 @@ import type { IClient, IStore } from "./types";
|
|
|
13
13
|
* (built as `worker.mjs` in the published package). It must run as a
|
|
14
14
|
* **module** worker (`type: "module"`).
|
|
15
15
|
*
|
|
16
|
+
* ## Handshake (race-safe)
|
|
17
|
+
*
|
|
18
|
+
* The worker posts an unsolicited `{ kind: "ready" }` after init. Apps often
|
|
19
|
+
* construct the Worker at module load (or before `openDiplomaticClient` finishes
|
|
20
|
+
* opening IndexedDB), so that event can fire before the library sets
|
|
21
|
+
* `onmessage`. **That is fine:** connect also probes with a request/response
|
|
22
|
+
* `ping`. The worker holds commands until init completes, so the probe succeeds
|
|
23
|
+
* even if `ready` was dropped. Do **not** reimplement message buffering in the
|
|
24
|
+
* app unless you need it for other reasons.
|
|
25
|
+
*
|
|
16
26
|
* ## Vite (recommended for SPA templates)
|
|
17
27
|
*
|
|
18
28
|
* ```ts
|
|
@@ -23,6 +33,7 @@ import type { IClient, IStore } from "./types";
|
|
|
23
33
|
*
|
|
24
34
|
* `?worker` makes Vite emit a real worker asset and a constructor. Create the
|
|
25
35
|
* instance once (module scope or `useMemo`/`useRef`) — not on every render.
|
|
36
|
+
* Early construction is supported; the handshake recovers if `ready` is missed.
|
|
26
37
|
*
|
|
27
38
|
* ## webpack / Rollup / esbuild / Parcel (`new URL` + import.meta.url)
|
|
28
39
|
*
|
package/dist/web/progress.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
*
|
|
3
3
|
* Exposed only via `IDiplomaticClientXferState.progress` on `client.xferState`
|
|
4
4
|
* (get + listen / `useClientXferState`). There is no separate progress channel. */
|
|
5
|
-
export type SyncPhase = "peek" | "
|
|
5
|
+
export type SyncPhase = "peek" | "pull" | "open" | "exec" | "push" | "import" | "idle";
|
|
6
6
|
export interface SyncProgressEvent {
|
|
7
7
|
phase: SyncPhase;
|
|
8
8
|
/** Host label when the work is host-scoped. */
|
|
@@ -19,11 +19,16 @@ type UseClientBase = {
|
|
|
19
19
|
* import DiplomaticWorker from "@interncom/diplomatic/worker?worker";
|
|
20
20
|
* const syncWorker = new DiplomaticWorker();
|
|
21
21
|
* useClient({ worker: syncWorker, seed, host });
|
|
22
|
+
*
|
|
23
|
+
* Handshake is race-safe (ready event and/or probe ping). See
|
|
24
|
+
* `openDiplomaticClient` for bundler recipes and handshake notes.
|
|
22
25
|
*/
|
|
23
26
|
export type UseClientWorkerOptions = UseClientBase & {
|
|
24
27
|
/**
|
|
25
28
|
* App-constructed sync Worker. Create once (module scope or useMemo/useRef),
|
|
26
|
-
* not each render.
|
|
29
|
+
* not each render. Early construction before `useClient` opens IDB is OK —
|
|
30
|
+
* the library does not require catching the unsolicited `ready` event.
|
|
31
|
+
* See `openDiplomaticClient` for instantiation recipes.
|
|
27
32
|
*/
|
|
28
33
|
worker: Worker;
|
|
29
34
|
store?: never;
|
package/dist/web/sync.d.ts
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import DiplomaticClientAPI from "./shared/client";
|
|
2
|
-
import { IClock } from "./shared/clock";
|
|
3
2
|
import { Status } from "./shared/consts";
|
|
4
3
|
import { Enclave } from "./shared/enclave";
|
|
5
4
|
import { Hash, HostHandle, IBag, ICrypto } from "./shared/types";
|
|
5
|
+
import { ValStat } from "./shared/valstat";
|
|
6
6
|
import { ProgressFn } from "./progress";
|
|
7
7
|
import { IDownloadMessage, IHostRow, IMsgParts, IStore, type IStoredMessageWrite } from "./types";
|
|
8
8
|
/** Default soft cap for one push/pull request (~1 MiB). Apps with large
|
|
9
9
|
* payloads (e.g. media) should raise maxPushBytes / maxPullBytes. */
|
|
10
10
|
export declare const defaultMaxPushBytes: number;
|
|
11
11
|
export declare const defaultMaxPullBytes: number;
|
|
12
|
+
/** Pull result held in memory until open (not durable). */
|
|
13
|
+
export type IPulled = {
|
|
14
|
+
dl: IDownloadMessage;
|
|
15
|
+
bodyCph?: Uint8Array;
|
|
16
|
+
};
|
|
17
|
+
/** Host connection methods used by sync phases. */
|
|
18
|
+
export type SyncConn<Handle extends HostHandle> = Pick<DiplomaticClientAPI<Handle>, "pull" | "push" | "peek" | "seal" | "keys">;
|
|
12
19
|
export interface ISyncParams<Handle extends HostHandle> {
|
|
13
|
-
conn:
|
|
20
|
+
conn: SyncConn<Handle>;
|
|
14
21
|
store: IStore<Handle>;
|
|
15
22
|
enclave: Enclave;
|
|
16
|
-
clock: IClock;
|
|
17
23
|
host: IHostRow<Handle>;
|
|
18
24
|
crypto: ICrypto;
|
|
19
25
|
/** Soft max sealed-bag bytes per push request. Oversized bags go alone. */
|
|
@@ -27,19 +33,33 @@ export interface ISyncParams<Handle extends HostHandle> {
|
|
|
27
33
|
}
|
|
28
34
|
/** Push one batch of sealed bags; deq successes; advance lastSeq from store. */
|
|
29
35
|
export declare function pushBatch<Handle extends HostHandle>(conn: Pick<DiplomaticClientAPI<Handle>, "push">, store: IStore<Handle>, hostLabel: string, bags: IBag[], hashes: Hash[]): Promise<Status>;
|
|
30
|
-
/**
|
|
31
|
-
export declare function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
/** pull: network only. Download-queue items → ciphertext (still enqueued). */
|
|
37
|
+
export declare function pullBodies<Handle extends HostHandle>(conn: Pick<DiplomaticClientAPI<Handle>, "pull">, items: IDownloadMessage[]): Promise<ValStat<IPulled[]>>;
|
|
38
|
+
export type IOpened = {
|
|
39
|
+
parts: IMsgParts[];
|
|
40
|
+
hashes: Hash[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* open: decrypt pulled bodies → msg archive (apld=false), deq downloads.
|
|
44
|
+
* Bad bags are dequeued and skipped (not retry-able).
|
|
45
|
+
* Does not exec or push.
|
|
46
|
+
*/
|
|
47
|
+
export declare function openPulled<Handle extends HostHandle>(store: IStore<Handle>, enclave: Enclave, crypto: ICrypto, items: IPulled[]): Promise<ValStat<IOpened>>;
|
|
48
|
+
/** Discover unseen bags and enqueue download work; advance host lastSeq. */
|
|
35
49
|
export declare function syncPeek<Handle extends HostHandle>({ conn, store, enclave, host, crypto, onProgress, peekProgressEvery, }: ISyncParams<Handle>): Promise<Status>;
|
|
50
|
+
/** Seal and upload pending msgs; list once so concurrent enqs wait for next sync. */
|
|
36
51
|
export declare function syncPush<Handle extends HostHandle>({ conn, store, host, maxPushBytes, onProgress }: ISyncParams<Handle>): Promise<Status>;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Pull + open for one host, depth-1 pipelined:
|
|
54
|
+
* await pull(i); start pull(i+1); open(i); afterOpen? (exec)
|
|
55
|
+
* Ciphertext only in the in-flight Promise, never IDB.
|
|
56
|
+
*/
|
|
57
|
+
export declare function syncPull<Handle extends HostHandle>({ conn, store, enclave, host, crypto, maxPullBytes, onProgress, }: ISyncParams<Handle>,
|
|
58
|
+
/** After each opened pull batch (e.g. drainApplyQueue / exec). */
|
|
59
|
+
afterOpen?: () => Promise<void>): Promise<Status>;
|
|
41
60
|
export declare function msg2StoredMsgData({ head, body }: IMsgParts): IStoredMessageWrite;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
61
|
+
/**
|
|
62
|
+
* notif → open inline bodies into archive; enq incomplete → scheduleSync.
|
|
63
|
+
* `scheduleSync` runs full peek/push/pull (or worker handoff).
|
|
64
|
+
*/
|
|
65
|
+
export declare function handleNotif<Handle extends HostHandle>(bytes: Uint8Array, { conn, store, enclave, host, crypto, onProgress, }: ISyncParams<Handle>, scheduleSync: () => void): Promise<void>;
|
|
@@ -8,11 +8,19 @@ import type { IClient, IDiplomaticClientState, IDiplomaticClientXferState, IHost
|
|
|
8
8
|
*
|
|
9
9
|
* Provide a live `Worker` — the library never constructs one. See
|
|
10
10
|
* `openDiplomaticClient` for bundler/CDN instantiation recipes.
|
|
11
|
+
*
|
|
12
|
+
* Handshake is race-safe: the worker posts unsolicited `{ kind: "ready" }`, but
|
|
13
|
+
* connect also probes with `ping`. Early construction (module scope) is fine even
|
|
14
|
+
* if `ready` fired before `onmessage` was set — the ping still succeeds once the
|
|
15
|
+
* worker has finished init (cmds are held until then on the worker side).
|
|
11
16
|
*/
|
|
12
17
|
export type WorkerClientOptions = {
|
|
13
18
|
/** Already-constructed module Worker running `@interncom/diplomatic/worker`. */
|
|
14
19
|
worker: Worker;
|
|
15
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Max wait for handshake (`ready` event or probe ping; default 15s).
|
|
22
|
+
* Failures throw; no fallback.
|
|
23
|
+
*/
|
|
16
24
|
readyTimeoutMs?: number;
|
|
17
25
|
clock?: IClock;
|
|
18
26
|
/**
|
|
@@ -48,8 +56,19 @@ export declare class WorkerClient implements IClient<URL> {
|
|
|
48
56
|
* Attach to an app-provided Worker. `store` is the shared protocol IDB (main
|
|
49
57
|
* connection) used for local msg writes; worker opens its own connection.
|
|
50
58
|
* Throws if the worker never becomes ready — does not fall back to main thread.
|
|
59
|
+
*
|
|
60
|
+
* Handshake: wait for unsolicited `ready` **or** a successful probe `ping`.
|
|
61
|
+
* The probe covers the common case where the app started the Worker early and
|
|
62
|
+
* `ready` was dropped before this thread set `onmessage`.
|
|
51
63
|
*/
|
|
52
64
|
static connect(state: IStateManager, store: IStore<URL>, opts: WorkerClientOptions): Promise<WorkerClient>;
|
|
65
|
+
/** Resolve the ready barrier (idempotent). */
|
|
66
|
+
private markReady;
|
|
67
|
+
/**
|
|
68
|
+
* Active handshake: post ping without waiting for the ready event.
|
|
69
|
+
* On pong, mark ready so connect can proceed even if `ready` was missed.
|
|
70
|
+
*/
|
|
71
|
+
private probeReady;
|
|
53
72
|
/** Lightweight RPC check after connect. */
|
|
54
73
|
ping(): Promise<void>;
|
|
55
74
|
/** Terminate the worker (drops protocol DB connection in that thread). */
|
|
@@ -4,8 +4,14 @@ export type PostFn = (msg: WorkerEvent, transfer?: Transferable[]) => void;
|
|
|
4
4
|
export declare class WorkerRuntime {
|
|
5
5
|
private client;
|
|
6
6
|
private post;
|
|
7
|
+
/** Resolves when init finishes (success or failure). Cmds wait on this. */
|
|
8
|
+
private whenReady;
|
|
9
|
+
private resolveReady;
|
|
10
|
+
private rejectReady;
|
|
7
11
|
constructor(post: PostFn);
|
|
8
12
|
init(): Promise<void>;
|
|
13
|
+
private markReady;
|
|
14
|
+
private failReady;
|
|
9
15
|
private requireClient;
|
|
10
16
|
private emitClientState;
|
|
11
17
|
private emitXferState;
|