camusdb 0.1.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.
Files changed (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +950 -0
  3. package/dist/auth/credentials.d.ts +30 -0
  4. package/dist/auth/credentials.d.ts.map +1 -0
  5. package/dist/auth/credentials.js +23 -0
  6. package/dist/auth/credentials.js.map +1 -0
  7. package/dist/auth/login-client.d.ts +37 -0
  8. package/dist/auth/login-client.d.ts.map +1 -0
  9. package/dist/auth/login-client.js +8 -0
  10. package/dist/auth/login-client.js.map +1 -0
  11. package/dist/auth/rest-login-client.d.ts +17 -0
  12. package/dist/auth/rest-login-client.d.ts.map +1 -0
  13. package/dist/auth/rest-login-client.js +71 -0
  14. package/dist/auth/rest-login-client.js.map +1 -0
  15. package/dist/auth/token-provider.d.ts +123 -0
  16. package/dist/auth/token-provider.d.ts.map +1 -0
  17. package/dist/auth/token-provider.js +209 -0
  18. package/dist/auth/token-provider.js.map +1 -0
  19. package/dist/backup.d.ts +98 -0
  20. package/dist/backup.d.ts.map +1 -0
  21. package/dist/backup.js +153 -0
  22. package/dist/backup.js.map +1 -0
  23. package/dist/cache.d.ts +90 -0
  24. package/dist/cache.d.ts.map +1 -0
  25. package/dist/cache.js +121 -0
  26. package/dist/cache.js.map +1 -0
  27. package/dist/client.d.ts +406 -0
  28. package/dist/client.d.ts.map +1 -0
  29. package/dist/client.js +724 -0
  30. package/dist/client.js.map +1 -0
  31. package/dist/column-type.d.ts +33 -0
  32. package/dist/column-type.d.ts.map +1 -0
  33. package/dist/column-type.js +50 -0
  34. package/dist/column-type.js.map +1 -0
  35. package/dist/column-value.d.ts +77 -0
  36. package/dist/column-value.d.ts.map +1 -0
  37. package/dist/column-value.js +60 -0
  38. package/dist/column-value.js.map +1 -0
  39. package/dist/config.d.ts +181 -0
  40. package/dist/config.d.ts.map +1 -0
  41. package/dist/config.js +315 -0
  42. package/dist/config.js.map +1 -0
  43. package/dist/connection-string.d.ts +45 -0
  44. package/dist/connection-string.d.ts.map +1 -0
  45. package/dist/connection-string.js +170 -0
  46. package/dist/connection-string.js.map +1 -0
  47. package/dist/endpoint-pool.d.ts +70 -0
  48. package/dist/endpoint-pool.d.ts.map +1 -0
  49. package/dist/endpoint-pool.js +120 -0
  50. package/dist/endpoint-pool.js.map +1 -0
  51. package/dist/error-codes.d.ts +44 -0
  52. package/dist/error-codes.d.ts.map +1 -0
  53. package/dist/error-codes.js +43 -0
  54. package/dist/error-codes.js.map +1 -0
  55. package/dist/errors.d.ts +24 -0
  56. package/dist/errors.d.ts.map +1 -0
  57. package/dist/errors.js +33 -0
  58. package/dist/errors.js.map +1 -0
  59. package/dist/hlc.d.ts +19 -0
  60. package/dist/hlc.d.ts.map +1 -0
  61. package/dist/hlc.js +11 -0
  62. package/dist/hlc.js.map +1 -0
  63. package/dist/index.d.ts +55 -0
  64. package/dist/index.d.ts.map +1 -0
  65. package/dist/index.js +51 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/json.d.ts +41 -0
  68. package/dist/json.d.ts.map +1 -0
  69. package/dist/json.js +345 -0
  70. package/dist/json.js.map +1 -0
  71. package/dist/object-id.d.ts +39 -0
  72. package/dist/object-id.d.ts.map +1 -0
  73. package/dist/object-id.js +99 -0
  74. package/dist/object-id.js.map +1 -0
  75. package/dist/options.d.ts +77 -0
  76. package/dist/options.d.ts.map +1 -0
  77. package/dist/options.js +68 -0
  78. package/dist/options.js.map +1 -0
  79. package/dist/prepared/binder.d.ts +20 -0
  80. package/dist/prepared/binder.d.ts.map +1 -0
  81. package/dist/prepared/binder.js +32 -0
  82. package/dist/prepared/binder.js.map +1 -0
  83. package/dist/prepared/policy.d.ts +81 -0
  84. package/dist/prepared/policy.d.ts.map +1 -0
  85. package/dist/prepared/policy.js +164 -0
  86. package/dist/prepared/policy.js.map +1 -0
  87. package/dist/query-stream.d.ts +55 -0
  88. package/dist/query-stream.d.ts.map +1 -0
  89. package/dist/query-stream.js +94 -0
  90. package/dist/query-stream.js.map +1 -0
  91. package/dist/result-set.d.ts +62 -0
  92. package/dist/result-set.d.ts.map +1 -0
  93. package/dist/result-set.js +100 -0
  94. package/dist/result-set.js.map +1 -0
  95. package/dist/retry.d.ts +38 -0
  96. package/dist/retry.d.ts.map +1 -0
  97. package/dist/retry.js +93 -0
  98. package/dist/retry.js.map +1 -0
  99. package/dist/routing/advice.d.ts +63 -0
  100. package/dist/routing/advice.d.ts.map +1 -0
  101. package/dist/routing/advice.js +61 -0
  102. package/dist/routing/advice.js.map +1 -0
  103. package/dist/routing/route-cache.d.ts +53 -0
  104. package/dist/routing/route-cache.d.ts.map +1 -0
  105. package/dist/routing/route-cache.js +123 -0
  106. package/dist/routing/route-cache.js.map +1 -0
  107. package/dist/routing/router.d.ts +53 -0
  108. package/dist/routing/router.d.ts.map +1 -0
  109. package/dist/routing/router.js +89 -0
  110. package/dist/routing/router.js.map +1 -0
  111. package/dist/row-source.d.ts +48 -0
  112. package/dist/row-source.d.ts.map +1 -0
  113. package/dist/row-source.js +35 -0
  114. package/dist/row-source.js.map +1 -0
  115. package/dist/runtime.d.ts +58 -0
  116. package/dist/runtime.d.ts.map +1 -0
  117. package/dist/runtime.js +137 -0
  118. package/dist/runtime.js.map +1 -0
  119. package/dist/shared-registry.d.ts +32 -0
  120. package/dist/shared-registry.d.ts.map +1 -0
  121. package/dist/shared-registry.js +48 -0
  122. package/dist/shared-registry.js.map +1 -0
  123. package/dist/sql-syntax.d.ts +44 -0
  124. package/dist/sql-syntax.d.ts.map +1 -0
  125. package/dist/sql-syntax.js +83 -0
  126. package/dist/sql-syntax.js.map +1 -0
  127. package/dist/statements.d.ts +15 -0
  128. package/dist/statements.d.ts.map +1 -0
  129. package/dist/statements.js +90 -0
  130. package/dist/statements.js.map +1 -0
  131. package/dist/transaction.d.ts +117 -0
  132. package/dist/transaction.d.ts.map +1 -0
  133. package/dist/transaction.js +204 -0
  134. package/dist/transaction.js.map +1 -0
  135. package/dist/transport/authenticating-transport.d.ts +63 -0
  136. package/dist/transport/authenticating-transport.d.ts.map +1 -0
  137. package/dist/transport/authenticating-transport.js +119 -0
  138. package/dist/transport/authenticating-transport.js.map +1 -0
  139. package/dist/transport/branch-statements.d.ts +39 -0
  140. package/dist/transport/branch-statements.d.ts.map +1 -0
  141. package/dist/transport/branch-statements.js +74 -0
  142. package/dist/transport/branch-statements.js.map +1 -0
  143. package/dist/transport/error-text.d.ts +26 -0
  144. package/dist/transport/error-text.d.ts.map +1 -0
  145. package/dist/transport/error-text.js +75 -0
  146. package/dist/transport/error-text.js.map +1 -0
  147. package/dist/transport/grpc/batcher.d.ts +127 -0
  148. package/dist/transport/grpc/batcher.d.ts.map +1 -0
  149. package/dist/transport/grpc/batcher.js +399 -0
  150. package/dist/transport/grpc/batcher.js.map +1 -0
  151. package/dist/transport/grpc/codec.d.ts +40 -0
  152. package/dist/transport/grpc/codec.d.ts.map +1 -0
  153. package/dist/transport/grpc/codec.js +231 -0
  154. package/dist/transport/grpc/codec.js.map +1 -0
  155. package/dist/transport/grpc/grpc-transport.d.ts +115 -0
  156. package/dist/transport/grpc/grpc-transport.d.ts.map +1 -0
  157. package/dist/transport/grpc/grpc-transport.js +577 -0
  158. package/dist/transport/grpc/grpc-transport.js.map +1 -0
  159. package/dist/transport/grpc/messages.d.ts +221 -0
  160. package/dist/transport/grpc/messages.d.ts.map +1 -0
  161. package/dist/transport/grpc/messages.js +56 -0
  162. package/dist/transport/grpc/messages.js.map +1 -0
  163. package/dist/transport/grpc/proto.d.ts +71 -0
  164. package/dist/transport/grpc/proto.d.ts.map +1 -0
  165. package/dist/transport/grpc/proto.js +67 -0
  166. package/dist/transport/grpc/proto.js.map +1 -0
  167. package/dist/transport/http.d.ts +62 -0
  168. package/dist/transport/http.d.ts.map +1 -0
  169. package/dist/transport/http.js +169 -0
  170. package/dist/transport/http.js.map +1 -0
  171. package/dist/transport/ndjson-row-source.d.ts +38 -0
  172. package/dist/transport/ndjson-row-source.d.ts.map +1 -0
  173. package/dist/transport/ndjson-row-source.js +197 -0
  174. package/dist/transport/ndjson-row-source.js.map +1 -0
  175. package/dist/transport/rest-decode.d.ts +33 -0
  176. package/dist/transport/rest-decode.d.ts.map +1 -0
  177. package/dist/transport/rest-decode.js +162 -0
  178. package/dist/transport/rest-decode.js.map +1 -0
  179. package/dist/transport/rest-prepared-cache.d.ts +50 -0
  180. package/dist/transport/rest-prepared-cache.d.ts.map +1 -0
  181. package/dist/transport/rest-prepared-cache.js +101 -0
  182. package/dist/transport/rest-prepared-cache.js.map +1 -0
  183. package/dist/transport/rest-transport.d.ts +88 -0
  184. package/dist/transport/rest-transport.d.ts.map +1 -0
  185. package/dist/transport/rest-transport.js +388 -0
  186. package/dist/transport/rest-transport.js.map +1 -0
  187. package/dist/transport/transport-pool.d.ts +40 -0
  188. package/dist/transport/transport-pool.d.ts.map +1 -0
  189. package/dist/transport/transport-pool.js +48 -0
  190. package/dist/transport/transport-pool.js.map +1 -0
  191. package/dist/transport/transport.d.ts +199 -0
  192. package/dist/transport/transport.d.ts.map +1 -0
  193. package/dist/transport/transport.js +11 -0
  194. package/dist/transport/transport.js.map +1 -0
  195. package/dist/values/decode.d.ts +39 -0
  196. package/dist/values/decode.d.ts.map +1 -0
  197. package/dist/values/decode.js +75 -0
  198. package/dist/values/decode.js.map +1 -0
  199. package/dist/values/encode.d.ts +45 -0
  200. package/dist/values/encode.d.ts.map +1 -0
  201. package/dist/values/encode.js +271 -0
  202. package/dist/values/encode.js.map +1 -0
  203. package/dist/values/ticks.d.ts +31 -0
  204. package/dist/values/ticks.d.ts.map +1 -0
  205. package/dist/values/ticks.js +52 -0
  206. package/dist/values/ticks.js.map +1 -0
  207. package/dist/values/typed.d.ts +67 -0
  208. package/dist/values/typed.d.ts.map +1 -0
  209. package/dist/values/typed.js +134 -0
  210. package/dist/values/typed.js.map +1 -0
  211. package/dist/values/uuid.d.ts +27 -0
  212. package/dist/values/uuid.d.ts.map +1 -0
  213. package/dist/values/uuid.js +76 -0
  214. package/dist/values/uuid.js.map +1 -0
  215. package/dist/vector.d.ts +26 -0
  216. package/dist/vector.d.ts.map +1 -0
  217. package/dist/vector.js +48 -0
  218. package/dist/vector.js.map +1 -0
  219. package/package.json +86 -0
  220. package/proto/camus_sql.proto +566 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-set.js","sourceRoot":"","sources":["../src/result-set.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ /**
8
+ * True when running the same work again may succeed.
9
+ *
10
+ * `CADB0509` is deliberately **not** retryable here. It says a commit or rollback outcome is not
11
+ * resolved yet, which means the transaction may already be durable — replaying the work from
12
+ * `BEGIN` could apply it twice. The driver resolves that code by re-issuing the same finalize on
13
+ * the same handle, which `CamusTransaction` does on its own.
14
+ */
15
+ export declare function isRetryable(error: unknown): boolean;
16
+ /** How a retry loop behaves. */
17
+ export interface RetryOptions {
18
+ /** How many times the work runs in total, the first attempt included. Default 5. */
19
+ readonly maxAttempts?: number;
20
+ /** Ends the loop between attempts. */
21
+ readonly signal?: AbortSignal;
22
+ }
23
+ /**
24
+ * Runs `operation` and retries it while it fails with a retryable error.
25
+ *
26
+ * Use it around a unit of work that is safe to run twice — a single autocommit statement, or a
27
+ * whole transaction from `BEGIN` to `COMMIT`. Do not use it around a commit alone: a commit whose
28
+ * outcome is unknown must not be replayed from the start.
29
+ *
30
+ * The delay grows exponentially from 20 ms, caps at 400 ms, and carries 25% jitter, so a set of
31
+ * clients that conflicted do not retry in step.
32
+ */
33
+ export declare function withRetry<T>(operation: (attempt: number) => Promise<T>, options?: RetryOptions): Promise<T>;
34
+ /** The back-off for one attempt, in milliseconds. Exported so a caller can mirror the schedule. */
35
+ export declare function computeDelayMs(attempt: number): number;
36
+ /** A cancellable sleep. Rejects with the signal's reason when the signal ends the wait. */
37
+ export declare function delay(milliseconds: number, signal?: AbortSignal): Promise<void>;
38
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAanD;AAED,gCAAgC;AAChC,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B,sCAAsC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAYZ;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED,2FAA2F;AAC3F,wBAAgB,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB/E"}
package/dist/retry.js ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ import { CamusError } from './errors.js';
8
+ import { CamusErrorCode } from './error-codes.js';
9
+ /**
10
+ * Which failures a caller may retry, and a loop that does it.
11
+ *
12
+ * A serializable transaction can lose a conflict and be aborted. The abort is not a bug and it is
13
+ * not a lasting condition: the same work, run again, usually commits. This module holds the one
14
+ * classification of "run it again" the whole driver uses, so a retry loop a caller writes and the
15
+ * loops inside the driver agree on what is retryable.
16
+ */
17
+ /** The server codes that name a lost conflict or a transient internal condition. */
18
+ const RETRYABLE_CODES = new Set(['CADB0502', 'CADB0504', 'CADB0505']);
19
+ /**
20
+ * Message fragments that name the same conditions on a server that reported them without a
21
+ * dedicated code. A message test is coarse, but the alternative is failing a transaction that
22
+ * would have committed on its second attempt.
23
+ */
24
+ const RETRYABLE_MESSAGE_MARKERS = ['MustRetry', 'AlreadyLocked', 'commit returned Aborted'];
25
+ /**
26
+ * True when running the same work again may succeed.
27
+ *
28
+ * `CADB0509` is deliberately **not** retryable here. It says a commit or rollback outcome is not
29
+ * resolved yet, which means the transaction may already be durable — replaying the work from
30
+ * `BEGIN` could apply it twice. The driver resolves that code by re-issuing the same finalize on
31
+ * the same handle, which `CamusTransaction` does on its own.
32
+ */
33
+ export function isRetryable(error) {
34
+ for (let current = error; current != null; current = current.cause) {
35
+ if (!CamusError.is(current))
36
+ continue;
37
+ if (current.code === CamusErrorCode.FinalizeUnresolved)
38
+ return false;
39
+ if (RETRYABLE_CODES.has(current.code))
40
+ return true;
41
+ for (const marker of RETRYABLE_MESSAGE_MARKERS) {
42
+ if (current.message.includes(marker))
43
+ return true;
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+ /**
49
+ * Runs `operation` and retries it while it fails with a retryable error.
50
+ *
51
+ * Use it around a unit of work that is safe to run twice — a single autocommit statement, or a
52
+ * whole transaction from `BEGIN` to `COMMIT`. Do not use it around a commit alone: a commit whose
53
+ * outcome is unknown must not be replayed from the start.
54
+ *
55
+ * The delay grows exponentially from 20 ms, caps at 400 ms, and carries 25% jitter, so a set of
56
+ * clients that conflicted do not retry in step.
57
+ */
58
+ export async function withRetry(operation, options = {}) {
59
+ const maxAttempts = Math.max(1, options.maxAttempts ?? 5);
60
+ for (let attempt = 1;; attempt++) {
61
+ try {
62
+ return await operation(attempt);
63
+ }
64
+ catch (error) {
65
+ if (attempt >= maxAttempts || !isRetryable(error))
66
+ throw error;
67
+ await delay(computeDelayMs(attempt), options.signal);
68
+ }
69
+ }
70
+ }
71
+ /** The back-off for one attempt, in milliseconds. Exported so a caller can mirror the schedule. */
72
+ export function computeDelayMs(attempt) {
73
+ const base = Math.min(20 * 2 ** attempt, 400);
74
+ const jitter = base * 0.25 * (2 * Math.random() - 1);
75
+ return Math.max(1, base + jitter);
76
+ }
77
+ /** A cancellable sleep. Rejects with the signal's reason when the signal ends the wait. */
78
+ export function delay(milliseconds, signal) {
79
+ if (signal?.aborted === true)
80
+ return Promise.reject(signal.reason);
81
+ return new Promise((resolve, reject) => {
82
+ const timer = setTimeout(() => {
83
+ signal?.removeEventListener('abort', onAbort);
84
+ resolve();
85
+ }, milliseconds);
86
+ function onAbort() {
87
+ clearTimeout(timer);
88
+ reject(signal.reason);
89
+ }
90
+ signal?.addEventListener('abort', onAbort, { once: true });
91
+ });
92
+ }
93
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ /** Whether routing advice asks the client to remember a destination or to forget one. */
8
+ export declare const CamusRoutingDisposition: {
9
+ /** A disposition this driver does not know. The advice is ignored. */
10
+ readonly Unknown: "unknown";
11
+ /** Remember the advertised node for future executions of this statement. */
12
+ readonly Prefer: "prefer";
13
+ /** Forget any destination learned for this statement. */
14
+ readonly Clear: "clear";
15
+ };
16
+ export type CamusRoutingDisposition = (typeof CamusRoutingDisposition)[keyof typeof CamusRoutingDisposition];
17
+ /** The only routing metadata version this driver accepts. */
18
+ export declare const ROUTING_ACCEPT_VERSION = 1;
19
+ /**
20
+ * Advisory routing metadata attached to a successful statement response.
21
+ *
22
+ * It is a performance hint, never an instruction: the statement that carried it already ran
23
+ * normally, and a client that ignores it loses nothing but a network hop. It never carries SQL
24
+ * literals, row values, encoded keys, credentials, or a cluster map.
25
+ *
26
+ * `preferredNodeId` is an opaque node identity, not an address to dial. It becomes a destination
27
+ * only through the client's configured `routingNodes` trust map.
28
+ */
29
+ export interface CamusRoutingAdvice {
30
+ /** The metadata contract version. Advice of any other version is ignored. */
31
+ readonly version: number;
32
+ readonly disposition: CamusRoutingDisposition;
33
+ /** The opaque node identity to prefer. */
34
+ readonly preferredNodeId?: string | undefined;
35
+ /**
36
+ * True when the destination holds across different parameter values for this statement. A
37
+ * narrower scope is not reusable, so the advice is ignored.
38
+ */
39
+ readonly parametersIndependentScope: boolean;
40
+ /**
41
+ * An opaque change detector over the statement's resolved physical dependencies. It changes when
42
+ * the dependency set changes: a schema change, a TRUNCATE, a view refresh, a recreated database.
43
+ * It is not sortable and it is not authentication.
44
+ */
45
+ readonly dependencyToken?: string | undefined;
46
+ /** The longest period the route may be reused, in milliseconds, measured from receipt. */
47
+ readonly maxAgeMs: number;
48
+ /** Why the server chose this disposition. Diagnostic only. */
49
+ readonly reason?: string | undefined;
50
+ }
51
+ /** Builds the public object from decoded parts, whichever transport decoded them. */
52
+ export declare function makeRoutingAdvice(parts: {
53
+ version: number;
54
+ disposition: string | undefined;
55
+ preferredNodeId: string | undefined;
56
+ reuseScope: string | undefined;
57
+ dependencyToken: string | undefined;
58
+ maxAgeMs: number;
59
+ reason: string | undefined;
60
+ }): CamusRoutingAdvice;
61
+ /** Reads advice out of a REST response body, or reports `undefined` when the body carried none. */
62
+ export declare function routingAdviceFromJson(body: unknown): CamusRoutingAdvice | undefined;
63
+ //# sourceMappingURL=advice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advice.d.ts","sourceRoot":"","sources":["../../src/routing/advice.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yFAAyF;AACzF,eAAO,MAAM,uBAAuB;IAClC,sEAAsE;;IAEtE,4EAA4E;;IAE5E,yDAAyD;;CAEjD,CAAC;AAEX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAC;AAE7G,6DAA6D;AAC7D,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,QAAQ,CAAC,WAAW,EAAE,uBAAuB,CAAC;IAE9C,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE9C;;;OAGG;IACH,QAAQ,CAAC,0BAA0B,EAAE,OAAO,CAAC;IAE7C;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE9C,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,qFAAqF;AACrF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,GAAG,kBAAkB,CAUrB;AAaD,mGAAmG;AACnG,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CAiBnF"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ /** Whether routing advice asks the client to remember a destination or to forget one. */
8
+ export const CamusRoutingDisposition = {
9
+ /** A disposition this driver does not know. The advice is ignored. */
10
+ Unknown: 'unknown',
11
+ /** Remember the advertised node for future executions of this statement. */
12
+ Prefer: 'prefer',
13
+ /** Forget any destination learned for this statement. */
14
+ Clear: 'clear',
15
+ };
16
+ /** The only routing metadata version this driver accepts. */
17
+ export const ROUTING_ACCEPT_VERSION = 1;
18
+ /** Builds the public object from decoded parts, whichever transport decoded them. */
19
+ export function makeRoutingAdvice(parts) {
20
+ return {
21
+ version: parts.version,
22
+ disposition: parseDisposition(parts.disposition),
23
+ preferredNodeId: parts.preferredNodeId,
24
+ parametersIndependentScope: parts.reuseScope === 'statementParametersIndependent',
25
+ dependencyToken: parts.dependencyToken,
26
+ maxAgeMs: parts.maxAgeMs,
27
+ reason: parts.reason,
28
+ };
29
+ }
30
+ function parseDisposition(disposition) {
31
+ switch (disposition) {
32
+ case 'prefer':
33
+ return CamusRoutingDisposition.Prefer;
34
+ case 'clear':
35
+ return CamusRoutingDisposition.Clear;
36
+ default:
37
+ return CamusRoutingDisposition.Unknown;
38
+ }
39
+ }
40
+ /** Reads advice out of a REST response body, or reports `undefined` when the body carried none. */
41
+ export function routingAdviceFromJson(body) {
42
+ if (typeof body !== 'object' || body === null)
43
+ return undefined;
44
+ const routing = body.routing;
45
+ if (typeof routing !== 'object' || routing === null)
46
+ return undefined;
47
+ const record = routing;
48
+ return makeRoutingAdvice({
49
+ version: typeof record.version === 'number' ? record.version : 0,
50
+ disposition: readString(record.disposition),
51
+ preferredNodeId: readString(record.preferredNodeId),
52
+ reuseScope: readString(record.reuseScope),
53
+ dependencyToken: readString(record.dependencyToken),
54
+ maxAgeMs: typeof record.maxAgeMs === 'number' ? record.maxAgeMs : 0,
55
+ reason: readString(record.reason),
56
+ });
57
+ }
58
+ function readString(value) {
59
+ return typeof value === 'string' ? value : undefined;
60
+ }
61
+ //# sourceMappingURL=advice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advice.js","sourceRoot":"","sources":["../../src/routing/advice.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,yFAAyF;AACzF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,sEAAsE;IACtE,OAAO,EAAE,SAAS;IAClB,4EAA4E;IAC5E,MAAM,EAAE,QAAQ;IAChB,yDAAyD;IACzD,KAAK,EAAE,OAAO;CACN,CAAC;AAIX,6DAA6D;AAC7D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAyCxC,qFAAqF;AACrF,MAAM,UAAU,iBAAiB,CAAC,KAQjC;IACC,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,WAAW,CAAC;QAChD,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,0BAA0B,EAAE,KAAK,CAAC,UAAU,KAAK,gCAAgC;QACjF,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,WAA+B;IACvD,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,uBAAuB,CAAC,MAAM,CAAC;QACxC,KAAK,OAAO;YACV,OAAO,uBAAuB,CAAC,KAAK,CAAC;QACvC;YACE,OAAO,uBAAuB,CAAC,OAAO,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,qBAAqB,CAAC,IAAa;IACjD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAEhE,MAAM,OAAO,GAAI,IAA8B,CAAC,OAAO,CAAC;IACxD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAEtE,MAAM,MAAM,GAAG,OAAkC,CAAC;IAElD,OAAO,iBAAiB,CAAC;QACvB,OAAO,EAAE,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAChE,WAAW,EAAE,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC;QAC3C,eAAe,EAAE,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC;QACnD,UAAU,EAAE,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC;QACzC,eAAe,EAAE,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC;QACnD,QAAQ,EAAE,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;KAClC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ /** Whether a statement was a query or a write. A route is learned per kind. */
8
+ export declare const CamusRouteOpKind: {
9
+ readonly Query: 0;
10
+ readonly NonQuery: 1;
11
+ };
12
+ export type CamusRouteOpKind = (typeof CamusRouteOpKind)[keyof typeof CamusRouteOpKind];
13
+ /**
14
+ * The bounded cache of destinations learned for statements.
15
+ *
16
+ * Each entry is keyed by database, exact SQL text, and statement kind, and holds a node identity
17
+ * with an expiry measured on a monotonic clock. Two properties matter beyond ordinary caching:
18
+ *
19
+ * - A late reply cannot overwrite a newer route. Every read reports the entry's revision, and a
20
+ * write applies only when the revision it observed is still the current one. Two replies for the
21
+ * same statement can arrive out of order, and the older one must not win.
22
+ * - The cache is bounded twice, by entry count and by retained bytes. SQL text is unbounded in
23
+ * length, so a count alone does not bound memory.
24
+ */
25
+ export declare class CamusStatementRouteCache {
26
+ private readonly entries;
27
+ private readonly maxEntries;
28
+ private readonly maxBytes;
29
+ private retainedBytes;
30
+ private revisionSeq;
31
+ constructor(maxEntries: number, maxBytes: number);
32
+ get size(): number;
33
+ /**
34
+ * The node identity learned for a statement, and the revision that read observed. A miss, an
35
+ * expired entry, and an entry that was never written all report `undefined` with revision 0.
36
+ */
37
+ tryGet(key: string, now: number): {
38
+ nodeId: string | undefined;
39
+ revision: number;
40
+ };
41
+ /**
42
+ * Records a destination, but only when the caller's observed revision still matches. A first
43
+ * write must observe revision 0, which is what a read of an absent entry reports.
44
+ */
45
+ learn(key: string, keyBytes: number, nodeId: string, dependencyToken: string | undefined, expiresAt: number, observedRevision: number, now: number): void;
46
+ /** Forgets a destination, but only when the caller's observed revision still matches. */
47
+ clear(key: string, observedRevision: number): void;
48
+ private remove;
49
+ private evict;
50
+ }
51
+ /** The cache key for one statement. The separator cannot appear in a kind or a database name. */
52
+ export declare function routeKey(database: string, sql: string, kind: CamusRouteOpKind): string;
53
+ //# sourceMappingURL=route-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-cache.d.ts","sourceRoot":"","sources":["../../src/routing/route-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAWxF;;;;;;;;;;;GAWG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IAEpD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAElC,OAAO,CAAC,aAAa,CAAK;IAE1B,OAAO,CAAC,WAAW,CAAK;gBAEZ,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAKhD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAclF;;;OAGG;IACH,KAAK,CACH,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EACxB,GAAG,EAAE,MAAM,GACV,IAAI;IA6BP,yFAAyF;IACzF,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAMlD,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,KAAK;CA2Bd;AAED,iGAAiG;AACjG,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAEtF"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ /** Whether a statement was a query or a write. A route is learned per kind. */
8
+ export const CamusRouteOpKind = {
9
+ Query: 0,
10
+ NonQuery: 1,
11
+ };
12
+ /**
13
+ * The bounded cache of destinations learned for statements.
14
+ *
15
+ * Each entry is keyed by database, exact SQL text, and statement kind, and holds a node identity
16
+ * with an expiry measured on a monotonic clock. Two properties matter beyond ordinary caching:
17
+ *
18
+ * - A late reply cannot overwrite a newer route. Every read reports the entry's revision, and a
19
+ * write applies only when the revision it observed is still the current one. Two replies for the
20
+ * same statement can arrive out of order, and the older one must not win.
21
+ * - The cache is bounded twice, by entry count and by retained bytes. SQL text is unbounded in
22
+ * length, so a count alone does not bound memory.
23
+ */
24
+ export class CamusStatementRouteCache {
25
+ entries = new Map();
26
+ maxEntries;
27
+ maxBytes;
28
+ retainedBytes = 0;
29
+ revisionSeq = 0;
30
+ constructor(maxEntries, maxBytes) {
31
+ this.maxEntries = Math.max(1, maxEntries);
32
+ this.maxBytes = Math.max(1, maxBytes);
33
+ }
34
+ get size() {
35
+ return this.entries.size;
36
+ }
37
+ /**
38
+ * The node identity learned for a statement, and the revision that read observed. A miss, an
39
+ * expired entry, and an entry that was never written all report `undefined` with revision 0.
40
+ */
41
+ tryGet(key, now) {
42
+ const entry = this.entries.get(key);
43
+ if (entry === undefined)
44
+ return { nodeId: undefined, revision: 0 };
45
+ if (now >= entry.expiresAt) {
46
+ this.remove(key, entry);
47
+ return { nodeId: undefined, revision: 0 };
48
+ }
49
+ entry.lastTouched = now;
50
+ return { nodeId: entry.nodeId, revision: entry.revision };
51
+ }
52
+ /**
53
+ * Records a destination, but only when the caller's observed revision still matches. A first
54
+ * write must observe revision 0, which is what a read of an absent entry reports.
55
+ */
56
+ learn(key, keyBytes, nodeId, dependencyToken, expiresAt, observedRevision, now) {
57
+ const existing = this.entries.get(key);
58
+ if (existing !== undefined && existing.revision !== observedRevision)
59
+ return;
60
+ if (existing === undefined && observedRevision !== 0)
61
+ return;
62
+ const entry = existing ?? {
63
+ nodeId,
64
+ dependencyToken,
65
+ expiresAt,
66
+ revision: 0,
67
+ lastTouched: now,
68
+ bytes: 0,
69
+ };
70
+ if (existing !== undefined)
71
+ this.retainedBytes -= existing.bytes;
72
+ else
73
+ this.entries.set(key, entry);
74
+ entry.nodeId = nodeId;
75
+ entry.dependencyToken = dependencyToken;
76
+ entry.expiresAt = expiresAt;
77
+ entry.revision = ++this.revisionSeq;
78
+ entry.lastTouched = now;
79
+ entry.bytes = keyBytes + (nodeId.length + (dependencyToken?.length ?? 0)) * 2 + 64;
80
+ this.retainedBytes += entry.bytes;
81
+ this.evict(now);
82
+ }
83
+ /** Forgets a destination, but only when the caller's observed revision still matches. */
84
+ clear(key, observedRevision) {
85
+ const entry = this.entries.get(key);
86
+ if (entry !== undefined && entry.revision === observedRevision)
87
+ this.remove(key, entry);
88
+ }
89
+ remove(key, entry) {
90
+ this.entries.delete(key);
91
+ this.retainedBytes -= entry.bytes;
92
+ }
93
+ evict(now) {
94
+ if (this.entries.size <= this.maxEntries && this.retainedBytes <= this.maxBytes)
95
+ return;
96
+ // Expired entries first: they are free to drop and cost a live route nothing.
97
+ for (const [key, entry] of this.entries) {
98
+ if (now >= entry.expiresAt)
99
+ this.remove(key, entry);
100
+ }
101
+ while (this.entries.size > this.maxEntries || this.retainedBytes > this.maxBytes) {
102
+ let victimKey;
103
+ let oldest = Number.POSITIVE_INFINITY;
104
+ for (const [key, entry] of this.entries) {
105
+ if (entry.lastTouched < oldest) {
106
+ oldest = entry.lastTouched;
107
+ victimKey = key;
108
+ }
109
+ }
110
+ if (victimKey === undefined)
111
+ return;
112
+ const victim = this.entries.get(victimKey);
113
+ if (victim === undefined)
114
+ return;
115
+ this.remove(victimKey, victim);
116
+ }
117
+ }
118
+ }
119
+ /** The cache key for one statement. The separator cannot appear in a kind or a database name. */
120
+ export function routeKey(database, sql, kind) {
121
+ return `${String(kind)} ${database} ${sql}`;
122
+ }
123
+ //# sourceMappingURL=route-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-cache.js","sourceRoot":"","sources":["../../src/routing/route-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ import type { CamusEndpointPool } from '../endpoint-pool.js';
8
+ import type { CamusRoutingAdvice } from './advice.js';
9
+ import type { CamusRouteOpKind } from './route-cache.js';
10
+ /**
11
+ * Learned statement routing for one deployment: the operator-configured trust map from server node
12
+ * identities to endpoint pool members, plus the bounded cache of learned routes.
13
+ *
14
+ * The trust map is the routing authority. Advice names an opaque node identity; it becomes a
15
+ * destination only through this map, and only when the mapped address is a member of the endpoint
16
+ * pool. So a response can never steer traffic, or credentials, anywhere the operator did not list,
17
+ * and every routable address already passed the same validation the pool applies.
18
+ *
19
+ * A router is shared per deployment and routing configuration, for the same reason the endpoint
20
+ * pool is: an application that builds a client per request would otherwise start cold every time
21
+ * and never learn anything.
22
+ */
23
+ export declare class CamusStatementRouter {
24
+ private static readonly shared;
25
+ private static readonly MAX_ENTRIES;
26
+ private static readonly MAX_BYTES;
27
+ /** The process-wide router for a deployment-and-configuration key. */
28
+ static forKey(key: string, factory: () => CamusStatementRouter): CamusStatementRouter;
29
+ /** @internal Test hook: drops every shared router. */
30
+ static resetShared(): void;
31
+ private readonly routes;
32
+ private readonly nodeAddresses;
33
+ private readonly pool;
34
+ private readonly maxHintAgeMs;
35
+ /** @internal Test hook: the monotonic clock this router reads. */
36
+ clock: () => number;
37
+ constructor(nodeAddresses: ReadonlyMap<string, string>, pool: CamusEndpointPool, maxHintAgeMs: number);
38
+ /** How many destinations are currently learned. Diagnostic. */
39
+ get learnedRouteCount(): number;
40
+ /**
41
+ * The endpoint to prefer for a statement, or `undefined` to fall back to the pool's rotation.
42
+ *
43
+ * The returned `revision` must be handed back to `learn` for the same statement, so a reply that
44
+ * arrives late cannot overwrite a route a faster reply already refreshed.
45
+ */
46
+ selectEndpoint(database: string, sql: string, kind: CamusRouteOpKind): {
47
+ endpoint: string | undefined;
48
+ revision: number;
49
+ };
50
+ /** Applies the advice a statement's reply carried. Unusable advice is dropped, never an error. */
51
+ learn(database: string, sql: string, kind: CamusRouteOpKind, advice: CamusRoutingAdvice | undefined, observedRevision: number): void;
52
+ }
53
+ //# sourceMappingURL=router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/routing/router.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAA8C;IAE5E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAQ;IAE3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAmB;IAEpD,sEAAsE;IACtE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAAoB,GAAG,oBAAoB;IAIrF,sDAAsD;IACtD,MAAM,CAAC,WAAW,IAAI,IAAI;IAI1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAGrB;IAEF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAE5D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IAEzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,kEAAkE;IAClE,KAAK,EAAE,MAAM,MAAM,CAA2B;gBAElC,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM;IAMrG,+DAA+D;IAC/D,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED;;;;;OAKG;IACH,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,gBAAgB,GACrB;QAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAerD,kGAAkG;IAClG,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,gBAAgB,EAAE,MAAM,GACvB,IAAI;CAiCR"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ import { SharedRegistry } from '../shared-registry.js';
8
+ import { CamusRoutingDisposition, ROUTING_ACCEPT_VERSION } from './advice.js';
9
+ import { CamusStatementRouteCache, routeKey } from './route-cache.js';
10
+ /**
11
+ * Learned statement routing for one deployment: the operator-configured trust map from server node
12
+ * identities to endpoint pool members, plus the bounded cache of learned routes.
13
+ *
14
+ * The trust map is the routing authority. Advice names an opaque node identity; it becomes a
15
+ * destination only through this map, and only when the mapped address is a member of the endpoint
16
+ * pool. So a response can never steer traffic, or credentials, anywhere the operator did not list,
17
+ * and every routable address already passed the same validation the pool applies.
18
+ *
19
+ * A router is shared per deployment and routing configuration, for the same reason the endpoint
20
+ * pool is: an application that builds a client per request would otherwise start cold every time
21
+ * and never learn anything.
22
+ */
23
+ export class CamusStatementRouter {
24
+ static shared = new SharedRegistry();
25
+ static MAX_ENTRIES = 4096;
26
+ static MAX_BYTES = 4 * 1024 * 1024;
27
+ /** The process-wide router for a deployment-and-configuration key. */
28
+ static forKey(key, factory) {
29
+ return CamusStatementRouter.shared.get(key, factory);
30
+ }
31
+ /** @internal Test hook: drops every shared router. */
32
+ static resetShared() {
33
+ CamusStatementRouter.shared.clear();
34
+ }
35
+ routes = new CamusStatementRouteCache(CamusStatementRouter.MAX_ENTRIES, CamusStatementRouter.MAX_BYTES);
36
+ nodeAddresses;
37
+ pool;
38
+ maxHintAgeMs;
39
+ /** @internal Test hook: the monotonic clock this router reads. */
40
+ clock = () => performance.now();
41
+ constructor(nodeAddresses, pool, maxHintAgeMs) {
42
+ this.nodeAddresses = nodeAddresses;
43
+ this.pool = pool;
44
+ this.maxHintAgeMs = Math.max(1, maxHintAgeMs);
45
+ }
46
+ /** How many destinations are currently learned. Diagnostic. */
47
+ get learnedRouteCount() {
48
+ return this.routes.size;
49
+ }
50
+ /**
51
+ * The endpoint to prefer for a statement, or `undefined` to fall back to the pool's rotation.
52
+ *
53
+ * The returned `revision` must be handed back to `learn` for the same statement, so a reply that
54
+ * arrives late cannot overwrite a route a faster reply already refreshed.
55
+ */
56
+ selectEndpoint(database, sql, kind) {
57
+ const key = routeKey(database, sql, kind);
58
+ const { nodeId, revision } = this.routes.tryGet(key, this.clock());
59
+ if (nodeId === undefined)
60
+ return { endpoint: undefined, revision };
61
+ const address = this.nodeAddresses.get(nodeId);
62
+ if (address === undefined)
63
+ return { endpoint: undefined, revision };
64
+ // A route pointing at a node that stopped answering falls back to rotation rather than
65
+ // steering traffic at it.
66
+ return { endpoint: this.pool.isQuarantined(address) ? undefined : address, revision };
67
+ }
68
+ /** Applies the advice a statement's reply carried. Unusable advice is dropped, never an error. */
69
+ learn(database, sql, kind, advice, observedRevision) {
70
+ if (advice === undefined || advice.version !== ROUTING_ACCEPT_VERSION)
71
+ return;
72
+ const key = routeKey(database, sql, kind);
73
+ if (advice.disposition === CamusRoutingDisposition.Clear) {
74
+ this.routes.clear(key, observedRevision);
75
+ return;
76
+ }
77
+ if (advice.disposition !== CamusRoutingDisposition.Prefer ||
78
+ !advice.parametersIndependentScope ||
79
+ advice.preferredNodeId === undefined ||
80
+ advice.maxAgeMs <= 0 ||
81
+ !this.nodeAddresses.has(advice.preferredNodeId)) {
82
+ return;
83
+ }
84
+ const now = this.clock();
85
+ const ttl = Math.min(advice.maxAgeMs, this.maxHintAgeMs);
86
+ this.routes.learn(key, (database.length + sql.length) * 2, advice.preferredNodeId, advice.dependencyToken, now + ttl, observedRevision, now);
87
+ }
88
+ }
89
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/routing/router.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE9E,OAAO,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEtE;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,oBAAoB;IACvB,MAAM,CAAU,MAAM,GAAG,IAAI,cAAc,EAAwB,CAAC;IAEpE,MAAM,CAAU,WAAW,GAAG,IAAI,CAAC;IAEnC,MAAM,CAAU,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAEpD,sEAAsE;IACtE,MAAM,CAAC,MAAM,CAAC,GAAW,EAAE,OAAmC;QAC5D,OAAO,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;IAED,sDAAsD;IACtD,MAAM,CAAC,WAAW;QAChB,oBAAoB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtC,CAAC;IAEgB,MAAM,GAAG,IAAI,wBAAwB,CACpD,oBAAoB,CAAC,WAAW,EAChC,oBAAoB,CAAC,SAAS,CAC/B,CAAC;IAEe,aAAa,CAA8B;IAE3C,IAAI,CAAoB;IAExB,YAAY,CAAS;IAEtC,kEAAkE;IAClE,KAAK,GAAiB,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;IAE9C,YAAY,aAA0C,EAAE,IAAuB,EAAE,YAAoB;QACnG,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;IAED,+DAA+D;IAC/D,IAAI,iBAAiB;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACH,cAAc,CACZ,QAAgB,EAChB,GAAW,EACX,IAAsB;QAEtB,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAEnE,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QAEnE,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QAEpE,uFAAuF;QACvF,0BAA0B;QAC1B,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;IACxF,CAAC;IAED,kGAAkG;IAClG,KAAK,CACH,QAAgB,EAChB,GAAW,EACX,IAAsB,EACtB,MAAsC,EACtC,gBAAwB;QAExB,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,KAAK,sBAAsB;YAAE,OAAO;QAE9E,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QAE1C,IAAI,MAAM,CAAC,WAAW,KAAK,uBAAuB,CAAC,KAAK,EAAE,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IACE,MAAM,CAAC,WAAW,KAAK,uBAAuB,CAAC,MAAM;YACrD,CAAC,MAAM,CAAC,0BAA0B;YAClC,MAAM,CAAC,eAAe,KAAK,SAAS;YACpC,MAAM,CAAC,QAAQ,IAAI,CAAC;YACpB,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,EAC/C,CAAC;YACD,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAEzD,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,GAAG,EACH,CAAC,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAClC,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,eAAe,EACtB,GAAG,GAAG,GAAG,EACT,gBAAgB,EAChB,GAAG,CACJ,CAAC;IACJ,CAAC"}