@calimero-network/mero-js 12.0.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -288,9 +288,12 @@ export interface Namespace {
288
288
  namespaceId: string;
289
289
  appKey: string;
290
290
  targetApplicationId: string;
291
- /** @deprecated Always `"LazyOnAccess"`. Core keeps the key only for the
292
- * released Python client and drops it once that floor moves. */
293
- upgradePolicy: string;
291
+ /**
292
+ * Absent from nodes that have dropped the concept, always `"LazyOnAccess"` on
293
+ * every released one. Optional because this SDK talks to both; it carries no
294
+ * information either way. Delete once no supported release still sends it.
295
+ */
296
+ upgradePolicy?: string;
294
297
  createdAt: number;
295
298
  name?: string;
296
299
  memberCount: number;
@@ -436,15 +439,25 @@ export interface GroupUpgradeStatus {
436
439
  initiatedAt: number;
437
440
  initiatedBy: string;
438
441
  status: string;
439
- total?: number;
440
- completed?: number;
441
- failed?: number;
442
+ /** Contexts THIS NODE enumerated for the upgrade. Node-local; fleet progress
443
+ * is the `getMigrationStatus` rollup. */
444
+ localContextsTotal?: number;
445
+ localContextsSwapped?: number;
446
+ /** Contexts whose swap failed on this node; a non-zero value is what
447
+ * `retryGroupUpgrade` picks up. */
448
+ localContextsFailed?: number;
449
+ /** Unix seconds at which THIS NODE finished its own context swaps. Not fleet
450
+ * convergence - that is `MigrationStatus.fleetCompletedAt`. */
442
451
  completedAt?: number;
443
452
  }
444
453
  export type MemberMigrationState = 'migrated' | 'in_progress' | 'unknown' | 'failed';
445
454
  /** Why a member's migration did not complete. */
446
455
  export type MigrationFailureReason = 'check_aborted' | 'apply_failed' | 'no_migration_path';
447
456
  export interface MemberMigrationReport {
457
+ /** ABI state version the member has loaded, from `#[app::state(version = N)]` -
458
+ * the engine's migration gate, not the bundle semver and not a CRDT concept.
459
+ * The wrong reading here is how the core rollup defect (comparing bundle-semver
460
+ * majors instead of state versions) went unnoticed. */
448
461
  schemaVersion: number;
449
462
  residueAuto: number;
450
463
  syncedUpToHlc: number;
@@ -477,7 +490,14 @@ export interface MigrationStatusRollup {
477
490
  export interface MigrationStatus {
478
491
  targetVersion: number;
479
492
  expectedMembers: number;
493
+ /** Governance HLC the cohort was pinned at, as an opaque display string.
494
+ * Absent when there is no migration record. */
480
495
  cohortPinnedAtHlc?: string;
496
+ /** Unix seconds at which this node watched the FLEET converge, absent while it
497
+ * has not. Distinct from `GroupUpgradeStatus.completedAt`, which is this node's
498
+ * own local swap completion. Durable, unlike `rollup.allMigrated`, which is
499
+ * recomputed from in-TTL heartbeats and lapses when a member goes quiet. */
500
+ fleetCompletedAt?: number;
481
501
  rollup: MigrationStatusRollup;
482
502
  members: MemberMigrationStatusEntry[];
483
503
  }
@@ -490,9 +510,12 @@ export interface GroupInfo {
490
510
  groupId: string;
491
511
  appKey: string;
492
512
  targetApplicationId: string;
493
- /** @deprecated Always `"LazyOnAccess"`. Core keeps the key only for the
494
- * released Python client and drops it once that floor moves. */
495
- upgradePolicy: string;
513
+ /**
514
+ * Absent from nodes that have dropped the concept, always `"LazyOnAccess"` on
515
+ * every released one. Optional because this SDK talks to both; it carries no
516
+ * information either way. Delete once no supported release still sends it.
517
+ */
518
+ upgradePolicy?: string;
496
519
  memberCount: number;
497
520
  contextCount: number;
498
521
  activeUpgrade?: GroupUpgradeStatus;
@@ -676,9 +699,9 @@ export interface UpgradeGroupRequest {
676
699
  export interface UpgradeGroupResponseData {
677
700
  groupId: string;
678
701
  status: string;
679
- total?: number;
680
- completed?: number;
681
- failed?: number;
702
+ localContextsTotal?: number;
703
+ localContextsSwapped?: number;
704
+ localContextsFailed?: number;
682
705
  }
683
706
  export type GroupUpgradeStatusResponseData = GroupUpgradeStatus | null;
684
707
  export interface RetryGroupUpgradeRequest {
@@ -3,7 +3,92 @@ export interface GroupMembershipEventData {
3
3
  groupId: string;
4
4
  type: 'MemberJoined' | 'MemberAdded' | 'MemberRemoved';
5
5
  data: {
6
- member: string;
7
- role?: string;
6
+ /** The member's ACCOUNT, hex-encoded 32 bytes (64 chars) - the principal the
7
+ * governance rows name. Not a bs58 signing key: the field this replaced
8
+ * carried one, and both are strings, so the rename is what makes a stale
9
+ * consumer fail loudly instead of comparing accounts against keys forever. */
10
+ memberAccount: string;
11
+ /** Absent on `MemberRemoved`, and on a `MemberJoined` inherited from an Open
12
+ * subgroup. Core's set is closed. */
13
+ role?: 'Admin' | 'Member' | 'ReadOnly' | 'ReadOnlyTee';
8
14
  };
9
15
  }
16
+ /**
17
+ * A migration was accepted and its target ABI state version resolved.
18
+ * `toStateVersion` is the `#[app::state(version = N)]` number, not the bundle
19
+ * semver (`toVersion`).
20
+ */
21
+ export interface MigrationStartedData {
22
+ fromVersion: string;
23
+ toVersion: string;
24
+ toStateVersion: number;
25
+ /** Contexts the EMITTING NODE enumerated for the migration. Node-local, never
26
+ * the fleet cohort size that `MigrationProgressData.total` carries. */
27
+ localContextsTotal: number;
28
+ }
29
+ /**
30
+ * Fleet rollup counters, recomputed as peers' heartbeat facts change. Counters
31
+ * only: the per-member detail behind them stays in the admin-gated
32
+ * `getMigrationStatus` read.
33
+ */
34
+ export interface MigrationProgressData {
35
+ migrated: number;
36
+ inProgress: number;
37
+ unknown: number;
38
+ failed: number;
39
+ /** The pinned FLEET COHORT size, never a node-local context count like
40
+ * `MigrationStartedData.localContextsTotal`. */
41
+ total: number;
42
+ }
43
+ /**
44
+ * One subgroup's local context swaps advanced on the emitting node.
45
+ *
46
+ * Admin-only: it names a descendant subgroup, which a plain namespace member
47
+ * may not enumerate, so core withholds it from non-admin subscribers. A
48
+ * non-admin never receiving this variant is correct behaviour, not a gap.
49
+ */
50
+ export interface CascadeProgressData {
51
+ /** Hex-encoded descendant subgroup id, never the namespace root the event is
52
+ * keyed on. */
53
+ subgroupId: string;
54
+ localContextsSwapped: number;
55
+ /** Contexts the emitting node holds for THIS SUBGROUP. Node-local and
56
+ * per-subgroup; unrelated to both sibling totals. */
57
+ localContextsTotal: number;
58
+ }
59
+ /** Every pinned-cohort member reported the target version. */
60
+ export interface MigrationCompletedData {
61
+ toVersion: string;
62
+ /** FLEET convergence, in seconds since the epoch: the same stamp
63
+ * `MigrationStatus.fleetCompletedAt` returns. Not `GroupUpgradeStatus.completedAt`,
64
+ * which is this node's own local swap completion. */
65
+ completedAt: number;
66
+ }
67
+ /**
68
+ * Parsed group-migration event (core's `GroupMigration` `NodeEvent` variant),
69
+ * keyed on the namespace root a client subscribes with.
70
+ *
71
+ * `MigrationStarted`, `MigrationProgress` and `MigrationCompleted` reach every
72
+ * subscribed member; `CascadeProgress` reaches namespace admins only.
73
+ */
74
+ export type GroupMigrationEventData = {
75
+ groupId: string;
76
+ type: 'MigrationStarted';
77
+ data: MigrationStartedData;
78
+ } | {
79
+ groupId: string;
80
+ type: 'MigrationProgress';
81
+ data: MigrationProgressData;
82
+ } | {
83
+ groupId: string;
84
+ type: 'CascadeProgress';
85
+ data: CascadeProgressData;
86
+ } | {
87
+ groupId: string;
88
+ type: 'MigrationCompleted';
89
+ data: MigrationCompletedData;
90
+ };
91
+ /** Narrows a raw `'event'` payload to the group-migration family by its tag. */
92
+ export declare function isGroupMigrationEvent(event: {
93
+ type?: string;
94
+ }): event is GroupMigrationEventData;
@@ -1 +1,10 @@
1
- export {};
1
+ const MIGRATION_EVENT_TYPES = new Set([
2
+ 'MigrationStarted',
3
+ 'MigrationProgress',
4
+ 'CascadeProgress',
5
+ 'MigrationCompleted',
6
+ ]);
7
+ /** Narrows a raw `'event'` payload to the group-migration family by its tag. */
8
+ export function isGroupMigrationEvent(event) {
9
+ return event.type !== undefined && MIGRATION_EVENT_TYPES.has(event.type);
10
+ }
@@ -2,4 +2,4 @@ export { SseClient } from './sse.js';
2
2
  export type { SseEventData, AppVersionChangedEvent } from './sse.js';
3
3
  export { WsClient } from './ws.js';
4
4
  export type { WsEventData } from './ws.js';
5
- export type { GroupMembershipEventData } from './group.js';
5
+ export type { GroupMembershipEventData, GroupMigrationEventData, MigrationStartedData, MigrationProgressData, CascadeProgressData, MigrationCompletedData, } from './group.js';
@@ -1,5 +1,5 @@
1
- import type { GroupMembershipEventData } from './group.js';
2
- export type { GroupMembershipEventData };
1
+ import type { GroupMembershipEventData, GroupMigrationEventData } from './group.js';
2
+ export type { GroupMembershipEventData, GroupMigrationEventData };
3
3
  export interface SseEventData {
4
4
  contextId: string;
5
5
  /** The context-event discriminator (core serializes it as a sibling of
@@ -13,7 +13,10 @@ export interface AppVersionChangedEvent {
13
13
  fromVersion?: string;
14
14
  toVersion?: string;
15
15
  }
16
- type SseEventHandler = (event: SseEventData | GroupMembershipEventData) => void;
16
+ /** Anything the `'event'` stream can deliver: context events plus the
17
+ * group-keyed membership and migration families. */
18
+ type SseEvent = SseEventData | GroupMembershipEventData | GroupMigrationEventData;
19
+ type SseEventHandler = (event: SseEvent) => void;
17
20
  type SseConnectHandler = (sessionId: string) => void;
18
21
  type SseErrorHandler = (error: Error) => void;
19
22
  export declare class SseClient {
@@ -44,6 +47,16 @@ export declare class SseClient {
44
47
  * Returns an unsubscribe closure (so callers need not retain the listener).
45
48
  */
46
49
  onAppVersionChanged(handler: (e: AppVersionChangedEvent) => void): () => void;
50
+ /**
51
+ * Typed convenience over the generic `'event'` stream: invokes `handler` only
52
+ * for group-migration events, narrowed on `type` so `data` is the matching
53
+ * payload. Returns an unsubscribe closure.
54
+ *
55
+ * A non-admin subscriber sees `MigrationStarted`, `MigrationProgress` and
56
+ * `MigrationCompleted` but never `CascadeProgress`, which core delivers to
57
+ * namespace admins only.
58
+ */
59
+ onMigrationEvent(handler: (e: GroupMigrationEventData) => void): () => void;
47
60
  private emit;
48
61
  connect(): Promise<void>;
49
62
  private readStream;
@@ -1,3 +1,4 @@
1
+ import { isGroupMigrationEvent } from './group.js';
1
2
  export class SseClient {
2
3
  constructor(opts) {
3
4
  this.sessionId = null;
@@ -47,6 +48,23 @@ export class SseClient {
47
48
  this.on('event', listener);
48
49
  return () => this.off('event', listener);
49
50
  }
51
+ /**
52
+ * Typed convenience over the generic `'event'` stream: invokes `handler` only
53
+ * for group-migration events, narrowed on `type` so `data` is the matching
54
+ * payload. Returns an unsubscribe closure.
55
+ *
56
+ * A non-admin subscriber sees `MigrationStarted`, `MigrationProgress` and
57
+ * `MigrationCompleted` but never `CascadeProgress`, which core delivers to
58
+ * namespace admins only.
59
+ */
60
+ onMigrationEvent(handler) {
61
+ const listener = (ev) => {
62
+ if (isGroupMigrationEvent(ev))
63
+ handler(ev);
64
+ };
65
+ this.on('event', listener);
66
+ return () => this.off('event', listener);
67
+ }
50
68
  emit(event, arg) {
51
69
  const key = event;
52
70
  if (key in this.listeners) {
@@ -182,7 +200,8 @@ export class SseClient {
182
200
  });
183
201
  return;
184
202
  }
185
- // Group-membership event message (untagged NodeEvent's group variant)
203
+ // Group-keyed event message (untagged NodeEvent's membership and
204
+ // migration variants; the `type` tag tells them apart).
186
205
  if (msg.result.groupId) {
187
206
  this.emit('event', {
188
207
  groupId: msg.result.groupId,
@@ -1,5 +1,5 @@
1
- import type { GroupMembershipEventData } from './group.js';
2
- export type { GroupMembershipEventData };
1
+ import type { GroupMembershipEventData, GroupMigrationEventData } from './group.js';
2
+ export type { GroupMembershipEventData, GroupMigrationEventData };
3
3
  export interface WsEventData {
4
4
  contextId: string;
5
5
  /** The context-event discriminator (core serializes it as a sibling of
@@ -7,7 +7,10 @@ export interface WsEventData {
7
7
  type?: string;
8
8
  data: unknown;
9
9
  }
10
- type WsEventHandler = (event: WsEventData | GroupMembershipEventData) => void;
10
+ /** Anything the `'event'` stream can deliver: context events plus the
11
+ * group-keyed membership and migration families. */
12
+ type WsEvent = WsEventData | GroupMembershipEventData | GroupMigrationEventData;
13
+ type WsEventHandler = (event: WsEvent) => void;
11
14
  type WsConnectHandler = () => void;
12
15
  type WsErrorHandler = (error: Error) => void;
13
16
  /**
package/dist/events/ws.js CHANGED
@@ -113,7 +113,8 @@ export class WsClient {
113
113
  });
114
114
  return;
115
115
  }
116
- // Group-membership event message (untagged NodeEvent's group variant)
116
+ // Group-keyed event message (untagged NodeEvent's membership and
117
+ // migration variants; the `type` tag tells them apart).
117
118
  if (msg.result.groupId) {
118
119
  this.emit('event', {
119
120
  groupId: msg.result.groupId,
@@ -1,3 +1,3 @@
1
- function N(n){let e=n.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let s=new AbortController,r=i=>{s.abort(i.target.reason);for(let o of e)o.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return s.signal}function _(n){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(n);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},n),e.signal}var ae=new Set(["token_reuse","token_revoked"]);function oe(n){if(n)try{let e=JSON.parse(n)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var y=class extends Error{constructor(t,s,r,i,o){let c=oe(o);super(c?`HTTP ${t} ${s}: ${c}`:`HTTP ${t} ${s}`);this.status=t;this.statusText=s;this.url=r;this.headers=i;this.bodyText=o;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:F(this.headers),bodyText:this.bodyText}}},I=class extends y{constructor(t,s,r,i,o,c){super(s,r,i,o,c);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${s} ${r}`}};function F(n){let e={};return n.forEach((t,s)=>{e[s]=t}),e}var v=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async head(e,t){let s=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:F(s.headers),status:s.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,s=0,r){let o=this.buildUrl(e),c=r??Date.now(),m=this.createAbortSignal(t),u=await this.buildHeaders(t?.headers),d;u instanceof Headers?(d={},u.forEach((p,C)=>{d[C]=p})):d=u;let l={method:t?.method||"GET",headers:d},h=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!h||t?.body!==void 0&&h&&s===0)&&(l.body=t.body);let g;if(s>0&&r!==void 0){let p=t?.timeoutMs||this.transport.timeoutMs;if(p){let C=Date.now()-c,T=Math.max(0,p-C);g=this.createAbortSignal({...t,timeoutMs:T})}else g=this.createAbortSignal(t)}else g=m;g&&(l.signal=g),this.transport.credentials!==void 0&&(l.credentials=this.transport.credentials),t?.mode!==void 0&&(l.mode=t.mode),t?.cache!==void 0&&(l.cache=t.cache),t?.redirect!==void 0&&(l.redirect=t.redirect),t?.referrer!==void 0&&(l.referrer=t.referrer),t?.referrerPolicy!==void 0&&(l.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(l.integrity=t.integrity),t?.keepalive!==void 0&&(l.keepalive=t.keepalive);try{let p=await this.transport.fetch(o,l);if(!p.ok){let C=await this.getBodyText(p),T=new y(p.status,p.statusText,o,p.headers,C),P=p.headers.get("x-auth-error");if((p.status===401||p.status===403)&&P&&ae.has(P)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new I(P,p.status,p.statusText,o,p.headers,C)}let re=t?.signal?.aborted===!0;if(p.status===401&&this.transport.refreshToken&&P==="token_expired"&&s<1&&!h&&!re)try{let f=this.refreshTokenPromise;f||(f=this.transport.refreshToken(),this.refreshTokenPromise=f);let H=await f;if(!H||H.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let S=this.onTokenRefreshPromise;S||(S=this.transport.onTokenRefresh(H),this.onTokenRefreshPromise=S),await S,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let K=t?.timeoutMs||this.transport.timeoutMs;if(K&&r!==void 0){let ie=Date.now()-c;if(K-ie<=0)throw T}return this.makeRequest(e,t,s+1,c)}catch(f){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,f instanceof Error&&f.message.includes("onTokenRefresh")?f:T}throw T}return this.parseResponse(p,t?.parse)}catch(p){throw p instanceof y||p instanceof Error&&p.message.includes("onTokenRefresh")?p:new y(0,"Network Error",o,new Headers,p instanceof Error?p.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let s=e?.timeoutMs||this.transport.timeoutMs;return s&&t.push(_(s)),t.length>0?N(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let s=await this.transport.getAuthToken();s&&s.trim()!==""&&(t.Authorization=`Bearer ${s}`)}catch{}return e&&(e instanceof Headers?e.forEach((s,r)=>{t[r]=s}):Array.isArray(e)?e.forEach(([s,r])=>{t[s]=r}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let s=await e.text();if(!s)return null;try{return JSON.parse(s)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${s.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function q(n){return new v(n)}function k(n){let e={fetch:(t,s)=>globalThis.fetch(t,s),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return q(e)}function E(n){let e=n.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let s={fetch:e===globalThis.fetch?(r,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return q(s)}function L(n){return typeof window<"u"?k(n):E(n)}function pe(n,e){if(e<=0)return!1;let s=n?.name;if(s==="TimeoutError")return!0;if(s==="AbortError")return!1;let r=n;if("status"in r&&typeof r.status=="number"){let i=r.status;return i>=500||i===429}return s==="TypeError"}function ce(n){let t=250*Math.pow(2,n-1),s=(Math.random()-.5)*.4*t;return Math.max(0,t+s)}async function M(n,e={}){let{attempts:t=3}=e,s;for(let r=1;r<=t;r++)try{return await n(r)}catch(i){if(s=i,!pe(s,t-r))throw s;let o=ce(r),u=s.headers?.get?.("Retry-After");if(u){let d=parseInt(u,10);if(!isNaN(d))o=Math.max(o,d*1e3);else{let l=new Date(u);if(!isNaN(l.getTime())){let h=Math.max(0,l.getTime()-Date.now());o=Math.max(o,Math.min(h,6e4))}}}await new Promise(d=>setTimeout(d,o))}throw s||new Error("Retry failed without error")}function le(n,e={}){return async(...t)=>M(()=>n(...t),e)}var R=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var x=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function Ue(n){let e=new x;return new R(e)}function He(n){let e=new x;return new R(e)}function Ne(n){let e=new x;return new R(e)}function z(n,e){return new R(n)}function a(n){return n?.data}function ue(n,e){let[t,s]=Q(n),[r,i]=Q(e),o=t.split("."),c=r.split("."),m=Math.max(o.length,c.length);for(let h=0;h<m;h++){let g=X(o[h]??"0",c[h]??"0");if(g!==0)return g}if(s===void 0&&i===void 0)return 0;if(s===void 0)return 1;if(i===void 0)return-1;let u=s.split("."),d=i.split("."),l=Math.max(u.length,d.length);for(let h=0;h<l;h++){if(h>=u.length)return-1;if(h>=d.length)return 1;let g=X(u[h],d[h]);if(g!==0)return g}return 0}function Q(n){let e=n.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function X(n,e){let t=/^\d+$/.test(n),s=/^\d+$/.test(e);if(t&&s){let r=Number(n)-Number(e);return r<0?-1:r>0?1:0}return t?-1:s?1:n<e?-1:n>e?1:0}async function Y(n,e,t){return M(async()=>{let s=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!s.ok){let r=new Error(`registry ${e} fetch failed (${s.status}) for ${t}`);throw r.status=s.status,r}return s},{attempts:3})}var b=class{constructor(e){this.httpClient=e}async healthCheck(){return a(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return a(await this.httpClient.post("/admin-api/install-application",e))}async installFromRegistry(e,t,s){let r=new URL(e).origin,i=new URL(`/api/v2/bundles/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,r).toString(),c=await(await Y(i,"manifest",`${t}@${s}`)).json(),m=encodeURIComponent(c.package),u=encodeURIComponent(c.appVersion),d=`${r}/artifacts/${m}/${u}/${m}-${u}.mpk`;return this.installApplication({url:d,package:c.package,version:c.appVersion,metadata:[]})}async getRegistryVersions(e,t){let s=new URL("/api/v2/bundles",new URL(e).origin);s.searchParams.set("package",t);let i=await(await Y(s.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(o=>o.appVersion).filter(o=>typeof o=="string").sort((o,c)=>ue(c,o))}async installDevApplication(e){return a(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return a(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return a(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return a(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return a(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let s=t?`?service_name=${encodeURIComponent(t)}`:"";return a(await this.httpClient.get(`/admin-api/applications/${e}/abi${s}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return a(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return a(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return a(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return a(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return a(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return a(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return a(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let s=t.toString(),r=s?`/admin-api/blobs?${s}`:"/admin-api/blobs",i=a(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:a(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),s=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(s)?s:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return a(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return a(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return a(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return a(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return a(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return a(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return a(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return a(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return a(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return a(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return a(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async listNamespacesForApplication(e){return a(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return a(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return a(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async joinNamespace(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}))}async createGroupInNamespace(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return a(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async getGroupInfo(e){return a(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e,t){return a(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let s=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${s}: missing or non-array \`members\` field`)}return t}async listGroupContexts(e){return a(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,s)}async getMemberCapabilities(e,t){return a(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,s)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,s)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,s)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return a(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return a(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}async reparentGroup(e,t){let s=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return s?.data??s}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t,s){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,s??{})}async createGroupInvitation(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return a(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return a(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return a(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return a(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return a(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return a(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t??{})}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t??{})}async setMemberAutoFollow(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,s)}async abortMigration(e,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function Ve(n){return new b(k(n))}function Je(n){return new b(E(n))}function Ke(n){return new b(L(n))}function Z(n,e){return new b(n)}function O(n){try{let e=n.indexOf("#");if(e===-1)return null;let t=n.substring(e+1),s=new URLSearchParams(t),r=s.get("access_token");return r?{accessToken:r,refreshToken:s.get("refresh_token")??"",applicationId:s.get("application_id")??"",contextId:s.get("context_id")??"",contextIdentity:s.get("context_identity")??"",nodeUrl:s.get("node_url")??""}:null}catch{return null}}function W(n,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${n.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var G=class extends Error{constructor(e,t,s,r){super(t),this.name="RpcError",this.code=e,this.data=s,this.type=r}},D=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t={jsonrpc:"2.0",id:1,method:"execute",params:{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}}},s=await this.httpClient.post("/jsonrpc",t);if(s.error){let r=s.error,i=r.code??-1,o=r.message??r.type??"RPC error";throw new G(i,o,r.data,r.type)}return s.result&&"output"in s.result?s.result.output:s.result}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var w=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}onAppVersionChanged(e){let t=s=>{if(s.type!=="AppVersionChanged")return;let r=s.data;e({contextId:s.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=await fetch(`${this.baseUrl}/sse`,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!t.ok)throw new Error(`SSE connection failed: ${t.status}`);if(!t.body)throw new Error("SSE response has no body");this.readStream(t.body).catch(s=>{if(this.closed)return;let r=s instanceof Error?s:new Error(String(s));this.emit("error",r),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),s=new TextDecoder,r="";try{for(;;){let{done:i,value:o}=await t.read();if(i)break;r+=s.decode(o,{stream:!0});let c=r.split(`
2
- `);r=c.pop()??"";for(let m of c)if(m.startsWith("data:")){let u=m.slice(5).trim();u&&this.handleMessage(u)}}if(r+=s.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let o=i instanceof Error?i:new Error(String(i));this.emit("error",o)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:s,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:s,groupIds:r})}async sendSubscription(e,t){try{let s=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let i=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.status}`))}catch(s){this.emit("error",s instanceof Error?s:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var $=class ${constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=s=>{this.handleMessage(s.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.add(s);for(let s of t.groupIds??[])this.subscribedGroupIds.add(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.delete(s);for(let s of t.groupIds??[])this.subscribedGroupIds.delete(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let s={};return e.length>0&&(s.contextIds=e),t.length>0&&(s.groupIds=t),s}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),$.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};$.MAX_BACKOFF_MS=3e4;var A=$;var de="mero-js:token-refresh";function he(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function B(n,e){try{let t=n.split(".");if(t.length===3){let s=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;s.length%4;)s+="=";let r=JSON.parse(atob(s));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var U=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window;this.httpClient=k({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async s=>{this.tokenData&&(this.tokenData.access_token=s,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=z(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Z(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new D({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new w({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new A({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let s={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},r=await this.authClient.generateTokens(s),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:B(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Authentication failed: ${s instanceof Error?s.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=he();return t?t.request(de,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let s=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=s.data.access_token;return this.tokenData={access_token:r,refresh_token:s.data.refresh_token,expires_at:B(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Token refresh failed: ${s instanceof Error?s.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||B(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return O(e)}static buildAuthLoginUrl(e,t){return W(e,t)}};function me(n){return new U(n)}var j=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},ge="mero-tokens",V=class{constructor(e=ge){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var J=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}};var mt={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256};function gt(n,e){let t=e>>>0;return(n&t)>>>0===t}function ft(n,e){return(n|e)>>>0}function yt(n,e){return(n&~e)>>>0}var ee=[2428,2429,2528,2529],fe="localhost",ye=2e3;function te(n){return`http://${fe}:${n}`}function se(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function ne(n,e={}){let{timeoutMs:t=ye,signal:s}=e;if(s?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),o=s;o&&o.addEventListener("abort",i,{once:!0});let c=setTimeout(()=>r.abort(),t);try{let m=se(n,"admin-api/health"),u=await fetch(m,{method:"GET",signal:r.signal});if(!u.ok)return!1;try{let d=await u.json(),l=d?.data?.status!==void 0?d?.data?.status:d?.status;return l===void 0?!0:typeof l=="string"&&l.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(c),o&&o.removeEventListener("abort",i)}}async function Re(n={}){let{ports:e=ee,timeoutMs:t,signal:s}=n;return(await Promise.all(e.map(async i=>{let o=te(i);return await ne(o,{timeoutMs:t,signal:s})?o:null}))).filter(i=>i!==null)}export{b as AdminApiClient,R as AuthApiClient,I as AuthRevokedError,mt as CAPABILITIES,J as CloudClient,ee as DEFAULT_LOCAL_NODE_PORTS,y as HTTPError,V as LocalStorageTokenStore,j as MemoryTokenStore,U as MeroJs,D as RpcClient,G as RpcError,w as SseClient,v as WebHttpClient,A as WsClient,W as buildAuthLoginUrl,N as combineSignals,ue as compareSemver,Ke as createAdminApiClient,Z as createAdminApiClientFromHttpClient,Ne as createAuthApiClient,z as createAuthApiClientFromHttpClient,Ve as createBrowserAdminApiClient,Ue as createBrowserAuthApiClient,k as createBrowserHttpClient,q as createHttpClient,me as createMeroJs,Je as createNodeAdminApiClient,He as createNodeAuthApiClient,E as createNodeHttpClient,le as createRetryableMethod,_ as createTimeoutSignal,L as createUniversalHttpClient,Re as discoverLocalNodes,gt as hasCap,te as localNodeUrl,se as nodeEndpoint,O as parseAuthCallback,ne as probeNodeHealth,ft as withCap,M as withRetry,yt as withoutCap};
1
+ function N(n){let e=n.filter(Boolean);if(e.length===0)return;let t=AbortSignal;if(typeof t.any=="function")try{return t.any(e)}catch{}let s=new AbortController,r=i=>{s.abort(i.target.reason);for(let o of e)o.removeEventListener("abort",r)};for(let i of e){if(i.aborted)return AbortSignal.abort(i.reason);i.addEventListener("abort",r,{once:!0})}return s.signal}function _(n){if(typeof AbortSignal.timeout=="function")return AbortSignal.timeout(n);let e=new AbortController;return setTimeout(()=>{e.abort(new DOMException("Timeout","TimeoutError"))},n),e.signal}var oe=new Set(["token_reuse","token_revoked"]);function pe(n){if(n)try{let e=JSON.parse(n)?.error;if(typeof e=="string"&&e.trim()!=="")return e;let t=e?.message;if(typeof t=="string"&&t.trim()!=="")return t}catch{}}var y=class extends Error{constructor(t,s,r,i,o){let c=pe(o);super(c?`HTTP ${t} ${s}: ${c}`:`HTTP ${t} ${s}`);this.status=t;this.statusText=s;this.url=r;this.headers=i;this.bodyText=o;this.name="HTTPError"}toJSON(){return{status:this.status,statusText:this.statusText,url:this.url,headers:F(this.headers),bodyText:this.bodyText}}},I=class extends y{constructor(t,s,r,i,o,c){super(s,r,i,o,c);this.reason=t;this.name="AuthRevokedError";this.message=`Authentication revoked (${t}): HTTP ${s} ${r}`}};function F(n){let e={};return n.forEach((t,s)=>{e[s]=t}),e}var v=class{constructor(e){this.transport=e;this.refreshTokenPromise=null;this.onTokenRefreshPromise=null}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,s){return this.request(e,{...s,method:"POST",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async put(e,t,s){return this.request(e,{...s,method:"PUT",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async delete(e,t){return this.request(e,{...t,method:"DELETE"})}async patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t?JSON.stringify(t):void 0,headers:{"Content-Type":"application/json",...s?.headers}})}async head(e,t){let s=await this.makeRequest(e,{...t,method:"HEAD",parse:"response"});return{headers:F(s.headers),status:s.status}}async request(e,t){return this.makeRequest(e,t)}async makeRequest(e,t,s=0,r){let o=this.buildUrl(e),c=r??Date.now(),m=this.createAbortSignal(t),u=await this.buildHeaders(t?.headers),d;u instanceof Headers?(d={},u.forEach((p,b)=>{d[b]=p})):d=u;let l={method:t?.method||"GET",headers:d},h=t?.body instanceof ReadableStream||typeof t?.body=="object"&&t?.body!==null&&"getReader"in t.body&&!(t.body instanceof Blob);(t?.body!==void 0&&!h||t?.body!==void 0&&h&&s===0)&&(l.body=t.body);let g;if(s>0&&r!==void 0){let p=t?.timeoutMs||this.transport.timeoutMs;if(p){let b=Date.now()-c,T=Math.max(0,p-b);g=this.createAbortSignal({...t,timeoutMs:T})}else g=this.createAbortSignal(t)}else g=m;g&&(l.signal=g),this.transport.credentials!==void 0&&(l.credentials=this.transport.credentials),t?.mode!==void 0&&(l.mode=t.mode),t?.cache!==void 0&&(l.cache=t.cache),t?.redirect!==void 0&&(l.redirect=t.redirect),t?.referrer!==void 0&&(l.referrer=t.referrer),t?.referrerPolicy!==void 0&&(l.referrerPolicy=t.referrerPolicy),t?.integrity!==void 0&&(l.integrity=t.integrity),t?.keepalive!==void 0&&(l.keepalive=t.keepalive);try{let p=await this.transport.fetch(o,l);if(!p.ok){let b=await this.getBodyText(p),T=new y(p.status,p.statusText,o,p.headers,b),P=p.headers.get("x-auth-error");if((p.status===401||p.status===403)&&P&&oe.has(P)){if(this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,this.transport.onAuthRevoked)try{await this.transport.onAuthRevoked()}catch{}throw new I(P,p.status,p.statusText,o,p.headers,b)}let ie=t?.signal?.aborted===!0;if(p.status===401&&this.transport.refreshToken&&P==="token_expired"&&s<1&&!h&&!ie)try{let f=this.refreshTokenPromise;f||(f=this.transport.refreshToken(),this.refreshTokenPromise=f);let U=await f;if(!U||U.trim()==="")throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("Refresh token returned empty token");if(!this.transport.onTokenRefresh)throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,new Error("onTokenRefresh callback is required when refreshToken is provided. The callback must update the token storage so getAuthToken() returns the new token.");let S=this.onTokenRefreshPromise;S||(S=this.transport.onTokenRefresh(U),this.onTokenRefreshPromise=S),await S,this.refreshTokenPromise=null,this.onTokenRefreshPromise=null;let K=t?.timeoutMs||this.transport.timeoutMs;if(K&&r!==void 0){let ae=Date.now()-c;if(K-ae<=0)throw T}return this.makeRequest(e,t,s+1,c)}catch(f){throw this.refreshTokenPromise=null,this.onTokenRefreshPromise=null,f instanceof Error&&f.message.includes("onTokenRefresh")?f:T}throw T}return this.parseResponse(p,t?.parse)}catch(p){throw p instanceof y||p instanceof Error&&p.message.includes("onTokenRefresh")?p:new y(0,"Network Error",o,new Headers,p instanceof Error?p.message:"Unknown error")}}buildUrl(e){if(e.startsWith("http://")||e.startsWith("https://"))return e;let t=this.transport.baseUrl;return e.startsWith("/")?`${t.endsWith("/")?t.slice(0,-1):t}${e}`:`${t.endsWith("/")?t:`${t}/`}${e}`}createAbortSignal(e){let t=[];this.transport.defaultAbortSignal&&t.push(this.transport.defaultAbortSignal),e?.signal&&t.push(e.signal);let s=e?.timeoutMs||this.transport.timeoutMs;return s&&t.push(_(s)),t.length>0?N(t):void 0}async buildHeaders(e){let t={...this.transport.defaultHeaders};if(this.transport.getAuthToken)try{let s=await this.transport.getAuthToken();s&&s.trim()!==""&&(t.Authorization=`Bearer ${s}`)}catch{}return e&&(e instanceof Headers?e.forEach((s,r)=>{t[r]=s}):Array.isArray(e)?e.forEach(([s,r])=>{t[s]=r}):Object.assign(t,e)),t}async parseResponse(e,t){switch(t){case"text":return await e.text();case"blob":return await e.blob();case"arrayBuffer":return await e.arrayBuffer();case"response":return e;default:{let s=await e.text();if(!s)return null;try{return JSON.parse(s)}catch{throw new Error(`Expected a JSON response (status ${e.status}) but body was not JSON: ${s.slice(0,200)}`)}}}}async getBodyText(e){try{let t=await e.text();return t.length>65536?t.slice(0,65536)+"...":t}catch{return""}}};function q(n){return new v(n)}function k(n){let e={fetch:(t,s)=>globalThis.fetch(t,s),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return q(e)}function E(n){let e=n.fetch??globalThis.fetch;if(!e)throw new Error("No fetch implementation available. Please provide a fetch implementation (e.g., undici.fetch) or use Node.js 18+ which has native fetch support.");let s={fetch:e===globalThis.fetch?(r,i)=>globalThis.fetch(r,i):(r,i)=>e(r,i),baseUrl:n.baseUrl,getAuthToken:n.getAuthToken,onTokenRefresh:n.onTokenRefresh,refreshToken:n.refreshToken,onAuthRevoked:n.onAuthRevoked,defaultHeaders:n.defaultHeaders,timeoutMs:n.timeoutMs,credentials:n.credentials,defaultAbortSignal:n.defaultAbortSignal};return q(s)}function L(n){return typeof window<"u"?k(n):E(n)}function ce(n,e){if(e<=0)return!1;let s=n?.name;if(s==="TimeoutError")return!0;if(s==="AbortError")return!1;let r=n;if("status"in r&&typeof r.status=="number"){let i=r.status;return i>=500||i===429}return s==="TypeError"}function le(n){let t=250*Math.pow(2,n-1),s=(Math.random()-.5)*.4*t;return Math.max(0,t+s)}async function M(n,e={}){let{attempts:t=3}=e,s;for(let r=1;r<=t;r++)try{return await n(r)}catch(i){if(s=i,!ce(s,t-r))throw s;let o=le(r),u=s.headers?.get?.("Retry-After");if(u){let d=parseInt(u,10);if(!isNaN(d))o=Math.max(o,d*1e3);else{let l=new Date(u);if(!isNaN(l.getTime())){let h=Math.max(0,l.getTime()-Date.now());o=Math.max(o,Math.min(h,6e4))}}}await new Promise(d=>setTimeout(d,o))}throw s||new Error("Retry failed without error")}function ue(n,e={}){return async(...t)=>M(()=>n(...t),e)}var C=class{constructor(e){this.httpClient=e}async getHealth(){let e=await this.httpClient.get("/auth/health");if(!e.data)throw new Error("Health response data is null");return e.data}async getIdentity(){let e=await this.httpClient.get("/admin/identity");if(!e.data)throw new Error("Identity response data is null");return e.data}async getProviders(){let e=await this.httpClient.get("/auth/providers");if(!e.data)throw new Error("Providers response data is null");return e.data}async getLoginPage(){return this.httpClient.get("/auth/login",{parse:"text"})}async generateTokens(e){return this.httpClient.post("/auth/token",e)}async refreshToken(e){return this.httpClient.post("/auth/refresh",e)}async generateMockTokens(e){return this.httpClient.post("/auth/mock-token",e)}async validateToken(e){try{let t=await this.validateTokenGet(e);return{valid:t.status===200,headers:t.headers,status:t.status}}catch{return{valid:!1,headers:{},status:401}}}async validateTokenGet(e){let t=await this.httpClient.head("/auth/validate",{headers:{Authorization:`Bearer ${e}`}});return{status:t.status,headers:t.headers}}async revokeTokens(e){let t=await this.httpClient.post("/admin/revoke",e);if(!t.data)throw new Error("Revoke tokens response data is null");return t.data}async listRootKeys(){let e=await this.httpClient.get("/admin/keys");if(!e.data)throw new Error("Root keys response data is null");return e.data}async createRootKey(e){let t=await this.httpClient.post("/admin/keys",e);if(!t.data)throw new Error("Create root key response data is null");return t.data}async deleteRootKey(e){return this.httpClient.delete(`/admin/keys/${e}`)}async listClientKeys(){let e=await this.httpClient.get("/admin/keys/clients");if(!e.data)throw new Error("Client keys response data is null");return e.data}async generateClientKey(e){return this.httpClient.post("/admin/client-key",e)}async deleteClientKey(e,t){return this.httpClient.delete(`/admin/keys/${e}/clients/${t}`)}async getKeyPermissions(e){return this.httpClient.get(`/admin/keys/${e}/permissions`)}async updateKeyPermissions(e,t){return this.httpClient.put(`/admin/keys/${e}/permissions`,{add:t.add,remove:t.remove})}};var x=class{async get(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async post(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async put(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async delete(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async patch(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async head(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}async request(){throw new Error("HTTP client not implemented - use createAuthApiClientFromHttpClient with a real HTTP client")}};function Ne(n){let e=new x;return new C(e)}function _e(n){let e=new x;return new C(e)}function qe(n){let e=new x;return new C(e)}function z(n,e){return new C(n)}function a(n){return n?.data}function de(n,e){let[t,s]=Q(n),[r,i]=Q(e),o=t.split("."),c=r.split("."),m=Math.max(o.length,c.length);for(let h=0;h<m;h++){let g=X(o[h]??"0",c[h]??"0");if(g!==0)return g}if(s===void 0&&i===void 0)return 0;if(s===void 0)return 1;if(i===void 0)return-1;let u=s.split("."),d=i.split("."),l=Math.max(u.length,d.length);for(let h=0;h<l;h++){if(h>=u.length)return-1;if(h>=d.length)return 1;let g=X(u[h],d[h]);if(g!==0)return g}return 0}function Q(n){let e=n.split("+",1)[0],t=e.indexOf("-");return t===-1?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function X(n,e){let t=/^\d+$/.test(n),s=/^\d+$/.test(e);if(t&&s){let r=Number(n)-Number(e);return r<0?-1:r>0?1:0}return t?-1:s?1:n<e?-1:n>e?1:0}async function Y(n,e,t){return M(async()=>{let s=await fetch(n,{signal:AbortSignal.timeout(1e4)});if(!s.ok){let r=new Error(`registry ${e} fetch failed (${s.status}) for ${t}`);throw r.status=s.status,r}return s},{attempts:3})}var R=class{constructor(e){this.httpClient=e}async healthCheck(){return a(await this.httpClient.get("/admin-api/health"))}async isAuthed(){return this.httpClient.get("/admin-api/is-authed")}async installApplication(e){return a(await this.httpClient.post("/admin-api/install-application",e))}async installFromRegistry(e,t,s){let r=new URL(e).origin,i=new URL(`/api/v2/bundles/${encodeURIComponent(t)}/${encodeURIComponent(s)}`,r).toString(),c=await(await Y(i,"manifest",`${t}@${s}`)).json(),m=encodeURIComponent(c.package),u=encodeURIComponent(c.appVersion),d=`${r}/artifacts/${m}/${u}/${m}-${u}.mpk`;return this.installApplication({url:d,package:c.package,version:c.appVersion,metadata:[]})}async getRegistryVersions(e,t){let s=new URL("/api/v2/bundles",new URL(e).origin);s.searchParams.set("package",t);let i=await(await Y(s.toString(),"versions",t)).json();return(Array.isArray(i)?i:[]).map(o=>o.appVersion).filter(o=>typeof o=="string").sort((o,c)=>de(c,o))}async installDevApplication(e){return a(await this.httpClient.post("/admin-api/install-dev-application",e))}async uninstallApplication(e){return a(await this.httpClient.delete(`/admin-api/applications/${e}`))}async listApplications(){return a(await this.httpClient.get("/admin-api/applications"))}async getApplication(e){return a(await this.httpClient.get(`/admin-api/applications/${e}`))}async listApplicationVersions(e){return a(await this.httpClient.get(`/admin-api/applications/${e}/versions`))}async getApplicationAbi(e,t){let s=t?`?service_name=${encodeURIComponent(t)}`:"";return a(await this.httpClient.get(`/admin-api/applications/${e}/abi${s}`))}async listPackages(){let e=await this.httpClient.get("/admin-api/packages");return e?.data??e}async listPackageVersions(e){let t=await this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/versions`);return t?.data??t}async getLatestPackageVersion(e){return this.httpClient.get(`/admin-api/packages/${encodeURIComponent(e)}/latest`)}async createContext(e){let t={...e,initializationParams:e.initializationParams??[]};return a(await this.httpClient.post("/admin-api/contexts",t))}async deleteContext(e,t){return a(t?await this.httpClient.request(`/admin-api/contexts/${e}`,{method:"DELETE",body:JSON.stringify(t),headers:{"Content-Type":"application/json"}}):await this.httpClient.delete(`/admin-api/contexts/${e}`))}async getContexts(){return a(await this.httpClient.get("/admin-api/contexts"))}async getContext(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}`))}async getContextsForApplication(e){return a(await this.httpClient.get(`/admin-api/contexts/for-application/${e}`))}async generateContextIdentity(){return a(await this.httpClient.post("/admin-api/identity/context",{}))}async getContextIdentities(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/identities`))}async getContextIdentitiesOwned(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/identities-owned`))}async joinContext(e){return a(await this.httpClient.post(`/admin-api/contexts/${e}/join`,{}))}async getContextGroup(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/group`))}async getContextStorage(e){return a(await this.httpClient.get(`/admin-api/contexts/${e}/storage`))}async syncContext(e){await this.httpClient.post(`/admin-api/contexts/sync/${e??""}`,{})}async resyncContext(e,t={}){return await this.httpClient.post(`/admin-api/contexts/${e}/resync`,t)??{contextId:e,resyncStarted:!0}}async inviteSpecializedNode(e){return a(await this.httpClient.post("/admin-api/contexts/invite-specialized-node",e))}async updateContextApplication(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/application`,t)}async getContextsWithExecutorsForApplication(e){let t=await this.httpClient.get(`/admin-api/contexts/with-executors/for-application/${e}`);return Array.isArray(t)?t:t?.contexts??t?.data??[]}async uploadBlob(e){let t=new URLSearchParams;e.hash&&t.set("hash",e.hash),e.contextId&&t.set("context_id",e.contextId);let s=t.toString(),r=s?`/admin-api/blobs?${s}`:"/admin-api/blobs",i=a(await this.httpClient.request(r,{method:"PUT",body:e.data,headers:{"Content-Type":"application/octet-stream"}}));return{blobId:i.blob_id,size:i.size}}async deleteBlob(e){let t=await this.httpClient.delete(`/admin-api/blobs/${e}`);return{blobId:t.blob_id,deleted:t.deleted}}async listBlobs(){return{blobs:a(await this.httpClient.get("/admin-api/blobs")).blobs.map(t=>({blobId:t.blob_id,size:t.size}))}}async getBlob(e){return this.httpClient.get(`/admin-api/blobs/${e}`,{parse:"arrayBuffer"})}async getBlobInfo(e){let{headers:t}=await this.httpClient.head(`/admin-api/blobs/${e}`),s=Number(t["content-length"]);return{blobId:t["x-blob-id"]??e,size:Number.isFinite(s)?s:0,hash:t["x-blob-hash"],mimeType:t["x-blob-mime-type"]}}async createContextAlias(e){return a(await this.httpClient.post("/admin-api/alias/create/context",{alias:e.alias,contextId:e.contextId}))}async createApplicationAlias(e){return a(await this.httpClient.post("/admin-api/alias/create/application",{alias:e.alias,applicationId:e.applicationId}))}async lookupContextAlias(e){return a(await this.httpClient.post(`/admin-api/alias/lookup/context/${encodeURIComponent(e)}`,{}))}async lookupApplicationAlias(e){return a(await this.httpClient.post(`/admin-api/alias/lookup/application/${encodeURIComponent(e)}`,{}))}async deleteContextAlias(e){return a(await this.httpClient.post(`/admin-api/alias/delete/context/${encodeURIComponent(e)}`,{}))}async deleteApplicationAlias(e){return a(await this.httpClient.post(`/admin-api/alias/delete/application/${encodeURIComponent(e)}`,{}))}async listContextAliases(){return a(await this.httpClient.get("/admin-api/alias/list/context"))}async listApplicationAliases(){return a(await this.httpClient.get("/admin-api/alias/list/application"))}async listNamespaces(){return a(await this.httpClient.get("/admin-api/namespaces"))}async getNamespace(e){return a(await this.httpClient.get(`/admin-api/namespaces/${e}`))}async getNodeIdentity(){return a(await this.httpClient.get("/admin-api/identity"))}async getNamespaceIdentity(e){let t=await this.getNodeIdentity();return{namespaceId:e,publicKey:t.publicKey,account:t.accountId}}async listNamespacesForApplication(e){return a(await this.httpClient.get(`/admin-api/namespaces/for-application/${e}`))}async createNamespace(e){return a(await this.httpClient.post("/admin-api/namespaces",{upgradePolicy:"LazyOnAccess",...e}))}async deleteNamespace(e,t){return a(await this.httpClient.request(`/admin-api/namespaces/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async createNamespaceInvitation(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/invite`,t??{}))}async joinNamespace(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/join`,t,{timeoutMs:65e3}))}async createGroupInNamespace(e,t){return a(await this.httpClient.post(`/admin-api/namespaces/${e}/groups`,t??{}))}async listNamespaceGroups(e){return a(await this.httpClient.get(`/admin-api/namespaces/${e}/groups`))}async getGroupInfo(e){return a(await this.httpClient.get(`/admin-api/groups/${e}`))}async getDefaultCapabilities(e){return(await this.getGroupInfo(e)).defaultCapabilities}async getSubgroupVisibility(e){return(await this.getGroupInfo(e)).subgroupVisibility}async deleteGroup(e,t){return a(await this.httpClient.request(`/admin-api/groups/${e}`,{method:"DELETE",body:JSON.stringify(t??{}),headers:{"Content-Type":"application/json"}}))}async listGroupMembers(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/members`);if(!Array.isArray(t?.members)){let s=String(e).replace(/[\r\n\t\s]/g,"").slice(0,64);throw new Error(`Invalid listGroupMembers response for group ${s}: missing or non-array \`members\` field`)}return t}async listGroupContexts(e){return a(await this.httpClient.get(`/admin-api/groups/${e}/contexts`))}async addGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members`,t)}async removeGroupMembers(e,t){await this.httpClient.post(`/admin-api/groups/${e}/members/remove`,t)}async updateMemberRole(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/role`,s)}async getMemberCapabilities(e,t){return a(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/capabilities`))}async setMemberCapabilities(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/capabilities`,s)}async setDefaultCapabilities(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/default-capabilities`,t)}async setSubgroupVisibility(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/subgroup-visibility`,t)}async setTeeAdmissionPolicy(e,t){await this.httpClient.put(`/admin-api/groups/${e}/settings/tee-admission-policy`,t)}async getTeeAdmissionPolicy(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/settings/tee-admission-policy`);return t.data??t}async setGroupMetadata(e,t){await this.httpClient.put(`/admin-api/groups/${e}/metadata`,t)}async getGroupMetadata(e){return(await this.httpClient.get(`/admin-api/groups/${e}/metadata`))?.data??null}async setMemberMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/metadata`,s)}async getMemberMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/members/${t}/metadata`))?.data??null}async setContextMetadata(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/contexts/${t}/metadata`,s)}async getContextMetadata(e,t){return(await this.httpClient.get(`/admin-api/groups/${e}/contexts/${t}/metadata`))?.data??null}async syncGroup(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/sync`,t??{}))}async upgradeGroup(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/upgrade`,t))}async getGroupUpgradeStatus(e){return a(await this.httpClient.get(`/admin-api/groups/${e}/upgrade/status`))}async getMigrationStatus(e){let t=encodeURIComponent(e);return this.httpClient.get(`/admin-api/groups/${t}/migration-status`)}async getCascadeStatus(e){let t=encodeURIComponent(e);return a(await this.httpClient.get(`/admin-api/groups/${t}/cascade-status`))}async retryGroupUpgrade(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/upgrade/retry`,t??{}))}async reparentGroup(e,t){let s=await this.httpClient.post(`/admin-api/groups/${e}/reparent`,t);return s?.data??s}async listSubgroups(e){let t=await this.httpClient.get(`/admin-api/groups/${e}/subgroups`);return t.subgroups??t.data??[]}async detachContextFromGroup(e,t,s){await this.httpClient.post(`/admin-api/groups/${e}/contexts/${t}/remove`,s??{})}async createGroupInvitation(e,t){return a(await this.httpClient.post(`/admin-api/groups/${e}/invite`,t??{}))}async joinGroup(e){return a(await this.httpClient.post("/admin-api/groups/join",e))}async joinSubgroupInheritance(e){return a(await this.httpClient.post(`/admin-api/groups/${e}/join-via-inheritance`,{}))}async getTeeInfo(){return a(await this.httpClient.get("/admin-api/tee/info"))}async teeAttest(e){return a(await this.httpClient.post("/admin-api/tee/attest",e))}async teeVerifyQuote(e){return a(await this.httpClient.post("/admin-api/tee/verify-quote",e))}async getPeersCount(){return this.httpClient.get("/admin-api/peers")}async getNetworkStatus(){return this.httpClient.get("/admin-api/network/status")}async getUsage(){return this.httpClient.get("/admin-api/usage")}async getCertificate(){return this.httpClient.get("/admin-api/certificate",{parse:"text"})}async createGroup(e){return a(await this.httpClient.post("/admin-api/groups",{upgradePolicy:"LazyOnAccess",...e}))}async leaveGroup(e,t){await this.httpClient.post(`/admin-api/groups/${e}/leave`,t??{})}async leaveContext(e,t){await this.httpClient.post(`/admin-api/contexts/${e}/leave`,t??{})}async leaveNamespace(e,t){await this.httpClient.post(`/admin-api/namespaces/${e}/leave`,t??{})}async issueOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-ownership-proof`,t??{})}async issueNamespaceOwnershipProof(e,t){return this.httpClient.post(`/admin-api/groups/${e}/issue-namespace-ownership-proof`,t??{})}async setMemberAutoFollow(e,t,s){await this.httpClient.put(`/admin-api/groups/${e}/members/${t}/auto-follow`,s)}async abortMigration(e,t){return this.httpClient.post(`/admin-api/groups/${e}/migration/abort`,t??{})}};function Ke(n){return new R(k(n))}function Fe(n){return new R(E(n))}function ze(n){return new R(L(n))}function Z(n,e){return new R(n)}function O(n){try{let e=n.indexOf("#");if(e===-1)return null;let t=n.substring(e+1),s=new URLSearchParams(t),r=s.get("access_token");return r?{accessToken:r,refreshToken:s.get("refresh_token")??"",applicationId:s.get("application_id")??"",contextId:s.get("context_id")??"",contextIdentity:s.get("context_identity")??"",nodeUrl:s.get("node_url")??""}:null}catch{return null}}function W(n,e){let t=new URLSearchParams;return t.set("callback-url",e.callbackUrl),e.permissions&&e.permissions.length>0&&t.set("permissions",e.permissions.join(",")),t.set("mode",e.mode),e.packageName&&(t.set("package-name",e.packageName),e.packageVersion&&t.set("package-version",e.packageVersion),e.registryUrl&&t.set("registry-url",e.registryUrl)),`${n.replace(/\/+$/,"")}/auth/login?${t.toString()}`}var G=class extends Error{constructor(e,t,s,r){super(t),this.name="RpcError",this.code=e,this.data=s,this.type=r}},D=class{constructor(e){this.httpClient=e.httpClient}async execute(e){let t={jsonrpc:"2.0",id:1,method:"execute",params:{contextId:e.contextId,method:e.method,argsJson:e.argsJson??{}}},s=await this.httpClient.post("/jsonrpc",t);if(s.error){let r=s.error,i=r.code??-1,o=r.message??r.type??"RPC error";throw new G(i,o,r.data,r.type)}return s.result&&"output"in s.result?s.result.output:s.result}async migrateMyEntries(e){return this.execute({contextId:e,method:"migrate_my_entries"})}async countMyPending(e){return this.execute({contextId:e,method:"count_my_pending"})}};var he=new Set(["MigrationStarted","MigrationProgress","CascadeProgress","MigrationCompleted"]);function ee(n){return n.type!==void 0&&he.has(n.type)}var w=class{constructor(e){this.sessionId=null;this.abortController=null;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.closed=!1;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken,this.reconnectDelayMs=e.reconnectDelayMs??3e3}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}onAppVersionChanged(e){let t=s=>{if(s.type!=="AppVersionChanged")return;let r=s.data;e({contextId:s.contextId,fromVersion:r?.fromVersion,toVersion:r?.toVersion})};return this.on("event",t),()=>this.off("event",t)}onMigrationEvent(e){let t=s=>{ee(s)&&e(s)};return this.on("event",t),()=>this.off("event",t)}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.abortController&&!this.closed)){this.closed=!1,this.abortController=new AbortController;try{let e=await this.getAuthToken(),t=await fetch(`${this.baseUrl}/sse`,{headers:{Authorization:`Bearer ${e}`,Accept:"text/event-stream"},signal:this.abortController.signal});if(!t.ok)throw new Error(`SSE connection failed: ${t.status}`);if(!t.body)throw new Error("SSE response has no body");this.readStream(t.body).catch(s=>{if(this.closed)return;let r=s instanceof Error?s:new Error(String(s));this.emit("error",r),this.scheduleReconnect()})}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}async readStream(e){let t=e.getReader(),s=new TextDecoder,r="";try{for(;;){let{done:i,value:o}=await t.read();if(i)break;r+=s.decode(o,{stream:!0});let c=r.split(`
2
+ `);r=c.pop()??"";for(let m of c)if(m.startsWith("data:")){let u=m.slice(5).trim();u&&this.handleMessage(u)}}if(r+=s.decode(),r.startsWith("data:")){let i=r.slice(5).trim();i&&this.handleMessage(i)}}catch(i){if(this.closed)return;let o=i instanceof Error?i:new Error(String(i));this.emit("error",o)}this.closed||this.scheduleReconnect()}handleMessage(e){try{let t=JSON.parse(e);if(t.type==="connect"&&t.session_id){this.sessionId=t.session_id,this.emit("connect",t.session_id),(this.subscribedContextIds.size>0||this.subscribedGroupIds.size>0)&&this.sendSubscription("subscribe",{contextIds:[...this.subscribedContextIds],groupIds:[...this.subscribedGroupIds]});return}if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}async subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>!this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>!this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.add(i);for(let i of t.groupIds??[])this.subscribedGroupIds.add(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("subscribe",{contextIds:s,groupIds:r})}async unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e,s=(t.contextIds??[]).filter(i=>this.subscribedContextIds.has(i)),r=(t.groupIds??[]).filter(i=>this.subscribedGroupIds.has(i));for(let i of t.contextIds??[])this.subscribedContextIds.delete(i);for(let i of t.groupIds??[])this.subscribedGroupIds.delete(i);(s.length>0||r.length>0)&&this.sessionId&&await this.sendSubscription("unsubscribe",{contextIds:s,groupIds:r})}async sendSubscription(e,t){try{let s=await this.getAuthToken(),r={};t.contextIds&&t.contextIds.length>0&&(r.contextIds=t.contextIds),t.groupIds&&t.groupIds.length>0&&(r.groupIds=t.groupIds);let i=await fetch(`${this.baseUrl}/sse/subscription`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify({id:this.sessionId,method:e,params:r})});i.ok||this.emit("error",new Error(`SSE ${e} failed: ${i.status}`))}catch(s){this.emit("error",s instanceof Error?s:new Error(`SSE ${e} failed`))}}forceReconnect(){this.abortController&&(this.abortController.abort(),this.abortController=null),this.sessionId=null,this.connect()}scheduleReconnect(){this.closed||(this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.forceReconnect()},this.reconnectDelayMs))}close(){this.closed=!0,this.abortController&&(this.abortController.abort(),this.abortController=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.sessionId=null,this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};var $=class ${constructor(e){this.ws=null;this.closed=!1;this.reconnectAttempt=0;this.reconnectTimer=null;this.subscribedContextIds=new Set;this.subscribedGroupIds=new Set;this.listeners={connect:[],event:[],error:[]};this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.getAuthToken=e.getAuthToken}on(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s];r.includes(t)||r.push(t)}}off(e,t){let s=e;if(s in this.listeners){let r=this.listeners[s],i=r.indexOf(t);i!==-1&&r.splice(i,1)}}emit(e,t){let s=e;if(s in this.listeners)for(let r of this.listeners[s])try{r(t)}catch{}}async connect(){if(!(this.ws&&(this.ws.readyState===0||this.ws.readyState===1))){this.closed=!1;try{let e=await this.getAuthToken();if(!e)throw new Error("No authentication token available for WebSocket connection");let t=this.baseUrl.replace(/^http/,"ws");this.ws=new WebSocket(`${t}/ws?token=${encodeURIComponent(e)}`),this.ws.onopen=()=>{this.reconnectAttempt=0,this.emit("connect"),this.resubscribeAfterReconnect()},this.ws.onmessage=s=>{this.handleMessage(s.data)},this.ws.onerror=()=>{this.emit("error",new Error("WebSocket error"))},this.ws.onclose=()=>{this.closed||this.scheduleReconnect()}}catch(e){if(this.closed)return;let t=e instanceof Error?e:new Error(String(e));this.emit("error",t),this.scheduleReconnect()}}}handleMessage(e){if(typeof e=="string")try{let t=JSON.parse(e);if(!t.result)return;let s=t.result.data;if(Array.isArray(s))try{let r=new Uint8Array(s),i=new TextDecoder().decode(r);s=JSON.parse(i)}catch{}if(t.result.contextId){this.emit("event",{contextId:t.result.contextId,type:t.result.type,data:s});return}t.result.groupId&&this.emit("event",{groupId:t.result.groupId,type:t.result.type,data:s})}catch{}}subscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.add(s);for(let s of t.groupIds??[])this.subscribedGroupIds.add(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}unsubscribe(e){let t=Array.isArray(e)?{contextIds:e}:e;for(let s of t.contextIds??[])this.subscribedContextIds.delete(s);for(let s of t.groupIds??[])this.subscribedGroupIds.delete(s);this.ws&&this.ws.readyState===1&&this.sendMessage({id:null,method:"unsubscribe",params:this.buildSubscriptionParams(t.contextIds??[],t.groupIds??[])})}resubscribeAfterReconnect(){this.subscribedContextIds.size===0&&this.subscribedGroupIds.size===0||this.sendMessage({id:null,method:"subscribe",params:this.buildSubscriptionParams([...this.subscribedContextIds],[...this.subscribedGroupIds])})}buildSubscriptionParams(e,t){let s={};return e.length>0&&(s.contextIds=e),t.length>0&&(s.groupIds=t),s}sendMessage(e){this.ws&&this.ws.readyState===1&&this.ws.send(JSON.stringify(e))}scheduleReconnect(){if(this.closed)return;this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=Math.min(1e3*Math.pow(2,this.reconnectAttempt),$.MAX_BACKOFF_MS);this.reconnectAttempt++,this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}close(){this.closed=!0,this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.onclose=null,this.ws.close(),this.ws=null),this.subscribedContextIds.clear(),this.subscribedGroupIds.clear()}};$.MAX_BACKOFF_MS=3e4;var A=$;var me="mero-js:token-refresh";function ge(){let e=globalThis.navigator?.locks;return e&&typeof e.request=="function"?e:null}function V(n,e){try{let t=n.split(".");if(t.length===3){let s=t[1].replace(/-/g,"+").replace(/_/g,"/");for(;s.length%4;)s+="=";let r=JSON.parse(atob(s));if(typeof r.exp=="number")return r.exp*1e3}}catch{}return e}var H=class{constructor(e){this.tokenData=null;this.refreshPromise=null;this.rpcClient=null;this.sseClient=null;this.wsClient=null;this.wsWarned=!1;this.config={timeoutMs:1e4,...e},this.tokenStore=e.tokenStore??null,this.tokenStore&&(this.tokenData=this.tokenStore.getTokens());let t=typeof window<"u"&&"__TAURI_INTERNALS__"in window;this.httpClient=k({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",refreshToken:async()=>(await this.performTokenRefresh()).access_token,onTokenRefresh:async s=>{this.tokenData&&(this.tokenData.access_token=s,this.tokenStore?.setTokens(this.tokenData))},onAuthRevoked:async()=>{this.clearToken();try{await this.config.onAuthRevoked?.()}catch{}},timeoutMs:this.config.timeoutMs,credentials:this.config.requestCredentials??(t?"omit":void 0)}),this.authClient=z(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs}),this.adminClient=Z(this.httpClient,{baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||"",timeoutMs:this.config.timeoutMs})}get auth(){return this.authClient}get admin(){return this.adminClient}get rpc(){return this.rpcClient||(this.rpcClient=new D({httpClient:this.httpClient})),this.rpcClient}get events(){return this.sseClient||(this.sseClient=new w({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.sseClient}get ws(){return this.wsWarned||(this.wsWarned=!0,console.warn("[mero-js] WsClient is experimental. Use mero.events (SSE) for production.")),this.wsClient||(this.wsClient=new A({baseUrl:this.config.baseUrl,getAuthToken:async()=>(await this.getValidToken())?.access_token||""})),this.wsClient}async authenticate(e){let t=e||this.config.credentials;if(!t)throw new Error("No credentials provided for authentication");try{let s={auth_method:"user_password",public_key:t.username,client_name:"mero-js-sdk",permissions:["admin"],timestamp:Math.floor(Date.now()/1e3),provider_data:{username:t.username,password:t.password}},r=await this.authClient.generateTokens(s),i=r.data.access_token;return this.tokenData={access_token:i,refresh_token:r.data.refresh_token,expires_at:V(i,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Authentication failed: ${s instanceof Error?s.message:"Unknown error"}`)}}async getValidToken(){return this.tokenData}async performTokenRefresh(){if(this.refreshPromise)return this.refreshPromise;let e=this.tokenData?.access_token,t=this.withRefreshLock(()=>this.performTokenRefreshLocked(e));this.refreshPromise=t;try{return await t}finally{this.refreshPromise===t&&(this.refreshPromise=null)}}withRefreshLock(e){let t=ge();return t?t.request(me,e):e()}async performTokenRefreshLocked(e){let t=this.tokenStore?.getTokens()??null;if(t?.refresh_token&&(this.tokenData=t,e&&t.access_token!==e))return t;if(!this.tokenData?.refresh_token)throw new Error("No refresh token available");try{let s=await this.authClient.refreshToken({access_token:this.tokenData.access_token,refresh_token:this.tokenData.refresh_token}),r=s.data.access_token;return this.tokenData={access_token:r,refresh_token:s.data.refresh_token,expires_at:V(r,Date.now()+36e5)},this.tokenStore?.setTokens(this.tokenData),this.tokenData}catch(s){throw new Error(`Token refresh failed: ${s instanceof Error?s.message:"Unknown error"}`)}}clearToken(){this.refreshPromise=null,this.tokenData=null,this.tokenStore?.clear()}isAuthenticated(){return this.tokenData!==null}setTokenData(e){let t=e.expires_at||V(e.access_token,Date.now()+36e5);this.tokenData={...e,expires_at:t},this.tokenStore?.setTokens(this.tokenData)}getTokenData(){return this.tokenData}close(){this.sseClient?.close(),this.wsClient?.close()}static parseAuthCallback(e){return O(e)}static buildAuthLoginUrl(e,t){return W(e,t)}};function fe(n){return new H(n)}var B=class{constructor(){this.tokens=null}getTokens(){return this.tokens}setTokens(e){this.tokens=e}clear(){this.tokens=null}},ye="mero-tokens",j=class{constructor(e=ye){this.key=e}getTokens(){try{if(typeof localStorage>"u")return null;let e=localStorage.getItem(this.key);if(!e)return null;let t=JSON.parse(e);return t&&t.access_token&&t.refresh_token?{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:typeof t.expires_at=="number"?t.expires_at:Date.now()+36e5}:null}catch{return null}}setTokens(e){try{if(typeof localStorage>"u")return;localStorage.setItem(this.key,JSON.stringify(e))}catch{}}clear(){try{if(typeof localStorage>"u")return;localStorage.removeItem(this.key)}catch{}}};var J=class{constructor(e={}){this.baseUrl=(e.cloudBaseUrl||"https://cloud.calimero.network").replace(/\/+$/,"")}enableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/enable-ha?${t.toString()}`)}disableHA(e){let t=new URLSearchParams({group_id:e.groupId,context_id:e.contextId});e.redirectUrl&&t.set("redirect_url",e.redirectUrl),window.open(`${this.baseUrl}/disable-ha?${t.toString()}`)}};var Ct={CAN_CREATE_CONTEXT:1,CAN_INVITE_MEMBERS:2,CAN_JOIN_OPEN_SUBGROUPS:4,MANAGE_MEMBERS:8,MANAGE_APPLICATION:16,CAN_CREATE_SUBGROUP:32,CAN_DELETE_SUBGROUP:64,CAN_MANAGE_VISIBILITY:128,CAN_MANAGE_METADATA:256};function Rt(n,e){let t=e>>>0;return(n&t)>>>0===t}function bt(n,e){return(n|e)>>>0}function kt(n,e){return(n&~e)>>>0}var te=[2428,2429,2528,2529],Ce="localhost",Re=2e3;function se(n){return`http://${Ce}:${n}`}function ne(n,e){let t=n.endsWith("/")?n:`${n}/`;return new URL(e,t).toString()}async function re(n,e={}){let{timeoutMs:t=Re,signal:s}=e;if(s?.aborted)return!1;let r=new AbortController,i=()=>r.abort(),o=s;o&&o.addEventListener("abort",i,{once:!0});let c=setTimeout(()=>r.abort(),t);try{let m=ne(n,"admin-api/health"),u=await fetch(m,{method:"GET",signal:r.signal});if(!u.ok)return!1;try{let d=await u.json(),l=d?.data?.status!==void 0?d?.data?.status:d?.status;return l===void 0?!0:typeof l=="string"&&l.toLowerCase()==="alive"}catch{return!0}}catch{return!1}finally{clearTimeout(c),o&&o.removeEventListener("abort",i)}}async function be(n={}){let{ports:e=te,timeoutMs:t,signal:s}=n;return(await Promise.all(e.map(async i=>{let o=se(i);return await re(o,{timeoutMs:t,signal:s})?o:null}))).filter(i=>i!==null)}export{R as AdminApiClient,C as AuthApiClient,I as AuthRevokedError,Ct as CAPABILITIES,J as CloudClient,te as DEFAULT_LOCAL_NODE_PORTS,y as HTTPError,j as LocalStorageTokenStore,B as MemoryTokenStore,H as MeroJs,D as RpcClient,G as RpcError,w as SseClient,v as WebHttpClient,A as WsClient,W as buildAuthLoginUrl,N as combineSignals,de as compareSemver,ze as createAdminApiClient,Z as createAdminApiClientFromHttpClient,qe as createAuthApiClient,z as createAuthApiClientFromHttpClient,Ke as createBrowserAdminApiClient,Ne as createBrowserAuthApiClient,k as createBrowserHttpClient,q as createHttpClient,fe as createMeroJs,Fe as createNodeAdminApiClient,_e as createNodeAuthApiClient,E as createNodeHttpClient,ue as createRetryableMethod,_ as createTimeoutSignal,L as createUniversalHttpClient,be as discoverLocalNodes,Rt as hasCap,se as localNodeUrl,ne as nodeEndpoint,O as parseAuthCallback,re as probeNodeHealth,bt as withCap,M as withRetry,kt as withoutCap};
3
3
  //# sourceMappingURL=index.browser.mjs.map