terrascale 0.3.0 → 1.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.
- package/CHANGELOG.md +47 -0
- package/README.md +169 -115
- package/package.json +11 -16
- package/sdk-v1-route-manifest.json +2330 -0
- package/src/database-view.js +2 -1
- package/src/database.js +2 -420
- package/src/index.js +58 -75
- package/src/local/index.js +5 -3
- package/src/local/legacy-client.js +411 -0
- package/src/postgres.js +3 -1
- package/src/tanstack/index.js +2 -1
- package/src/v1/decode.js +110 -0
- package/src/v1/errors.js +185 -0
- package/src/v1/filter.js +230 -0
- package/src/v1/ids.js +118 -0
- package/src/v1/json.js +335 -0
- package/src/v1/routes.js +57 -0
- package/src/v1/shapes.js +145 -0
- package/src/v1/terrabase-v1.js +722 -0
- package/src/v1/transport.js +324 -0
- package/types/database-view.d.ts +3 -2
- package/types/database.d.ts +2 -98
- package/types/index.d.ts +42 -51
- package/types/local/index.d.ts +6 -4
- package/types/local/legacy-client.d.ts +94 -0
- package/types/local/test-environment.d.ts +1 -1
- package/types/postgres.d.ts +1 -0
- package/types/tanstack/index.d.ts +3 -2
- package/types/v1/decode.d.ts +105 -0
- package/types/v1/errors.d.ts +107 -0
- package/types/v1/filter.d.ts +148 -0
- package/types/v1/ids.d.ts +44 -0
- package/types/v1/json.d.ts +92 -0
- package/types/v1/routes.d.ts +26 -0
- package/types/v1/shapes.d.ts +78 -0
- package/types/v1/terrabase-v1.d.ts +374 -0
- package/types/v1/transport.d.ts +117 -0
- package/sdk-current-contract.json +0 -27
- package/sdk-route-manifest.json +0 -67
- package/src/discovery.js +0 -374
- package/types/discovery.d.ts +0 -114
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
// Internal typed transport for the TerraBase v1 client. It is not exported
|
|
2
|
+
// from any package entrypoint: callers reach it only through named operations.
|
|
3
|
+
import { parseV1Error } from "./errors.js";
|
|
4
|
+
import { requireName, requireProject } from "./ids.js";
|
|
5
|
+
import { parseExactJson } from "./json.js";
|
|
6
|
+
import { v1Route, v1RoutePath } from "./routes.js";
|
|
7
|
+
/**
|
|
8
|
+
* @import { FetchLike } from "../config.js"
|
|
9
|
+
* @import { TerraBaseV1Error } from "./errors.js"
|
|
10
|
+
* @import { JsonValue } from "./json.js"
|
|
11
|
+
* @import { V1Operation } from "./routes.js"
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Server request body limit (api-v1.md). */
|
|
15
|
+
export const maximumRequestBytes = 4 * 1024 * 1024;
|
|
16
|
+
// Query budgets count stored JSON before wrappers and serializer escaping.
|
|
17
|
+
const defaultMaximumResponseBytes = 64 * 1024 * 1024;
|
|
18
|
+
const tokenPattern = /^tb_[A-Za-z0-9_-]{43}$/u;
|
|
19
|
+
/**
|
|
20
|
+
* Resolver input contains no credential. A successful URL is cached for this client/database.
|
|
21
|
+
* @typedef {{ readonly project: string; readonly database: string; readonly signal?: AbortSignal | undefined }} V1EndpointContext
|
|
22
|
+
*/
|
|
23
|
+
/** @typedef {(context: V1EndpointContext) => string | Promise<string>} V1EndpointResolver */
|
|
24
|
+
/**
|
|
25
|
+
* Project-scoped C# Documents API client. Supply exactly one of baseUrl or endpointResolver.
|
|
26
|
+
* URLs must use HTTPS or loopback HTTP. Mutations are never automatically replayed.
|
|
27
|
+
* @typedef {object} TerraBaseV1ClientConfig
|
|
28
|
+
* @property {string} project
|
|
29
|
+
* @property {string} token A tb_ API key; held privately.
|
|
30
|
+
* @property {string | undefined} [baseUrl]
|
|
31
|
+
* @property {V1EndpointResolver | undefined} [endpointResolver]
|
|
32
|
+
* @property {FetchLike | undefined} [fetch]
|
|
33
|
+
* @property {number | undefined} [maxResponseBytes] Default 64 MiB, including query framing and escaping.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {object} V1CallOptions
|
|
38
|
+
* @property {string} [body]
|
|
39
|
+
* @property {string} [contentType]
|
|
40
|
+
* @property {Readonly<Record<string, string>>} [headers] Contract headers only (If-Match, If-None-Match).
|
|
41
|
+
* @property {URLSearchParams | undefined} [query]
|
|
42
|
+
* @property {AbortSignal | undefined} [signal]
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {object} V1CallResult
|
|
47
|
+
* @property {number} status
|
|
48
|
+
* @property {Headers} headers
|
|
49
|
+
* @property {JsonValue | undefined} value
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {string} host
|
|
54
|
+
* @returns {boolean}
|
|
55
|
+
*/
|
|
56
|
+
function isLoopbackHost(host) {
|
|
57
|
+
const name = host.toLowerCase();
|
|
58
|
+
return (
|
|
59
|
+
name === "localhost" ||
|
|
60
|
+
name.endsWith(".localhost") ||
|
|
61
|
+
name === "[::1]" ||
|
|
62
|
+
isLoopbackIpv4(name)
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A dotted-decimal address in 127.0.0.0/8 with every octet at most 255. An
|
|
68
|
+
* out-of-range octet would make the URL parser treat the host as a DNS name.
|
|
69
|
+
* @param {string} name
|
|
70
|
+
* @returns {boolean}
|
|
71
|
+
*/
|
|
72
|
+
function isLoopbackIpv4(name) {
|
|
73
|
+
const octets = /^127\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/u.exec(name);
|
|
74
|
+
return octets !== null && octets.slice(1).every((octet) => Number(octet) <= 255);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @param {string} raw
|
|
79
|
+
* @param {string} what
|
|
80
|
+
* @returns {URL}
|
|
81
|
+
*/
|
|
82
|
+
export function requireServiceUrl(raw, what) {
|
|
83
|
+
/** @type {URL} */
|
|
84
|
+
let url;
|
|
85
|
+
if (typeof raw !== "string") throw new TypeError(`${what} must be an absolute URL.`);
|
|
86
|
+
try {
|
|
87
|
+
url = new URL(raw);
|
|
88
|
+
} catch {
|
|
89
|
+
throw new TypeError(`${what} must be an absolute URL.`);
|
|
90
|
+
}
|
|
91
|
+
if (url.username !== "" || url.password !== "" || url.hash !== "")
|
|
92
|
+
throw new TypeError(`${what} must not carry credentials or a fragment.`);
|
|
93
|
+
if (
|
|
94
|
+
url.protocol !== "https:" &&
|
|
95
|
+
!(url.protocol === "http:" && isLoopbackHost(url.hostname))
|
|
96
|
+
)
|
|
97
|
+
throw new TypeError(`${what} must use HTTPS; plain HTTP is allowed only for loopback hosts.`);
|
|
98
|
+
return url;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* An explicitly configured endpoint, with no discovery or hardcoded hosts.
|
|
103
|
+
* @param {string} baseUrl
|
|
104
|
+
* @returns {V1EndpointResolver}
|
|
105
|
+
*/
|
|
106
|
+
export function staticBaseUrlResolver(baseUrl) {
|
|
107
|
+
const base = canonicalBaseUrl(baseUrl);
|
|
108
|
+
return () => base;
|
|
109
|
+
}
|
|
110
|
+
/** @param {string} raw @returns {string} */
|
|
111
|
+
function canonicalBaseUrl(raw) {
|
|
112
|
+
const url = requireServiceUrl(raw, "baseUrl");
|
|
113
|
+
if (url.search !== "") throw new TypeError("baseUrl must not carry a query.");
|
|
114
|
+
return `${url.origin}${url.pathname.replace(/\/+$/u, "")}`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** A response body that failed in transit after its headers arrived. */
|
|
118
|
+
export class BodyTransportError extends Error {
|
|
119
|
+
/** @param {unknown} cause */
|
|
120
|
+
constructor(cause) {
|
|
121
|
+
super("TerraBase response body failed in transit.", { cause });
|
|
122
|
+
this.name = "BodyTransportError";
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Internal transport bound to one data key. */
|
|
127
|
+
export class V1Transport {
|
|
128
|
+
/** @type {string} */
|
|
129
|
+
#project;
|
|
130
|
+
/** @type {V1EndpointResolver} */
|
|
131
|
+
#resolver;
|
|
132
|
+
/** @type {Map<string, { promise: Promise<string>; timer: ReturnType<typeof setTimeout>; waiters: number }>} */
|
|
133
|
+
#bases = new Map();
|
|
134
|
+
/** @type {string} */
|
|
135
|
+
#token;
|
|
136
|
+
/** @type {FetchLike} */
|
|
137
|
+
#fetch;
|
|
138
|
+
/** @type {number} */
|
|
139
|
+
#maxResponseBytes;
|
|
140
|
+
|
|
141
|
+
/** @param {TerraBaseV1ClientConfig} config */
|
|
142
|
+
constructor(config) {
|
|
143
|
+
if (typeof config !== "object" || config === null) throw new TypeError("TerraBase v1 client config is required.");
|
|
144
|
+
this.#project = requireProject(config.project);
|
|
145
|
+
if ((config.baseUrl === undefined) === (config.endpointResolver === undefined))
|
|
146
|
+
throw new TypeError("Supply exactly one of baseUrl or endpointResolver.");
|
|
147
|
+
if (config.endpointResolver !== undefined && typeof config.endpointResolver !== "function")
|
|
148
|
+
throw new TypeError("endpointResolver must be a function.");
|
|
149
|
+
this.#resolver = config.endpointResolver ?? staticBaseUrlResolver(/** @type {string} */ (config.baseUrl));
|
|
150
|
+
if (typeof config.token !== "string" || !tokenPattern.test(config.token))
|
|
151
|
+
throw new TypeError("token must be a tb_ API key with 43 base64url characters.");
|
|
152
|
+
if ("autoIdempotencyKey" in config || "maxRetries" in config || "resolver" in config)
|
|
153
|
+
throw new TypeError("Unsupported client configuration member.");
|
|
154
|
+
const fetchHandler = config.fetch ?? globalThis.fetch?.bind(globalThis);
|
|
155
|
+
if (typeof fetchHandler !== "function") throw new TypeError("TerraBase v1 client requires a fetch implementation.");
|
|
156
|
+
const maxResponseBytes = config.maxResponseBytes ?? defaultMaximumResponseBytes;
|
|
157
|
+
if (!Number.isSafeInteger(maxResponseBytes) || maxResponseBytes < 1)
|
|
158
|
+
throw new TypeError("maxResponseBytes must be a positive integer.");
|
|
159
|
+
this.#token = config.token;
|
|
160
|
+
this.#fetch = fetchHandler;
|
|
161
|
+
this.#maxResponseBytes = maxResponseBytes;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @param {V1Operation} operation
|
|
166
|
+
* @param {Readonly<Record<string, string>>} params
|
|
167
|
+
* @param {AbortSignal | undefined} [signal]
|
|
168
|
+
* @returns {Promise<string>}
|
|
169
|
+
*/
|
|
170
|
+
async url(operation, params, signal) {
|
|
171
|
+
signal?.throwIfAborted();
|
|
172
|
+
const database = requireName("database", params.database);
|
|
173
|
+
let base = this.#bases.get(database);
|
|
174
|
+
if (base === undefined) {
|
|
175
|
+
const controller = new AbortController();
|
|
176
|
+
const timer = setTimeout(() => controller.abort(new DOMException(
|
|
177
|
+
"TerraBase endpoint resolution timed out after 30 seconds.", "TimeoutError",
|
|
178
|
+
)), 30_000);
|
|
179
|
+
/** @type {Promise<string>} */
|
|
180
|
+
const promise = new Promise((resolve, reject) => {
|
|
181
|
+
controller.signal.addEventListener("abort", () => reject(controller.signal.reason), { once: true });
|
|
182
|
+
void Promise.resolve().then(() => this.#resolver(Object.freeze({
|
|
183
|
+
project: this.#project, database, signal: controller.signal,
|
|
184
|
+
}))).then(canonicalBaseUrl).then(resolve, reject).finally(() => clearTimeout(timer));
|
|
185
|
+
});
|
|
186
|
+
base = { promise, timer, waiters: 0 };
|
|
187
|
+
this.#bases.set(database, base);
|
|
188
|
+
// A failed resolution is not a session; a later operation may resolve again.
|
|
189
|
+
void promise.catch(() => { if (this.#bases.get(database) === base) this.#bases.delete(database); });
|
|
190
|
+
}
|
|
191
|
+
base.waiters++;
|
|
192
|
+
if (typeof base.timer === "object") base.timer.ref();
|
|
193
|
+
try {
|
|
194
|
+
// Each caller cancels its own wait; one caller cannot abort shared session resolution.
|
|
195
|
+
const resolved = signal === undefined ? await base.promise : await new Promise((resolve, reject) => {
|
|
196
|
+
const abort = () => reject(signal.reason);
|
|
197
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
198
|
+
void base.promise.then(value => {
|
|
199
|
+
signal.removeEventListener("abort", abort);
|
|
200
|
+
resolve(value);
|
|
201
|
+
}, error => {
|
|
202
|
+
signal.removeEventListener("abort", abort);
|
|
203
|
+
reject(error);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
signal?.throwIfAborted();
|
|
207
|
+
return `${resolved}${v1RoutePath(v1Route(operation), { ...params, project: this.#project })}`;
|
|
208
|
+
} finally {
|
|
209
|
+
// Keep Node alive only while callers are waiting for this resolution.
|
|
210
|
+
if (--base.waiters === 0 && typeof base.timer === "object") base.timer.unref();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Reads a response body as UTF-8 text within the response byte bound. A
|
|
216
|
+
* connection failure while reading is a BodyTransportError.
|
|
217
|
+
* @param {Response} response
|
|
218
|
+
* @returns {Promise<string>}
|
|
219
|
+
*/
|
|
220
|
+
async readText(response) {
|
|
221
|
+
const reader = response.body?.getReader();
|
|
222
|
+
if (reader === undefined) return "";
|
|
223
|
+
/** @type {Uint8Array[]} */
|
|
224
|
+
const parts = [];
|
|
225
|
+
let size = 0;
|
|
226
|
+
try {
|
|
227
|
+
while (true) {
|
|
228
|
+
/** @type {ReadableStreamReadResult<Uint8Array>} */
|
|
229
|
+
let part;
|
|
230
|
+
try {
|
|
231
|
+
part = await reader.read();
|
|
232
|
+
} catch (error) {
|
|
233
|
+
throw new BodyTransportError(error);
|
|
234
|
+
}
|
|
235
|
+
if (part.done) break;
|
|
236
|
+
size += part.value.byteLength;
|
|
237
|
+
if (size > this.#maxResponseBytes)
|
|
238
|
+
throw new TypeError(`TerraBase response exceeds ${this.#maxResponseBytes} bytes.`);
|
|
239
|
+
parts.push(part.value);
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
void reader.cancel().catch(() => undefined);
|
|
243
|
+
throw error;
|
|
244
|
+
} finally {
|
|
245
|
+
reader.releaseLock();
|
|
246
|
+
}
|
|
247
|
+
const bytes = new Uint8Array(size);
|
|
248
|
+
let offset = 0;
|
|
249
|
+
for (const part of parts) {
|
|
250
|
+
bytes.set(part, offset);
|
|
251
|
+
offset += part.byteLength;
|
|
252
|
+
}
|
|
253
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Parses a JSON response body exactly.
|
|
258
|
+
* @param {Response} response
|
|
259
|
+
* @returns {Promise<JsonValue | undefined>}
|
|
260
|
+
*/
|
|
261
|
+
async readJson(response) {
|
|
262
|
+
return V1Transport.#decodeJson(response, await this.readText(response));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* @param {Response} response
|
|
267
|
+
* @param {string} text
|
|
268
|
+
* @returns {JsonValue | undefined}
|
|
269
|
+
*/
|
|
270
|
+
static #decodeJson(response, text) {
|
|
271
|
+
if (text === "") return undefined;
|
|
272
|
+
const mediaType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
|
|
273
|
+
if (mediaType !== "application/json")
|
|
274
|
+
throw new TypeError(`TerraBase returned ${mediaType ?? "no media type"} instead of application/json.`);
|
|
275
|
+
return parseExactJson(text);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Converts a non-success response to a TerraBaseV1Error.
|
|
280
|
+
* @param {Response} response
|
|
281
|
+
* @returns {Promise<TerraBaseV1Error>}
|
|
282
|
+
*/
|
|
283
|
+
async error(response) {
|
|
284
|
+
let text = "";
|
|
285
|
+
try {
|
|
286
|
+
text = await this.readText(response);
|
|
287
|
+
} catch {
|
|
288
|
+
text = "";
|
|
289
|
+
}
|
|
290
|
+
return parseV1Error(response.status, response.headers, text);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Calls only a named producer route. Redirects and failed mutations are never replayed.
|
|
295
|
+
* @param {V1Operation} operation
|
|
296
|
+
* @param {Readonly<Record<string, string>>} params
|
|
297
|
+
* @param {V1CallOptions} [options]
|
|
298
|
+
* @returns {Promise<V1CallResult>}
|
|
299
|
+
*/
|
|
300
|
+
async call(operation, params, options = {}) {
|
|
301
|
+
const route = v1Route(operation);
|
|
302
|
+
if (options.body !== undefined && new TextEncoder().encode(options.body).byteLength > maximumRequestBytes)
|
|
303
|
+
throw new TypeError(`TerraBase request bodies are limited to ${maximumRequestBytes} bytes.`);
|
|
304
|
+
let url = await this.url(operation, params, options.signal);
|
|
305
|
+
if (options.query !== undefined && options.query.size > 0) url += `?${options.query}`;
|
|
306
|
+
const headers = new Headers(options.headers);
|
|
307
|
+
headers.set("authorization", `Bearer ${this.#token}`);
|
|
308
|
+
headers.set("accept", route.responseMediaType);
|
|
309
|
+
if (options.body !== undefined) headers.set("content-type", options.contentType ?? "application/json");
|
|
310
|
+
/** @type {RequestInit} */
|
|
311
|
+
const init = { method: route.method, headers, redirect: "manual" };
|
|
312
|
+
if (options.body !== undefined) init.body = options.body;
|
|
313
|
+
if (options.signal !== undefined) init.signal = options.signal;
|
|
314
|
+
const response = await this.#fetch(url, init);
|
|
315
|
+
if (response.type === "opaqueredirect")
|
|
316
|
+
throw new TypeError("Fresh shape bootstrap requires server fetch; obtain a handle and snapshot offset with collection.shape() on your server.");
|
|
317
|
+
if (!route.successStatuses.includes(response.status)) throw await this.error(response);
|
|
318
|
+
if (response.status === 307) {
|
|
319
|
+
await response.body?.cancel();
|
|
320
|
+
return { status: response.status, headers: response.headers, value: undefined };
|
|
321
|
+
}
|
|
322
|
+
return { status: response.status, headers: response.headers, value: await this.readJson(response) };
|
|
323
|
+
}
|
|
324
|
+
}
|
package/types/database-view.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @deprecated Retired SQLite/Rust subscriptions; use the C# client.
|
|
2
3
|
* Native snapshot/poll source shared by React, Svelte and TanStack.
|
|
3
4
|
* @param {TerraBaseClient} client
|
|
4
5
|
* @param {DatabaseQueryOptions} options
|
|
@@ -6,7 +7,7 @@
|
|
|
6
7
|
*/
|
|
7
8
|
export function createDatabaseQuery(client: TerraBaseClient, options: DatabaseQueryOptions): DatabaseQuerySource;
|
|
8
9
|
/**
|
|
9
|
-
* @import { TerraBaseClient } from "./
|
|
10
|
+
* @import { TerraBaseClient } from "./local/legacy-client.js"
|
|
10
11
|
* @import {
|
|
11
12
|
* DatabaseField, DatabasePoint, DatabaseQueryPredicate, DatabaseQueryRow,
|
|
12
13
|
* DatabaseResult, DatabaseScope, DatabaseSubscriptionRequest,
|
|
@@ -172,7 +173,7 @@ export type DatabaseQuerySource = {
|
|
|
172
173
|
readonly binding: DatabaseViewBinding;
|
|
173
174
|
readonly subscribe: (observer: DatabaseQueryCallbacks, context: ReactiveSubscriptionContext) => () => void;
|
|
174
175
|
};
|
|
175
|
-
import type { TerraBaseClient } from "./
|
|
176
|
+
import type { TerraBaseClient } from "./local/legacy-client.js";
|
|
176
177
|
import type { DatabaseResult } from "./database-types.js";
|
|
177
178
|
import type { DatabaseSubscriptionRequest } from "./database-types.js";
|
|
178
179
|
import type { DatabaseSubscriptionResponse } from "./database-types.js";
|
package/types/database.d.ts
CHANGED
|
@@ -1,98 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @returns {TerraBaseClient}
|
|
4
|
-
*/
|
|
5
|
-
export function createTerraBaseClient(config: TerraBaseClientConfig): TerraBaseClient;
|
|
6
|
-
/** Current scoped document client. All mutations are server commits in one declared shard. */
|
|
7
|
-
export class TerraBaseClient {
|
|
8
|
-
/** @param {TerraBaseClientConfig} config */
|
|
9
|
-
constructor(config: TerraBaseClientConfig);
|
|
10
|
-
/** @returns {DatabaseScope} */
|
|
11
|
-
get scope(): DatabaseScope;
|
|
12
|
-
/**
|
|
13
|
-
* @param {string} collection
|
|
14
|
-
* @param {string} document
|
|
15
|
-
* @param {DatabaseRequestOptions} [options]
|
|
16
|
-
* @returns {Promise<DatabaseResult<DatabasePoint>>}
|
|
17
|
-
*/
|
|
18
|
-
read(collection: string, document: string, options?: DatabaseRequestOptions): Promise<DatabaseResult<DatabasePoint>>;
|
|
19
|
-
/**
|
|
20
|
-
* @param {string} collection
|
|
21
|
-
* @param {DatabaseQuery} query
|
|
22
|
-
* @param {DatabaseRequestOptions} [options]
|
|
23
|
-
* @returns {Promise<DatabaseResult<DatabaseQueryPage>>}
|
|
24
|
-
*/
|
|
25
|
-
query(collection: string, query: DatabaseQuery, options?: DatabaseRequestOptions): Promise<DatabaseResult<DatabaseQueryPage>>;
|
|
26
|
-
/**
|
|
27
|
-
* @param {string} collection
|
|
28
|
-
* @param {DatabaseSubscriptionRequest} request
|
|
29
|
-
* @param {DatabaseRequestOptions} [options]
|
|
30
|
-
* @returns {Promise<DatabaseResult<DatabaseSubscriptionResponse>>}
|
|
31
|
-
*/
|
|
32
|
-
subscription(collection: string, request: DatabaseSubscriptionRequest, options?: DatabaseRequestOptions): Promise<DatabaseResult<DatabaseSubscriptionResponse>>;
|
|
33
|
-
/**
|
|
34
|
-
* Prepare once and retain this identity for exact retry and durable status resolution.
|
|
35
|
-
* @param {DatabaseCommit} commit
|
|
36
|
-
* @returns {Promise<PreparedDatabaseCommit>}
|
|
37
|
-
*/
|
|
38
|
-
prepareCommit(commit: DatabaseCommit): Promise<PreparedDatabaseCommit>;
|
|
39
|
-
/**
|
|
40
|
-
* @param {PreparedDatabaseCommit} prepared
|
|
41
|
-
* @param {DatabaseRequestOptions} [options]
|
|
42
|
-
* @returns {Promise<DatabaseResult<DatabaseCommitReceipt>>}
|
|
43
|
-
*/
|
|
44
|
-
commit(prepared: PreparedDatabaseCommit, options?: DatabaseRequestOptions): Promise<DatabaseResult<DatabaseCommitReceipt>>;
|
|
45
|
-
/**
|
|
46
|
-
* Unknown, pending and expired outcomes remain unresolved; an absent document proves no abort.
|
|
47
|
-
* @param {DatabaseTransactionIdentity} identity
|
|
48
|
-
* @param {DatabaseRequestOptions} [options]
|
|
49
|
-
* @returns {Promise<DatabaseResult<DatabaseTransactionStatus>>}
|
|
50
|
-
*/
|
|
51
|
-
transactionStatus(identity: DatabaseTransactionIdentity, options?: DatabaseRequestOptions): Promise<DatabaseResult<DatabaseTransactionStatus>>;
|
|
52
|
-
#private;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* - `apiKey`: native service key used for authenticated Atlas discovery and the selected regional listener.
|
|
56
|
-
* - `endpoint`: a provisioned direct origin. Omit to use authenticated native Atlas discovery.
|
|
57
|
-
* - `discoveryTimeoutMs`: bounds the canonical Atlas request within the complete operation deadline.
|
|
58
|
-
*/
|
|
59
|
-
export type TerraBaseClientConfig = DatabaseScope & {
|
|
60
|
-
readonly apiKey: string | (() => string | Promise<string>);
|
|
61
|
-
readonly endpoint?: string;
|
|
62
|
-
readonly discoveryTimeoutMs?: number;
|
|
63
|
-
readonly requestTimeoutMs?: number;
|
|
64
|
-
readonly fetch?: FetchLike;
|
|
65
|
-
};
|
|
66
|
-
export type DatabaseRequestOptions = {
|
|
67
|
-
readonly signal?: AbortSignal;
|
|
68
|
-
};
|
|
69
|
-
export type PreparedDatabaseCommit = DatabaseTransactionIdentity & {
|
|
70
|
-
readonly [preparedBrand]: true;
|
|
71
|
-
};
|
|
72
|
-
import type { DatabaseScope } from "./database-types.js";
|
|
73
|
-
import type { DatabasePoint } from "./database-types.js";
|
|
74
|
-
import type { DatabaseResult } from "./database-types.js";
|
|
75
|
-
import type { DatabaseQuery } from "./database-types.js";
|
|
76
|
-
import type { DatabaseQueryPage } from "./database-types.js";
|
|
77
|
-
import type { DatabaseSubscriptionRequest } from "./database-types.js";
|
|
78
|
-
import type { DatabaseSubscriptionResponse } from "./database-types.js";
|
|
79
|
-
import type { DatabaseCommit } from "./database-types.js";
|
|
80
|
-
import type { DatabaseCommitReceipt } from "./database-types.js";
|
|
81
|
-
import type { DatabaseTransactionIdentity } from "./database-types.js";
|
|
82
|
-
import type { DatabaseTransactionStatus } from "./database-types.js";
|
|
83
|
-
import type { FetchLike } from "./config.js";
|
|
84
|
-
/**
|
|
85
|
-
* - `apiKey`: native service key used for authenticated Atlas discovery and the selected regional listener.
|
|
86
|
-
* - `endpoint`: a provisioned direct origin. Omit to use authenticated native Atlas discovery.
|
|
87
|
-
* - `discoveryTimeoutMs`: bounds the canonical Atlas request within the complete operation deadline.
|
|
88
|
-
* @typedef {DatabaseScope & {
|
|
89
|
-
* readonly apiKey: string | (() => string | Promise<string>);
|
|
90
|
-
* readonly endpoint?: string;
|
|
91
|
-
* readonly discoveryTimeoutMs?: number;
|
|
92
|
-
* readonly requestTimeoutMs?: number;
|
|
93
|
-
* readonly fetch?: FetchLike;
|
|
94
|
-
* }} TerraBaseClientConfig
|
|
95
|
-
*/
|
|
96
|
-
/** @typedef {{ readonly signal?: AbortSignal }} DatabaseRequestOptions */
|
|
97
|
-
declare const preparedBrand: unique symbol;
|
|
98
|
-
export {};
|
|
1
|
+
export type TerraBaseClientConfig = import("./v1/transport.js").TerraBaseV1ClientConfig;
|
|
2
|
+
export { createTerraBaseV1Client as createTerraBaseClient, TerraBaseV1Client as TerraBaseClient } from "./v1/terrabase-v1.js";
|
package/types/index.d.ts
CHANGED
|
@@ -1,52 +1,43 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export type
|
|
6
|
-
export type
|
|
7
|
-
export type
|
|
8
|
-
export type
|
|
9
|
-
export type
|
|
10
|
-
export type
|
|
11
|
-
export type
|
|
12
|
-
export type
|
|
13
|
-
export type
|
|
14
|
-
export type
|
|
15
|
-
export type
|
|
16
|
-
export type
|
|
17
|
-
export type
|
|
18
|
-
export type
|
|
19
|
-
export type
|
|
20
|
-
export type
|
|
21
|
-
export type
|
|
22
|
-
export type
|
|
23
|
-
export type
|
|
24
|
-
export type
|
|
25
|
-
export type
|
|
26
|
-
export type
|
|
27
|
-
export type
|
|
28
|
-
export type
|
|
29
|
-
export type
|
|
30
|
-
export type
|
|
31
|
-
export type
|
|
32
|
-
export type
|
|
33
|
-
export type
|
|
34
|
-
export type
|
|
35
|
-
export type
|
|
36
|
-
export type
|
|
37
|
-
export type
|
|
38
|
-
export type
|
|
39
|
-
export type
|
|
40
|
-
export type
|
|
41
|
-
export
|
|
42
|
-
export type TerraScaleSuccess<TValue> = import("./result.js").TerraScaleSuccess<TValue>;
|
|
43
|
-
export type DatabaseQueryOptions = import("./database-view.js").DatabaseQueryOptions;
|
|
44
|
-
export type DatabaseViewBinding = import("./database-view.js").DatabaseViewBinding;
|
|
45
|
-
export type DatabaseViewPosition = import("./database-view.js").DatabaseViewPosition;
|
|
46
|
-
export type DatabaseViewSnapshot = import("./database-view.js").DatabaseViewSnapshot;
|
|
47
|
-
export type DatabaseQueryCallbacks = import("./database-view.js").DatabaseQueryCallbacks;
|
|
48
|
-
export type DatabaseQuerySource = import("./database-view.js").DatabaseQuerySource;
|
|
49
|
-
export { createTerraBaseClient, TerraBaseClient } from "./database.js";
|
|
50
|
-
export { terraBaseDiscoveryOrigin, parseTerraBaseRoutingDocument, TerraBaseDiscoveryError, TerraBaseDiscoveryRouter } from "./discovery.js";
|
|
1
|
+
export { v1Filter } from "./v1/filter.js";
|
|
2
|
+
export { documentIdFor } from "./v1/ids.js";
|
|
3
|
+
export { ExactDecimal } from "./v1/json.js";
|
|
4
|
+
export { staticBaseUrlResolver } from "./v1/transport.js";
|
|
5
|
+
export type TerraBaseV1ClientConfig = import("./v1/transport.js").TerraBaseV1ClientConfig;
|
|
6
|
+
export type V1RequestOptions = import("./v1/terrabase-v1.js").V1RequestOptions;
|
|
7
|
+
export type V1ReadOptions = import("./v1/terrabase-v1.js").V1ReadOptions;
|
|
8
|
+
export type V1WriteOptions = import("./v1/terrabase-v1.js").V1WriteOptions;
|
|
9
|
+
export type V1CreateOptions = import("./v1/terrabase-v1.js").V1CreateOptions;
|
|
10
|
+
export type V1ConditionalWriteOptions = import("./v1/terrabase-v1.js").V1ConditionalWriteOptions;
|
|
11
|
+
export type V1PatchOp = import("./v1/terrabase-v1.js").V1PatchOp;
|
|
12
|
+
export type V1Patch = import("./v1/terrabase-v1.js").V1Patch;
|
|
13
|
+
export type V1SortKey = import("./v1/terrabase-v1.js").V1SortKey;
|
|
14
|
+
export type V1Query = import("./v1/terrabase-v1.js").V1Query;
|
|
15
|
+
export type V1Count = import("./v1/terrabase-v1.js").V1Count;
|
|
16
|
+
export type V1QueryPage = import("./v1/terrabase-v1.js").V1QueryPage;
|
|
17
|
+
export type V1Precondition = import("./v1/terrabase-v1.js").V1Precondition;
|
|
18
|
+
export type V1TransactionOpResult = import("./v1/terrabase-v1.js").V1TransactionOpResult;
|
|
19
|
+
export type V1CountBounds = import("./v1/terrabase-v1.js").V1CountBounds;
|
|
20
|
+
export type V1TransactionResult = import("./v1/terrabase-v1.js").V1TransactionResult;
|
|
21
|
+
export type V1Document = import("./v1/decode.js").V1Document;
|
|
22
|
+
export type V1WriteResult = import("./v1/decode.js").V1WriteResult;
|
|
23
|
+
export type V1Durability = import("./v1/decode.js").V1Durability;
|
|
24
|
+
export type V1Filter = import("./v1/filter.js").V1Filter;
|
|
25
|
+
export type V1Path = import("./v1/filter.js").V1Path;
|
|
26
|
+
export type V1Scalar = import("./v1/filter.js").V1Scalar;
|
|
27
|
+
export type V1JsonValue = import("./v1/json.js").JsonValue;
|
|
28
|
+
export type V1JsonObject = import("./v1/json.js").JsonObject;
|
|
29
|
+
export type V1JsonInput = import("./v1/json.js").JsonInput;
|
|
30
|
+
export type V1JsonInputObject = import("./v1/json.js").JsonInputObject;
|
|
31
|
+
export type V1ShapeRequest = import("./v1/shapes.js").V1ShapeRequest;
|
|
32
|
+
export type V1ShapeChange = import("./v1/shapes.js").V1ShapeChange;
|
|
33
|
+
export type V1ShapeOp = import("./v1/shapes.js").V1ShapeOp;
|
|
34
|
+
export type TerraBaseClientConfig = import("./v1/transport.js").TerraBaseV1ClientConfig;
|
|
35
|
+
export type V1EndpointContext = import("./v1/transport.js").V1EndpointContext;
|
|
36
|
+
export type V1EndpointResolver = import("./v1/transport.js").V1EndpointResolver;
|
|
37
|
+
export type V1CollectionInfo = import("./v1/terrabase-v1.js").V1CollectionInfo;
|
|
38
|
+
export type V1CollectionPage = import("./v1/terrabase-v1.js").V1CollectionPage;
|
|
39
|
+
export type V1CollectionListOptions = import("./v1/terrabase-v1.js").V1CollectionListOptions;
|
|
40
|
+
export type V1ShapePage = import("./v1/shapes.js").V1ShapePage;
|
|
41
|
+
export { createTerraBaseV1Client as createTerraBaseClient, TerraBaseV1Client as TerraBaseClient, createTerraBaseV1Client, TerraBaseV1Client, V1Database, V1Collection, V1Collections, V1Transaction } from "./v1/terrabase-v1.js";
|
|
51
42
|
export { terraScaleReleaseBlockers, TerraScaleCapabilityUnavailableError } from "./management-contracts.js";
|
|
52
|
-
export {
|
|
43
|
+
export { TerraBaseV1Error, V1PreconditionFailedError, V1InvalidKeyError, V1ForbiddenScopeError, V1NotFoundError, V1ErrorCode, isTerraBaseV1Error } from "./v1/errors.js";
|
package/types/local/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* @deprecated Retired Rust emulator; use a local TerraBase release.
|
|
2
3
|
* @param {TerraScaleSqliteRuntimeOptions} options
|
|
3
4
|
* @returns {TerraScaleSqliteRuntime}
|
|
4
5
|
*/
|
|
5
6
|
export function createTerraScaleSqliteRuntime(options: TerraScaleSqliteRuntimeOptions): TerraScaleSqliteRuntime;
|
|
6
|
-
/** @import { TerraBaseClient, TerraBaseClientConfig } from "
|
|
7
|
+
/** @import { TerraBaseClient, TerraBaseClientConfig } from "./legacy-client.js" */
|
|
7
8
|
/** @import { CollectionBinding, DatabaseScope } from "../database-types.js" */
|
|
8
9
|
/** @typedef {import("./context.js").LocalAuthenticationMode} LocalAuthenticationMode */
|
|
9
10
|
/** @typedef {import("./server.js").LocalServerAddress} LocalServerAddress */
|
|
@@ -23,7 +24,8 @@ export function createTerraScaleSqliteRuntime(options: TerraScaleSqliteRuntimeOp
|
|
|
23
24
|
* readonly port?: number;
|
|
24
25
|
* }} TerraScaleLocalListenOptions
|
|
25
26
|
*/
|
|
26
|
-
/**
|
|
27
|
+
/** @deprecated Retired Rust SQLite emulator; use a local TerraBase release binary.
|
|
28
|
+
* Explicit Node development backend. Never load this entrypoint in deployment or qualification. */
|
|
27
29
|
export class TerraScaleSqliteRuntime {
|
|
28
30
|
/**
|
|
29
31
|
* @param {TerraScaleSqliteRuntimeOptions} options
|
|
@@ -90,5 +92,5 @@ export type TerraScaleLocalListenOptions = {
|
|
|
90
92
|
};
|
|
91
93
|
import type { DatabaseScope } from "../database-types.js";
|
|
92
94
|
import type { CollectionBinding } from "../database-types.js";
|
|
93
|
-
import type { TerraBaseClientConfig } from "
|
|
94
|
-
import type { TerraBaseClient } from "
|
|
95
|
+
import type { TerraBaseClientConfig } from "./legacy-client.js";
|
|
96
|
+
import type { TerraBaseClient } from "./legacy-client.js";
|