@kumiai/hub-server 0.12.2 → 0.13.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/lib/handlers.js CHANGED
@@ -624,7 +624,10 @@ export function createHandlers(params) {
624
624
  logUnackedFrames();
625
625
  tornDown = true;
626
626
  notifyWindow();
627
- if (receiveToken != null) registry.releaseReceiveWriter(clientDID, receiveToken);
627
+ if (receiveToken != null) registry.releaseReceiveWriter({
628
+ did: clientDID,
629
+ token: receiveToken
630
+ });
628
631
  registry.unregisterIfIdle(clientDID);
629
632
  reader.cancel().catch(()=>{});
630
633
  writer.abort(new Error('receive channel torn down')).catch(()=>{});
@@ -718,7 +721,11 @@ export function createHandlers(params) {
718
721
  // Binding evicts whatever held the lane: a reconnect means the old connection broke and the
719
722
  // server learns last, so the stale writer must give way to the live one. See
720
723
  // `HubClientRegistry.bindReceiveWriter`.
721
- const { token, evicted } = registry.bindReceiveWriter(clientDID, onLive, ()=>endEvicted?.());
724
+ const { token, evicted } = registry.bindReceiveWriter({
725
+ did: clientDID,
726
+ writer: onLive,
727
+ endReceive: ()=>endEvicted?.()
728
+ });
722
729
  receiveToken = token;
723
730
  // After the bind, so the lane is never unheld between the two.
724
731
  evicted?.();
@@ -770,7 +777,10 @@ export function createHandlers(params) {
770
777
  if (!tornDown) logUnackedFrames();
771
778
  tornDown = true;
772
779
  notifyWindow();
773
- if (receiveToken != null) registry.releaseReceiveWriter(clientDID, receiveToken);
780
+ if (receiveToken != null) registry.releaseReceiveWriter({
781
+ did: clientDID,
782
+ token: receiveToken
783
+ });
774
784
  registry.unregisterIfIdle(clientDID);
775
785
  reader.cancel().catch(()=>{});
776
786
  writer.abort(error).catch(()=>{});
package/lib/hub.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { ServerTransportOf } from '@enkaku/protocol';
2
2
  import type { AccessRules, ReplayOptions, ResourceLimits, Server } from '@enkaku/server';
3
3
  import type { VerifyTokenHook } from '@kokuin/capability';
4
- import type { Identity } from '@kokuin/token';
4
+ import type { CryptoOptions, Identity } from '@kokuin/token';
5
5
  import type { HubProtocol, HubStore, WakeRegistry, WakeSender } from '@kumiai/hub-protocol';
6
6
  import { type AuthorizeHook, type HubRateLimits, type HubStoreErrorHook, type KeyPackageFetchLimits } from './handlers.js';
7
7
  import { HubClientRegistry } from './registry.js';
@@ -28,7 +28,7 @@ export type HubPurgeOptions = {
28
28
  };
29
29
  /** Replay settings a host may tune. The hub always enables replay checks and rejects stale tokens. */
30
30
  export type HubReplayOptions = Omit<ReplayOptions, 'enabled' | 'rejectStale'>;
31
- export type CreateHubParams = {
31
+ export type CreateHubParams = CryptoOptions & {
32
32
  transport: ServerTransportOf<HubProtocol>;
33
33
  store: HubStore;
34
34
  /**
package/lib/hub.js CHANGED
@@ -55,6 +55,7 @@ export function createHub(params) {
55
55
  protocol: hubProtocol,
56
56
  transport: params.transport,
57
57
  identity: params.identity,
58
+ crypto: params.crypto,
58
59
  accessRules: params.accessRules ?? DEFAULT_HUB_ACCESS_RULES,
59
60
  verifyToken: params.verifyToken,
60
61
  replay: {
package/lib/index.d.ts CHANGED
@@ -4,6 +4,6 @@ export type { CreateHubParams, HubInstance, HubPurgeOptions, HubReplayOptions }
4
4
  export { createHub, DEFAULT_HUB_ACCESS_RULES } from './hub.js';
5
5
  export { createMemoryStore, type MemoryStoreOptions } from './memoryStore.js';
6
6
  export { createRateLimiter, type RateLimitConfig, type RateLimiter } from './rateLimit.js';
7
- export type { ClientEntry } from './registry.js';
7
+ export type { ClientEntry, HubClientRegistryBindReceiveWriterParams, HubClientRegistryReleaseReceiveWriterParams, } from './registry.js';
8
8
  export { HubClientRegistry } from './registry.js';
9
9
  export { createWakeDispatcher, type WakeDispatcher, type WakeDispatcherParams, type WakeNotifyParams, } from './wake.js';
package/lib/registry.d.ts CHANGED
@@ -7,6 +7,15 @@ export type ClientEntry = {
7
7
  /** Identifies the binding, so a channel can only ever release its OWN. */
8
8
  token: symbol | null;
9
9
  };
10
+ export type HubClientRegistryBindReceiveWriterParams = {
11
+ did: string;
12
+ writer: (message: StoredMessage) => void;
13
+ endReceive: () => void;
14
+ };
15
+ export type HubClientRegistryReleaseReceiveWriterParams = {
16
+ did: string;
17
+ token: symbol;
18
+ };
10
19
  /**
11
20
  * Tracks online clients and their live receive-channel writers. Subscription
12
21
  * state is durable in the store, not here — the registry only routes live
@@ -39,12 +48,12 @@ export declare class HubClientRegistry {
39
48
  * it. So a release names the binding it is releasing, and one that is no longer current is a
40
49
  * no-op.
41
50
  */
42
- bindReceiveWriter(did: string, writer: (message: StoredMessage) => void, endReceive: () => void): {
51
+ bindReceiveWriter({ did, writer, endReceive }: HubClientRegistryBindReceiveWriterParams): {
43
52
  token: symbol;
44
53
  evicted: (() => void) | null;
45
54
  };
46
55
  /** Clear the binding this token names. A token that is no longer current is a no-op. */
47
- releaseReceiveWriter(did: string, token: symbol): void;
56
+ releaseReceiveWriter({ did, token }: HubClientRegistryReleaseReceiveWriterParams): void;
48
57
  getClient(did: string): ClientEntry | undefined;
49
58
  isOnline(did: string): boolean;
50
59
  isWriterBound(did: string): boolean;
package/lib/registry.js CHANGED
@@ -47,7 +47,7 @@
47
47
  * null the writer the new channel has just bound, leaving the DID online with nothing behind
48
48
  * it. So a release names the binding it is releasing, and one that is no longer current is a
49
49
  * no-op.
50
- */ bindReceiveWriter(did, writer, endReceive) {
50
+ */ bindReceiveWriter({ did, writer, endReceive }) {
51
51
  const entry = this.#clients.get(did);
52
52
  if (entry == null) return {
53
53
  token: Symbol('unbound'),
@@ -63,7 +63,7 @@
63
63
  evicted
64
64
  };
65
65
  }
66
- /** Clear the binding this token names. A token that is no longer current is a no-op. */ releaseReceiveWriter(did, token) {
66
+ /** Clear the binding this token names. A token that is no longer current is a no-op. */ releaseReceiveWriter({ did, token }) {
67
67
  const entry = this.#clients.get(did);
68
68
  if (entry == null || entry.token !== token) return;
69
69
  entry.sendMessage = null;
package/lib/wake.js CHANGED
@@ -31,12 +31,15 @@ const DEFAULT_DEBOUNCE_MS = 10_000;
31
31
  const registration = await params.registry.get(did);
32
32
  if (registration == null) return;
33
33
  const body = sealWakeHint({
34
- topicID,
35
- sequenceID,
36
- count
37
- }, {
38
- publicKey: fromB64U(registration.publicKey),
39
- authSecret: fromB64U(registration.authSecret)
34
+ hint: {
35
+ topicID,
36
+ sequenceID,
37
+ count
38
+ },
39
+ recipient: {
40
+ publicKey: fromB64U(registration.publicKey),
41
+ authSecret: fromB64U(registration.authSecret)
42
+ }
40
43
  });
41
44
  const verdict = await params.sender.send({
42
45
  registration,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kumiai/hub-server",
3
- "version": "0.12.2",
3
+ "version": "0.13.0",
4
4
  "description": "Hub server for Enkaku E2EE group message routing",
5
5
  "keywords": [
6
6
  "hub",
@@ -25,20 +25,21 @@
25
25
  "lib/*"
26
26
  ],
27
27
  "dependencies": {
28
- "@enkaku/protocol": "^0.22.5",
29
- "@enkaku/server": "^0.22.5",
30
- "@kokuin/capability": "^0.5.2",
31
- "@kokuin/token": "^0.6.4",
32
- "@kumiai/hub-protocol": "^0.12.0",
28
+ "@enkaku/protocol": "^0.23.0",
29
+ "@enkaku/server": "^0.23.0",
30
+ "@kokuin/capability": "^0.7.0",
31
+ "@kokuin/token": "^0.7.0",
32
+ "@kumiai/hub-protocol": "^0.13.0",
33
33
  "@sozai/codec": "^0.4.4",
34
34
  "@sozai/event": "^0.1.6",
35
35
  "@sozai/log": "^0.4.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@enkaku/client": "^0.22.5",
39
- "@enkaku/transport": "^0.22.5",
40
- "@kumiai/hub-conformance": "^0.12.0",
41
- "@kumiai/hub-wake": "^0.12.0"
38
+ "@enkaku/client": "^0.23.0",
39
+ "@enkaku/transport": "^0.23.0",
40
+ "@kokuin/crypto": "^0.7.0",
41
+ "@kumiai/hub-conformance": "^0.13.0",
42
+ "@kumiai/hub-wake": "^0.13.0"
42
43
  },
43
44
  "publishConfig": {
44
45
  "access": "public"