@forgezero/providers 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/binance.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/http.ts
150
150
  class BudgetExhausted extends ProviderError {
package/dist/chain.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/chain.ts
150
150
  var hexToNumber = (value) => Number(BigInt(value));
@@ -43,11 +43,6 @@ export interface ArangoConfig {
43
43
  url?: string;
44
44
  /** Explicit authenticated private coordinators. Bounded to prevent config abuse. */
45
45
  urls?: readonly string[];
46
- /**
47
- * Optional bootstrap Coordinators already proven to be in Arango `readonly`
48
- * server mode. Prefer signed, probed membership for production.
49
- */
50
- readOnlyUrls?: readonly string[];
51
46
  /**
52
47
  * Dynamic membership is accepted only as a signed/attested envelope verified
53
48
  * by the host. A Worker/KV node list by itself is discovery data, not routing
@@ -65,8 +60,6 @@ export interface ArangoConfig {
65
60
  maxCoordinatorAttempts?: number;
66
61
  /** Local transport-failure quarantine. Primarily injectable for tests. */
67
62
  unhealthyForMs?: number;
68
- /** What an explicit read-only preference does when no read-only coordinator can serve it. */
69
- readOnlyFallback?: 'authoritative' | 'error';
70
63
  now?: () => number;
71
64
  }
72
65
  export interface Query {
@@ -77,24 +70,15 @@ export interface Query {
77
70
  * caller assertions; this adapter never guesses AQL semantics from text.
78
71
  */
79
72
  retrySafety?: 'read' | 'idempotent' | 'never';
80
- /**
81
- * `prefer-readonly` targets Coordinators whose actual Arango server mode is
82
- * `readonly`. It is valid only with `retrySafety: 'read'`; ForgeZero does not
83
- * infer AQL semantics. Community 3.11.14 dirty follower reads are not exposed:
84
- * that server feature is Enterprise-only.
85
- */
86
- readPreference?: 'authoritative' | 'prefer-readonly';
87
73
  /** Required when `retrySafety` is `idempotent`; retained for audit correlation. */
88
74
  idempotencyKey?: string;
89
75
  }
90
76
  export interface ArangoCoordinatorMember {
91
77
  url: string;
92
- /** ArangoDB has no read-only DBServer/client role. Clients address Coordinators. */
78
+ /** Clients address Coordinators; Community 3.11.14 has no read-only joiner role. */
93
79
  role: 'coordinator';
94
80
  /** Actual `/_admin/server/mode` state for this Coordinator. */
95
- serverMode: 'default' | 'readonly';
96
- /** ForgeZero request-routing capability, required to agree with `serverMode`. */
97
- access: 'read-write' | 'read-only';
81
+ serverMode: 'default';
98
82
  capabilities: {
99
83
  /** Always false for the exact Community 3.11.14 contract. */
100
84
  dirtyFollowerReads: false;
@@ -122,7 +106,7 @@ export interface ArangoMembershipSnapshot {
122
106
  export type ArangoMembershipVerifier = (snapshot: ArangoMembershipSnapshot, signal?: AbortSignal) => Promise<boolean>;
123
107
  export declare const MAX_ARANGO_COORDINATORS = 16;
124
108
  export declare const ARANGO_COMMUNITY_VERSION: "3.11.14";
125
- /** Protected per-server API used to attest/set `default` or `readonly` mode. */
109
+ /** Protected API used to attest cluster-wide `default`/maintenance mode. */
126
110
  export declare const ARANGO_SERVER_MODE_PATH: "/_admin/server/mode";
127
111
  /**
128
112
  * Accept only an explicit, bounded set of private authenticated endpoints.
package/dist/database.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/database.ts
150
150
  var pools = new Map;
@@ -187,30 +187,18 @@ function arangoCoordinatorUrls(config) {
187
187
  async function resolveMembership(config, signal) {
188
188
  if (!config.membership) {
189
189
  const urls = arangoCoordinatorUrls(config);
190
- const readOnlyUrls = config.readOnlyUrls?.length ? arangoCoordinatorUrls({ urls: config.readOnlyUrls }) : [];
191
- if (urls.length + readOnlyUrls.length > MAX_ARANGO_COORDINATORS || urls.some((url) => readOnlyUrls.includes(url))) {
192
- throw new ProviderError("ARANGO_COORDINATORS_INVALID", `Writable and read-only ArangoDB coordinator URLs must be disjoint and total at most ${MAX_ARANGO_COORDINATORS}.`);
193
- }
194
190
  return {
195
- members: [...urls.map((url) => ({
191
+ members: urls.map((url) => ({
196
192
  url,
197
193
  role: "coordinator",
198
194
  serverMode: "default",
199
- access: "read-write",
200
- capabilities: { dirtyFollowerReads: false },
201
- status: "healthy"
202
- })), ...readOnlyUrls.map((url) => ({
203
- url,
204
- role: "coordinator",
205
- serverMode: "readonly",
206
- access: "read-only",
207
195
  capabilities: { dirtyFollowerReads: false },
208
196
  status: "healthy"
209
- }))],
210
- identity: `static:${urls.join(",")}:readonly:${readOnlyUrls.join(",")}`
197
+ })),
198
+ identity: `static:${urls.join(",")}`
211
199
  };
212
200
  }
213
- if (config.url || config.urls || config.readOnlyUrls) {
201
+ if (config.url || config.urls) {
214
202
  throw new ProviderError("ARANGO_MEMBERSHIP_AMBIGUOUS", "Configure static coordinator URLs or verified membership, not both.");
215
203
  }
216
204
  if (!config.clusterId || config.membership.clusterId !== config.clusterId) {
@@ -228,7 +216,7 @@ async function resolveMembership(config, signal) {
228
216
  throw new ProviderError("ARANGO_MEMBERSHIP_EXPIRED", "Dynamic ArangoDB membership is not currently valid.");
229
217
  }
230
218
  const validAuthority = snapshot.authority === "forgezero-platform-signed" || snapshot.authority === "node-attested";
231
- const validNodes = snapshot.coordinators.every((node) => Number.isFinite(node.observedAt) && node.nodeKey.length > 0 && node.nodeKey === node.publicKeys?.ed25519 && Boolean(node.publicKeys.mlDsa) && (node.status === "healthy" || node.status === "degraded" || node.status === "unhealthy") && node.role === "coordinator" && (node.serverMode === "default" || node.serverMode === "readonly") && node.access === (node.serverMode === "readonly" ? "read-only" : "read-write") && node.capabilities?.dirtyFollowerReads === false);
219
+ const validNodes = snapshot.coordinators.every((node) => Number.isFinite(node.observedAt) && node.nodeKey.length > 0 && node.nodeKey === node.publicKeys?.ed25519 && Boolean(node.publicKeys.mlDsa) && (node.status === "healthy" || node.status === "degraded" || node.status === "unhealthy") && node.role === "coordinator" && node.serverMode === "default" && node.capabilities?.dirtyFollowerReads === false);
232
220
  if (!validAuthority || !snapshot.revision || !validNodes) {
233
221
  throw new ProviderError("ARANGO_MEMBERSHIP_INVALID", "Dynamic ArangoDB membership needs a revision and observed timestamps.");
234
222
  }
@@ -291,20 +279,8 @@ function selectNode(pool, excluded, now, eligibleMember) {
291
279
  }
292
280
  return;
293
281
  }
294
- function assertReadPolicy(request) {
295
- if (request.readPreference !== undefined && request.readPreference !== "authoritative" && request.readPreference !== "prefer-readonly") {
296
- throw new ProviderError("ARANGO_READ_PREFERENCE_INVALID", "Unknown ArangoDB read preference.");
297
- }
298
- if (request.readPreference && request.retrySafety !== "read") {
299
- throw new ProviderError("ARANGO_READ_PREFERENCE_UNSAFE", "ArangoDB read preference requires an explicit read retry-safety assertion.");
300
- }
301
- }
302
- function nodeForRequest(pool, request, fallback, excluded, now) {
303
- const writable = (node) => node.member.access === "read-write";
304
- if (request.retrySafety === "read" && request.readPreference === "prefer-readonly") {
305
- return selectNode(pool, excluded, now, (node) => node.member.access === "read-only") ?? (fallback === "error" ? undefined : selectNode(pool, excluded, now, writable));
306
- }
307
- return selectNode(pool, excluded, now, writable);
282
+ function nodeForRequest(pool, excluded, now) {
283
+ return selectNode(pool, excluded, now, () => true);
308
284
  }
309
285
  var arangodb = defineProvider({
310
286
  id: "arangodb",
@@ -342,15 +318,6 @@ var arangodb = defineProvider({
342
318
  title: "Coordinator URLs",
343
319
  description: "Authenticated private coordinators in this one logical cluster."
344
320
  },
345
- readOnlyUrls: {
346
- type: "array",
347
- minItems: 1,
348
- maxItems: MAX_ARANGO_COORDINATORS - 1,
349
- uniqueItems: true,
350
- items: { type: "string" },
351
- title: "Read-only Coordinator URLs",
352
- description: "Optional bootstrap endpoints whose protected Arango server mode was probed as readonly."
353
- },
354
321
  clusterId: {
355
322
  type: "string",
356
323
  title: "Cluster ID",
@@ -369,11 +336,6 @@ var arangodb = defineProvider({
369
336
  minimum: 1000,
370
337
  maximum: 300000,
371
338
  title: "Local coordinator quarantine (ms)"
372
- },
373
- readOnlyFallback: {
374
- type: "string",
375
- enum: ["authoritative", "error"],
376
- title: "Read-only coordinator fallback"
377
339
  }
378
340
  }
379
341
  },
@@ -385,11 +347,10 @@ var arangodb = defineProvider({
385
347
  const membership = await resolveMembership(config, context.signal);
386
348
  const members = membership.members;
387
349
  const urls = members.map(({ url }) => url);
388
- assertReadPolicy(request);
389
350
  const safe = requestIsSafe(request);
390
- const available = request.retrySafety === "read" && request.readPreference === "prefer-readonly" && config.readOnlyFallback === "error" ? members.filter(({ serverMode }) => serverMode === "readonly").length : members.filter(({ serverMode }) => request.retrySafety === "read" && request.readPreference === "prefer-readonly" ? true : serverMode === "default").length;
351
+ const available = members.length;
391
352
  if (available === 0) {
392
- throw new ProviderError("ARANGO_COORDINATORS_UNAVAILABLE", request.readPreference === "prefer-readonly" ? "No verified read-only ArangoDB coordinator is available under the configured fallback policy." : "No verified authoritative ArangoDB coordinator is available.");
353
+ throw new ProviderError("ARANGO_COORDINATORS_UNAVAILABLE", "No verified authoritative ArangoDB coordinator is available.");
393
354
  }
394
355
  const attempts = boundedAttempts(config, available, safe);
395
356
  const key = `${membership.identity}/${config.database}/${config.username}`;
@@ -462,7 +423,7 @@ var arangodb = defineProvider({
462
423
  throw context.signal.reason ?? new ProviderError("ARANGO_ABORTED", "ArangoDB request was cancelled.");
463
424
  }
464
425
  const now = (config.now ?? Date.now)();
465
- const node = nodeForRequest(pool, request, config.readOnlyFallback, tried, now);
426
+ const node = nodeForRequest(pool, tried, now);
466
427
  if (!node)
467
428
  break;
468
429
  tried.add(node.url);
package/dist/email.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/email.ts
150
150
  var recipients = (to) => Array.isArray(to) ? [...to] : [to];
package/dist/http.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/http.ts
150
150
  class BudgetExhausted extends ProviderError {
package/dist/index.d.ts CHANGED
@@ -156,4 +156,4 @@ export interface EmailMessage {
156
156
  from?: string;
157
157
  replyTo?: string;
158
158
  }
159
- export declare const VERSION = "0.1.5";
159
+ export declare const VERSION = "0.1.6";
package/dist/index.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
  export {
149
149
  staticConfig,
150
150
  nextHealth,
package/dist/pool.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/http.ts
150
150
  class BudgetExhausted extends ProviderError {
package/dist/storage.js CHANGED
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/storage.ts
150
150
  var encoder = new TextEncoder;
@@ -144,7 +144,7 @@ function createRegistry(options) {
144
144
  }
145
145
  return { call };
146
146
  }
147
- var VERSION = "0.1.5";
147
+ var VERSION = "0.1.6";
148
148
 
149
149
  // src/translation.ts
150
150
  var GOOGLE_ENDPOINT = "https://generativelanguage.googleapis.com/v1beta/models";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgezero/providers",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public",