@private.me/xbind 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -7
- package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -1
- package/dist-standalone/_deps/shared/cjs/errors.js +729 -1
- package/dist-standalone/_deps/shared/cjs/index.js +463 -1
- package/dist-standalone/_deps/shared/cjs/types.js +315 -1
- package/dist-standalone/_deps/shared/errors.js +244 -1
- package/dist-standalone/_deps/shared/index.js +72 -1
- package/dist-standalone/_deps/shared/types.js +86 -1
- package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
- package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
- package/dist-standalone/_deps/ux-helpers/index.js +1 -1
- package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
- package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
- package/dist-standalone/_deps/ux-helpers/search.js +1 -1
- package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
- package/dist-standalone/_deps/xchange/errors.js +1 -1
- package/dist-standalone/_deps/xchange/index.js +1 -1
- package/dist-standalone/_deps/xchange/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/xchange.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
- package/dist-standalone/_deps/xregistry/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/index.js +1 -1
- package/dist-standalone/_deps/xregistry/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/types.js +1 -1
- package/dist-standalone/agent-call.js +659 -1
- package/dist-standalone/agent-sdk.js +328 -1
- package/dist-standalone/agent.js +1800 -1
- package/dist-standalone/approval.js +193 -1
- package/dist-standalone/async-iterators.js +382 -1
- package/dist-standalone/auth.js +219 -1
- package/dist-standalone/auto-accept.js +229 -1
- package/dist-standalone/backup-config.js +201 -1
- package/dist-standalone/backup.js +326 -1
- package/dist-standalone/batch-operations.js +388 -1
- package/dist-standalone/cancellation.js +477 -1
- package/dist-standalone/checkpoint.js +186 -1
- package/dist-standalone/circuit-breaker.js +468 -1
- package/dist-standalone/cjs/agent-call.js +701 -1
- package/dist-standalone/cjs/agent-sdk.js +332 -1
- package/dist-standalone/cjs/agent.js +1837 -1
- package/dist-standalone/cjs/approval.js +199 -1
- package/dist-standalone/cjs/async-iterators.js +392 -1
- package/dist-standalone/cjs/auth.js +225 -1
- package/dist-standalone/cjs/auto-accept.js +233 -1
- package/dist-standalone/cjs/backup-config.js +207 -1
- package/dist-standalone/cjs/backup.js +330 -1
- package/dist-standalone/cjs/batch-operations.js +397 -1
- package/dist-standalone/cjs/cancellation.js +490 -1
- package/dist-standalone/cjs/checkpoint.js +193 -1
- package/dist-standalone/cjs/circuit-breaker.js +476 -1
- package/dist-standalone/cjs/cli/init.js +492 -1
- package/dist-standalone/cjs/config-validation.js +522 -1
- package/dist-standalone/cjs/connect.js +312 -1
- package/dist-standalone/cjs/connection-pool.js +506 -1
- package/dist-standalone/cjs/correlation-id.js +339 -1
- package/dist-standalone/cjs/crypto-utils.js +176 -1
- package/dist-standalone/cjs/debug-mode.js +534 -1
- package/dist-standalone/cjs/did-document.js +101 -1
- package/dist-standalone/cjs/did-privateme.js +130 -1
- package/dist-standalone/cjs/did-web.js +201 -1
- package/dist-standalone/cjs/discovery.js +462 -1
- package/dist-standalone/cjs/dual-mode.js +251 -1
- package/dist-standalone/cjs/email-templates.js +313 -1
- package/dist-standalone/cjs/email-transport.js +239 -1
- package/dist-standalone/cjs/envelope.js +538 -1
- package/dist-standalone/cjs/errors.js +913 -1
- package/dist-standalone/cjs/event-emitter.js +461 -1
- package/dist-standalone/cjs/gateway-state.js +55 -1
- package/dist-standalone/cjs/gateway-transport.js +120 -1
- package/dist-standalone/cjs/graceful-degradation.js +403 -1
- package/dist-standalone/cjs/guardrails.js +223 -1
- package/dist-standalone/cjs/health-check.js +336 -1
- package/dist-standalone/cjs/http-compat.js +272 -1
- package/dist-standalone/cjs/http-status-map.js +571 -1
- package/dist-standalone/cjs/identity.js +645 -1
- package/dist-standalone/cjs/index.js +406 -1
- package/dist-standalone/cjs/invitation.js +421 -1
- package/dist-standalone/cjs/invite.js +328 -1
- package/dist-standalone/cjs/key-agreement.js +335 -1
- package/dist-standalone/cjs/lazy-init.js +300 -1
- package/dist-standalone/cjs/logger.js +291 -1
- package/dist-standalone/cjs/mdns-discovery.js +202 -1
- package/dist-standalone/cjs/nonce-store.js +80 -1
- package/dist-standalone/cjs/pairing-manager.js +223 -1
- package/dist-standalone/cjs/plugin-system.js +264 -1
- package/dist-standalone/cjs/plugins/logging.js +168 -1
- package/dist-standalone/cjs/plugins/metrics.js +181 -1
- package/dist-standalone/cjs/plugins/validation.js +302 -1
- package/dist-standalone/cjs/policy.js +320 -1
- package/dist-standalone/cjs/progress-callbacks.js +583 -1
- package/dist-standalone/cjs/redis-nonce-store.js +76 -1
- package/dist-standalone/cjs/registry-middleware.js +50 -1
- package/dist-standalone/cjs/retry-strategies.js +544 -1
- package/dist-standalone/cjs/retry-transport.js +102 -1
- package/dist-standalone/cjs/runtime/browser.js +533 -1
- package/dist-standalone/cjs/runtime/edge.js +526 -1
- package/dist-standalone/cjs/runtime/react-native.js +394 -1
- package/dist-standalone/cjs/security-policy.js +245 -1
- package/dist-standalone/cjs/serialization.js +1040 -1
- package/dist-standalone/cjs/split-channel.js +225 -1
- package/dist-standalone/cjs/subscription-proof.js +230 -1
- package/dist-standalone/cjs/succession.js +148 -1
- package/dist-standalone/cjs/timeouts.js +412 -1
- package/dist-standalone/cjs/trace-context.js +424 -1
- package/dist-standalone/cjs/trace-spans.js +495 -1
- package/dist-standalone/cjs/transport.js +63 -1
- package/dist-standalone/cjs/trust-registry.js +991 -1
- package/dist-standalone/cjs/types/error-response.js +56 -1
- package/dist-standalone/cjs/vault-auth.js +178 -1
- package/dist-standalone/cjs/vault-store-loader.js +194 -1
- package/dist-standalone/cjs/verify.js +25 -1
- package/dist-standalone/cjs/version-info.js +543 -1
- package/dist-standalone/cjs/xfetch.js +340 -1
- package/dist-standalone/cli/init.js +455 -1
- package/dist-standalone/cli/setup.js +514 -1
- package/dist-standalone/cli/types.js +27 -1
- package/dist-standalone/cli/xbind.js +148 -1
- package/dist-standalone/config-validation.js +513 -1
- package/dist-standalone/connect.js +274 -1
- package/dist-standalone/connection-pool.js +500 -1
- package/dist-standalone/correlation-id.js +326 -1
- package/dist-standalone/crypto-utils.js +157 -1
- package/dist-standalone/debug-mode.js +510 -1
- package/dist-standalone/did-document.js +96 -1
- package/dist-standalone/did-privateme.js +121 -1
- package/dist-standalone/did-web.js +196 -1
- package/dist-standalone/discovery.js +458 -1
- package/dist-standalone/dual-mode.js +247 -1
- package/dist-standalone/email-templates.js +309 -1
- package/dist-standalone/email-transport.js +232 -1
- package/dist-standalone/envelope.js +525 -1
- package/dist-standalone/errors.js +896 -1
- package/dist-standalone/event-emitter.js +456 -1
- package/dist-standalone/gateway-state.js +51 -1
- package/dist-standalone/gateway-transport.js +116 -1
- package/dist-standalone/graceful-degradation.js +396 -1
- package/dist-standalone/guardrails.js +216 -1
- package/dist-standalone/health-check.js +332 -1
- package/dist-standalone/http-compat.js +267 -1
- package/dist-standalone/http-status-map.js +561 -1
- package/dist-standalone/identity.js +619 -1
- package/dist-standalone/index.js +78 -1
- package/dist-standalone/invitation.js +415 -1
- package/dist-standalone/invite.js +324 -1
- package/dist-standalone/key-agreement.js +325 -1
- package/dist-standalone/lazy-init.js +295 -1
- package/dist-standalone/logger.js +285 -1
- package/dist-standalone/mdns-discovery.js +195 -1
- package/dist-standalone/nonce-store.js +76 -1
- package/dist-standalone/pairing-manager.js +219 -1
- package/dist-standalone/plugin-system.js +257 -1
- package/dist-standalone/plugins/logging.d.ts +84 -0
- package/dist-standalone/plugins/logging.js +163 -0
- package/dist-standalone/plugins/metrics.d.ts +111 -0
- package/dist-standalone/plugins/metrics.js +176 -0
- package/dist-standalone/plugins/validation.d.ts +104 -0
- package/dist-standalone/plugins/validation.js +297 -0
- package/dist-standalone/policy.js +315 -1
- package/dist-standalone/progress-callbacks.js +576 -1
- package/dist-standalone/redis-nonce-store.js +72 -1
- package/dist-standalone/registry-middleware.js +47 -1
- package/dist-standalone/retry-strategies.js +534 -1
- package/dist-standalone/retry-transport.js +98 -1
- package/dist-standalone/runtime/browser.d.ts +311 -0
- package/dist-standalone/runtime/browser.js +516 -0
- package/dist-standalone/runtime/edge.d.ts +282 -0
- package/dist-standalone/runtime/edge.js +511 -0
- package/dist-standalone/runtime/react-native.d.ts +157 -0
- package/dist-standalone/runtime/react-native.js +383 -0
- package/dist-standalone/security-policy.js +239 -1
- package/dist-standalone/serialization.js +1031 -1
- package/dist-standalone/split-channel.js +219 -1
- package/dist-standalone/subscription-proof.js +224 -1
- package/dist-standalone/succession.js +142 -1
- package/dist-standalone/timeouts.js +398 -1
- package/dist-standalone/trace-context.js +414 -1
- package/dist-standalone/trace-spans.js +488 -1
- package/dist-standalone/transport.js +59 -1
- package/dist-standalone/trust-registry.js +950 -1
- package/dist-standalone/types/error-response.d.ts +209 -0
- package/dist-standalone/types/error-response.js +52 -0
- package/dist-standalone/vault-auth.js +174 -1
- package/dist-standalone/vault-store-loader.js +187 -1
- package/dist-standalone/verify.js +16 -1
- package/dist-standalone/version-info.js +530 -1
- package/dist-standalone/xfetch.js +335 -1
- package/package.json +4 -10
- package/share1.dat +0 -0
- package/dist-standalone/_deps/mldsa-wasm/LICENSE +0 -24
- package/dist-standalone/_deps/mldsa-wasm/package.json +0 -46
- package/dist-standalone/_deps/shared/cjs/package.json +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/package.json +0 -1
- package/dist-standalone/_deps/xchange/cjs/package.json +0 -1
- package/dist-standalone/_deps/xregistry/cjs/package.json +0 -1
- package/dist-standalone/cjs/package.json +0 -3
- package/dist-standalone/package.json +0 -10
|
@@ -1 +1,388 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module batch-operations
|
|
3
|
+
* Batch operations support for xBind - enhanced API efficiency
|
|
4
|
+
*
|
|
5
|
+
* Provides batch operations for:
|
|
6
|
+
* - Send: Multiple messages in one call (reduces round-trips)
|
|
7
|
+
* - Receive: Batch envelope processing
|
|
8
|
+
* - Registry: Bulk registration/revocation/updates
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - Atomic semantics where possible (registry operations)
|
|
12
|
+
* - Partial success handling (graceful degradation)
|
|
13
|
+
* - Progress tracking for long-running batches
|
|
14
|
+
* - Performance optimization (parallel processing)
|
|
15
|
+
*/
|
|
16
|
+
import { err } from"./_deps/shared/index.js";
|
|
17
|
+
import { ProgressReporter } from"./_deps/ux-helpers/index.js";
|
|
18
|
+
/**
|
|
19
|
+
* Error thrown when batch operation fails.
|
|
20
|
+
*/
|
|
21
|
+
export class BatchOperationError extends Error {
|
|
22
|
+
summary;
|
|
23
|
+
constructor(message, summary) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.summary = summary;
|
|
26
|
+
this.name = 'BatchOperationError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/* ── Implementation ── */
|
|
30
|
+
/**
|
|
31
|
+
* Batch send multiple messages.
|
|
32
|
+
*
|
|
33
|
+
* Performance optimization: Sends messages in parallel (default) or sequentially.
|
|
34
|
+
* Reduces round-trips for bulk message delivery.
|
|
35
|
+
*
|
|
36
|
+
* @param agent - Agent instance
|
|
37
|
+
* @param options - Batch send options
|
|
38
|
+
* @returns Batch summary with individual results
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const agent = await Agent.create({ name: 'sender', registry });
|
|
43
|
+
* const summary = await batchSend(agent, {
|
|
44
|
+
* messages: [
|
|
45
|
+
* { to: 'did:key:abc', payload: { msg: 1 }, scope: 'chat' },
|
|
46
|
+
* { to: 'did:key:def', payload: { msg: 2 }, scope: 'chat' },
|
|
47
|
+
* ],
|
|
48
|
+
* strategy: 'parallel',
|
|
49
|
+
* });
|
|
50
|
+
* console.log(`Sent ${summary.succeeded}/${summary.total} messages`);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export async function batchSend(agent, options) {
|
|
54
|
+
const progress = new ProgressReporter(options.onProgress);
|
|
55
|
+
const startTime = Date.now();
|
|
56
|
+
const { messages, strategy = 'parallel', concurrency = 10, continueOnError = true, } = options;
|
|
57
|
+
progress.start(`Sending ${messages.length} messages (${strategy} mode)...`);
|
|
58
|
+
const results = [];
|
|
59
|
+
if (strategy === 'sequential') {
|
|
60
|
+
// Sequential: preserve ordering
|
|
61
|
+
for (let i = 0; i < messages.length; i++) {
|
|
62
|
+
const msg = messages[i];
|
|
63
|
+
const opStart = Date.now();
|
|
64
|
+
progress.update(`Sending message ${i + 1}/${messages.length}...`, (i / messages.length) * 100);
|
|
65
|
+
const result = await agent.send(msg);
|
|
66
|
+
const durationMs = Date.now() - opStart;
|
|
67
|
+
results.push({ index: i, result, durationMs });
|
|
68
|
+
if (!continueOnError && !result.ok) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (strategy === 'failfast') {
|
|
74
|
+
// Parallel with fail-fast: stop immediately on first error
|
|
75
|
+
const promises = messages.map((msg, index) => {
|
|
76
|
+
const opStart = Date.now();
|
|
77
|
+
return agent.send(msg).then(result => {
|
|
78
|
+
const durationMs = Date.now() - opStart;
|
|
79
|
+
if (!result.ok) {
|
|
80
|
+
throw new BatchOperationError(`Batch send failed at index ${index}: ${result.error}`, createSummary(results, Date.now() - startTime));
|
|
81
|
+
}
|
|
82
|
+
return { index, result, durationMs };
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
try {
|
|
86
|
+
const allResults = await Promise.all(promises);
|
|
87
|
+
results.push(...allResults);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (error instanceof BatchOperationError) {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
throw new BatchOperationError('Batch send failed', createSummary(results, Date.now() - startTime));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Parallel: process concurrently with controlled concurrency
|
|
98
|
+
const chunks = chunkArray(messages, concurrency);
|
|
99
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
100
|
+
const chunk = chunks[chunkIndex];
|
|
101
|
+
const baseIndex = chunkIndex * concurrency;
|
|
102
|
+
progress.update(`Processing chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
|
|
103
|
+
const chunkResults = await Promise.all(chunk.map(async (msg, offset) => {
|
|
104
|
+
const index = baseIndex + offset;
|
|
105
|
+
const opStart = Date.now();
|
|
106
|
+
const result = await agent.send(msg);
|
|
107
|
+
const durationMs = Date.now() - opStart;
|
|
108
|
+
return { index, result, durationMs };
|
|
109
|
+
}));
|
|
110
|
+
results.push(...chunkResults);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
progress.complete();
|
|
114
|
+
return createSummary(results, Date.now() - startTime);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Batch receive multiple envelopes.
|
|
118
|
+
*
|
|
119
|
+
* Performance optimization: Processes envelopes in parallel (default).
|
|
120
|
+
* Useful for bulk message ingestion from queues or webhooks.
|
|
121
|
+
*
|
|
122
|
+
* @param agent - Agent instance
|
|
123
|
+
* @param options - Batch receive options
|
|
124
|
+
* @returns Batch summary with individual results
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const agent = await Agent.create({ name: 'receiver', registry });
|
|
129
|
+
* const summary = await batchReceive(agent, {
|
|
130
|
+
* envelopes: incomingEnvelopes,
|
|
131
|
+
* strategy: 'parallel',
|
|
132
|
+
* });
|
|
133
|
+
* console.log(`Processed ${summary.succeeded}/${summary.total} envelopes`);
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export async function batchReceive(agent, options) {
|
|
137
|
+
const progress = new ProgressReporter(options.onProgress);
|
|
138
|
+
const startTime = Date.now();
|
|
139
|
+
const { envelopes, receiveOptions, strategy = 'parallel', concurrency = 10, continueOnError = true, } = options;
|
|
140
|
+
progress.start(`Receiving ${envelopes.length} envelopes (${strategy} mode)...`);
|
|
141
|
+
const results = [];
|
|
142
|
+
if (strategy === 'sequential') {
|
|
143
|
+
// Sequential: preserve ordering
|
|
144
|
+
for (let i = 0; i < envelopes.length; i++) {
|
|
145
|
+
const envelope = envelopes[i];
|
|
146
|
+
const opStart = Date.now();
|
|
147
|
+
progress.update(`Receiving envelope ${i + 1}/${envelopes.length}...`, (i / envelopes.length) * 100);
|
|
148
|
+
const result = await agent.receive(envelope, receiveOptions);
|
|
149
|
+
const durationMs = Date.now() - opStart;
|
|
150
|
+
results.push({ index: i, result, durationMs });
|
|
151
|
+
if (!continueOnError && !result.ok) {
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Parallel: process concurrently with controlled concurrency
|
|
158
|
+
const chunks = chunkArray(envelopes, concurrency);
|
|
159
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
160
|
+
const chunk = chunks[chunkIndex];
|
|
161
|
+
const baseIndex = chunkIndex * concurrency;
|
|
162
|
+
progress.update(`Processing chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
|
|
163
|
+
const chunkResults = await Promise.all(chunk.map(async (envelope, offset) => {
|
|
164
|
+
const index = baseIndex + offset;
|
|
165
|
+
const opStart = Date.now();
|
|
166
|
+
const result = await agent.receive(envelope, receiveOptions);
|
|
167
|
+
const durationMs = Date.now() - opStart;
|
|
168
|
+
return { index, result, durationMs };
|
|
169
|
+
}));
|
|
170
|
+
results.push(...chunkResults);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
progress.complete();
|
|
174
|
+
return createSummary(results, Date.now() - startTime);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Batch registry operations (register, revoke, updateScopes).
|
|
178
|
+
*
|
|
179
|
+
* Performance optimization: Groups operations by type for efficient processing.
|
|
180
|
+
* Atomic semantics: When atomic=true, all operations succeed or all fail.
|
|
181
|
+
*
|
|
182
|
+
* @param registry - Trust registry instance
|
|
183
|
+
* @param options - Batch registry options
|
|
184
|
+
* @returns Batch summary with individual results
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* const summary = await batchRegistryOps(registry, {
|
|
189
|
+
* operations: [
|
|
190
|
+
* { type: 'register', did: 'did:key:abc', params: { publicKey, name: 'Alice' } },
|
|
191
|
+
* { type: 'revoke', did: 'did:key:old' },
|
|
192
|
+
* ],
|
|
193
|
+
* atomic: false, // best-effort mode
|
|
194
|
+
* });
|
|
195
|
+
* console.log(`Completed ${summary.succeeded}/${summary.total} operations`);
|
|
196
|
+
* ```
|
|
197
|
+
*/
|
|
198
|
+
export async function batchRegistryOps(registry, options) {
|
|
199
|
+
const progress = new ProgressReporter(options.onProgress);
|
|
200
|
+
const startTime = Date.now();
|
|
201
|
+
const { operations, atomic = false, strategy = 'parallel', concurrency = 5, } = options;
|
|
202
|
+
progress.start(`Executing ${operations.length} registry operations (${atomic ? 'atomic' : 'best-effort'} mode)...`);
|
|
203
|
+
const results = [];
|
|
204
|
+
// Atomic mode: execute all or rollback (not implemented in base TrustRegistry)
|
|
205
|
+
// This is a placeholder for future transaction support
|
|
206
|
+
if (atomic) {
|
|
207
|
+
progress.update('Warning: Atomic mode not fully implemented - using best-effort', 10);
|
|
208
|
+
}
|
|
209
|
+
if (strategy === 'sequential') {
|
|
210
|
+
// Sequential: preserve ordering
|
|
211
|
+
for (let i = 0; i < operations.length; i++) {
|
|
212
|
+
const op = operations[i];
|
|
213
|
+
const opStart = Date.now();
|
|
214
|
+
progress.update(`Operation ${i + 1}/${operations.length}: ${op.type} ${op.did}`, (i / operations.length) * 100);
|
|
215
|
+
const result = await executeRegistryOperation(registry, op);
|
|
216
|
+
const durationMs = Date.now() - opStart;
|
|
217
|
+
results.push({ index: i, result, durationMs });
|
|
218
|
+
if (atomic && !result.ok) {
|
|
219
|
+
// TODO: Rollback previous operations
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// Parallel: process concurrently with controlled concurrency
|
|
226
|
+
const chunks = chunkArray(operations, concurrency);
|
|
227
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
228
|
+
const chunk = chunks[chunkIndex];
|
|
229
|
+
const baseIndex = chunkIndex * concurrency;
|
|
230
|
+
progress.update(`Processing chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
|
|
231
|
+
const chunkResults = await Promise.all(chunk.map(async (op, offset) => {
|
|
232
|
+
const index = baseIndex + offset;
|
|
233
|
+
const opStart = Date.now();
|
|
234
|
+
const result = await executeRegistryOperation(registry, op);
|
|
235
|
+
const durationMs = Date.now() - opStart;
|
|
236
|
+
return { index, result, durationMs };
|
|
237
|
+
}));
|
|
238
|
+
results.push(...chunkResults);
|
|
239
|
+
if (atomic && chunkResults.some(r => !r.result.ok)) {
|
|
240
|
+
// TODO: Rollback all operations
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
progress.complete();
|
|
246
|
+
return createSummary(results, Date.now() - startTime);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Batch resolve multiple DIDs.
|
|
250
|
+
*
|
|
251
|
+
* Performance optimization: Resolves DIDs in parallel.
|
|
252
|
+
* Useful for resolving recipient keys before bulk message sending.
|
|
253
|
+
*
|
|
254
|
+
* @param registry - Trust registry instance
|
|
255
|
+
* @param dids - DIDs to resolve
|
|
256
|
+
* @param options - Optional progress callback and concurrency
|
|
257
|
+
* @returns Batch summary with resolution results
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const summary = await batchResolve(registry, [
|
|
262
|
+
* 'did:key:abc',
|
|
263
|
+
* 'did:key:def',
|
|
264
|
+
* 'did:key:ghi',
|
|
265
|
+
* ]);
|
|
266
|
+
* const keys = summary.results
|
|
267
|
+
* .filter(r => r.result.ok)
|
|
268
|
+
* .map(r => r.result.value);
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export async function batchResolve(registry, dids, options) {
|
|
272
|
+
const progress = new ProgressReporter(options?.onProgress);
|
|
273
|
+
const startTime = Date.now();
|
|
274
|
+
const concurrency = options?.concurrency ?? 10;
|
|
275
|
+
progress.start(`Resolving ${dids.length} DIDs...`);
|
|
276
|
+
const results = [];
|
|
277
|
+
const chunks = chunkArray(dids, concurrency);
|
|
278
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
279
|
+
const chunk = chunks[chunkIndex];
|
|
280
|
+
const baseIndex = chunkIndex * concurrency;
|
|
281
|
+
progress.update(`Resolving chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
|
|
282
|
+
const chunkResults = await Promise.all(chunk.map(async (did, offset) => {
|
|
283
|
+
const index = baseIndex + offset;
|
|
284
|
+
const opStart = Date.now();
|
|
285
|
+
const result = await registry.resolve(did);
|
|
286
|
+
const durationMs = Date.now() - opStart;
|
|
287
|
+
return { index, result, durationMs };
|
|
288
|
+
}));
|
|
289
|
+
results.push(...chunkResults);
|
|
290
|
+
}
|
|
291
|
+
progress.complete();
|
|
292
|
+
return createSummary(results, Date.now() - startTime);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Batch get registry entries.
|
|
296
|
+
*
|
|
297
|
+
* Performance optimization: Fetches entries in parallel.
|
|
298
|
+
* Returns full registry metadata for multiple DIDs.
|
|
299
|
+
*
|
|
300
|
+
* @param registry - Trust registry instance
|
|
301
|
+
* @param dids - DIDs to fetch
|
|
302
|
+
* @param options - Optional progress callback and concurrency
|
|
303
|
+
* @returns Batch summary with entry results
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```typescript
|
|
307
|
+
* const summary = await batchGetEntries(registry, dids);
|
|
308
|
+
* const entries = summary.results
|
|
309
|
+
* .filter(r => r.result.ok)
|
|
310
|
+
* .map(r => r.result.value);
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
export async function batchGetEntries(registry, dids, options) {
|
|
314
|
+
const progress = new ProgressReporter(options?.onProgress);
|
|
315
|
+
const startTime = Date.now();
|
|
316
|
+
const concurrency = options?.concurrency ?? 10;
|
|
317
|
+
progress.start(`Fetching ${dids.length} registry entries...`);
|
|
318
|
+
const results = [];
|
|
319
|
+
const chunks = chunkArray(dids, concurrency);
|
|
320
|
+
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
|
|
321
|
+
const chunk = chunks[chunkIndex];
|
|
322
|
+
const baseIndex = chunkIndex * concurrency;
|
|
323
|
+
progress.update(`Fetching chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
|
|
324
|
+
const chunkResults = await Promise.all(chunk.map(async (did, offset) => {
|
|
325
|
+
const index = baseIndex + offset;
|
|
326
|
+
const opStart = Date.now();
|
|
327
|
+
const result = await registry.getEntry(did);
|
|
328
|
+
const durationMs = Date.now() - opStart;
|
|
329
|
+
return { index, result, durationMs };
|
|
330
|
+
}));
|
|
331
|
+
results.push(...chunkResults);
|
|
332
|
+
}
|
|
333
|
+
progress.complete();
|
|
334
|
+
return createSummary(results, Date.now() - startTime);
|
|
335
|
+
}
|
|
336
|
+
/* ── Helper Functions ── */
|
|
337
|
+
/**
|
|
338
|
+
* Execute a single registry operation.
|
|
339
|
+
*/
|
|
340
|
+
async function executeRegistryOperation(registry, op) {
|
|
341
|
+
switch (op.type) {
|
|
342
|
+
case 'register': {
|
|
343
|
+
if (!op.params) {
|
|
344
|
+
return err('INVALID_PARAMS');
|
|
345
|
+
}
|
|
346
|
+
const { publicKey, name, scopes, x25519PublicKey, mlKemPublicKey, mlDsaPublicKey, xchange, receiveScopes, sdkVersion, minEnvelopeVersion, maxEnvelopeVersion, ttlMs } = op.params;
|
|
347
|
+
return registry.register(op.did, publicKey, name, scopes, x25519PublicKey, mlKemPublicKey, mlDsaPublicKey, xchange, receiveScopes, sdkVersion, minEnvelopeVersion, maxEnvelopeVersion, ttlMs);
|
|
348
|
+
}
|
|
349
|
+
case 'revoke':
|
|
350
|
+
return registry.revoke(op.did);
|
|
351
|
+
case 'updateScopes': {
|
|
352
|
+
if (!op.newScopes || !('updateScopes' in registry) || typeof registry.updateScopes !== 'function') {
|
|
353
|
+
return err('INVALID_PARAMS');
|
|
354
|
+
}
|
|
355
|
+
return registry.updateScopes(op.did, op.newScopes);
|
|
356
|
+
}
|
|
357
|
+
default:
|
|
358
|
+
return err('INVALID_OPERATION');
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Create batch summary from results.
|
|
363
|
+
*/
|
|
364
|
+
function createSummary(results, totalDurationMs) {
|
|
365
|
+
const succeeded = results.filter(r => r.result.ok).length;
|
|
366
|
+
const failed = results.filter(r => !r.result.ok).length;
|
|
367
|
+
const avgDurationMs = results.length > 0
|
|
368
|
+
? results.reduce((sum, r) => sum + r.durationMs, 0) / results.length
|
|
369
|
+
: 0;
|
|
370
|
+
return {
|
|
371
|
+
total: results.length,
|
|
372
|
+
succeeded,
|
|
373
|
+
failed,
|
|
374
|
+
results,
|
|
375
|
+
totalDurationMs,
|
|
376
|
+
avgDurationMs,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Split array into chunks of specified size.
|
|
381
|
+
*/
|
|
382
|
+
function chunkArray(array, size) {
|
|
383
|
+
const chunks = [];
|
|
384
|
+
for (let i = 0; i < array.length; i += size) {
|
|
385
|
+
chunks.push(array.slice(i, i + size));
|
|
386
|
+
}
|
|
387
|
+
return chunks;
|
|
388
|
+
}
|