@romedb/client 0.0.0-stage → 0.2.14
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/LICENSE.md +20 -0
- package/README.md +140 -2
- package/client-internal.cjs +2 -0
- package/client.cjs +489 -0
- package/client.d.ts +105 -0
- package/client.mjs +502 -0
- package/package.json +49 -3
- package/request-journal.cjs +47 -0
- package/values.cjs +221 -0
- package/values.d.ts +15 -0
- package/values.mjs +230 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright 2024 the Turso authors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
10
|
+
subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,141 @@
|
|
|
1
|
-
#
|
|
1
|
+
# RomeDB client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@romedb/client` connects to a RomeDB database by URL, behind `romedb serve`, `romedb
|
|
4
|
+
serve --directory` or RomeDB Cloud. It runs in Node.js, Cloudflare Workers, browsers
|
|
5
|
+
and any other runtime with `fetch`.
|
|
6
|
+
|
|
7
|
+
The package is about 30 KB to download, has no dependencies and has no native addon. It holds the
|
|
8
|
+
same code as `@romedb/node/client` and `@romedb/node/values`, byte for byte, at the same
|
|
9
|
+
version. To open a local database file, use [`@romedb/node`](https://www.npmjs.com/package/@romedb/node).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install @romedb/client
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## A first request
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import { connect, Float64 } from '@romedb/client';
|
|
21
|
+
|
|
22
|
+
const rql = await connect({ url: process.env.ROMEDB_URL, token: process.env.ROMEDB_TOKEN });
|
|
23
|
+
const snapshot = await rql.read([{ sql: 'SELECT * FROM posts LIMIT 20' }]);
|
|
24
|
+
await rql.writeAtomic([
|
|
25
|
+
{ sql: 'UPDATE posts:p1 MERGE {score: $score}', params: { $score: new Float64(1) } },
|
|
26
|
+
]);
|
|
27
|
+
await rql.close();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`require('@romedb/client')` works the same way in Node.js.
|
|
31
|
+
|
|
32
|
+
## In a Cloudflare Worker
|
|
33
|
+
|
|
34
|
+
Workers need no `nodejs_compat`.
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
import { connect } from '@romedb/client';
|
|
38
|
+
|
|
39
|
+
export default {
|
|
40
|
+
async fetch(request, env) {
|
|
41
|
+
const rql = await connect({ url: env.ROMEDB_URL, token: env.ROMEDB_TOKEN });
|
|
42
|
+
const { results } = await rql.read([{ sql: "SELECT title FROM posts WHERE array::contains(tags, 'news')" }]);
|
|
43
|
+
return Response.json({ posts: results[0].rows.length });
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Value types only
|
|
49
|
+
|
|
50
|
+
`@romedb/client/values` exports `Float64`, `Record`, `Vector`, `encodeValue` and
|
|
51
|
+
`decodeValue`. Use it for code that never connects, such as a browser bundle.
|
|
52
|
+
|
|
53
|
+
## Using it with `@romedb/node`
|
|
54
|
+
|
|
55
|
+
Each package has its own value classes. A `Record` from `@romedb/client` is not an
|
|
56
|
+
instance of the `Record` from `@romedb/node/client`, so a client refuses a value from
|
|
57
|
+
the other package. Use one package for all your client code, or convert values at the
|
|
58
|
+
boundary.
|
|
59
|
+
|
|
60
|
+
## Saved requests
|
|
61
|
+
|
|
62
|
+
`saveRequest` and `loadRequest` keep a prepared write in a private file, so a write with
|
|
63
|
+
an unknown outcome can be recovered. They need Node.js file access and reject in other
|
|
64
|
+
runtimes. There, store the `PreparedWrite` object yourself, for example in a Durable
|
|
65
|
+
Object.
|
|
66
|
+
|
|
67
|
+
## URLs and tokens
|
|
68
|
+
|
|
69
|
+
A local service URL is `http://127.0.0.1:4321`. A Cloud URL names the organization
|
|
70
|
+
and database by stable UUIDs, and a dashboard URL that ends in `/query` also works.
|
|
71
|
+
Use HTTPS for every host that is not local.
|
|
72
|
+
|
|
73
|
+
`romedb://` is another name for `https://`. The client replaces the scheme and applies
|
|
74
|
+
the same rules, so `romedb://cloud.romedb.com/v1/organizations/{org}/databases/{db}`
|
|
75
|
+
and the `https://` form are the same database. Requests use `redirect: 'manual'`, and
|
|
76
|
+
any redirect fails with `RDB_PROTOCOL`, so the token never goes to another URL. Pass
|
|
77
|
+
the bearer token separately. The client refuses a token in the URL.
|
|
78
|
+
|
|
79
|
+
## Cloud URLs
|
|
80
|
+
|
|
81
|
+
For a Cloud URL, `connect()` returns without a network round trip. The database ID
|
|
82
|
+
comes from the URL, and the Cloud capabilities are documented. Reads start from
|
|
83
|
+
sequence 0 as their lower bound and update the sequence from each reply.
|
|
84
|
+
|
|
85
|
+
A write needs a current sequence. If none is known yet, `writeAtomic` first fetches
|
|
86
|
+
the database details, and `prepareWrite` throws `RDB_SEQUENCE_UNKNOWN` (outcome
|
|
87
|
+
`not-sent`) until a read, `info()` or an explicit `afterSequence` supplies one. To
|
|
88
|
+
fetch the details at connect, pass `deferInfo: false`. Other URLs always fetch the
|
|
89
|
+
details at connect and refuse `deferInfo: true`.
|
|
90
|
+
|
|
91
|
+
`connect()` on a Cloud URL also sends a warm request in the background and does not
|
|
92
|
+
wait for it. Cloud then starts the container of the database and opens it, so a query
|
|
93
|
+
a second or more later does not wait for that start. Errors of the background request
|
|
94
|
+
are ignored. To skip it, pass `warm: false`.
|
|
95
|
+
|
|
96
|
+
`await rql.warm()` sends the same request and returns `{ state }`. The state is
|
|
97
|
+
`ready` when the database is already open, `starting` when Cloud began to open it, or
|
|
98
|
+
`skipped` when Cloud declined because another database is busy. Call it when your
|
|
99
|
+
application knows that a query is coming, for example when a page or a function
|
|
100
|
+
starts. Local URLs refuse `warm()`.
|
|
101
|
+
|
|
102
|
+
## Local directories
|
|
103
|
+
|
|
104
|
+
An organization URL on a loopback host, such as a database of `romedb serve
|
|
105
|
+
--directory` (`http://127.0.0.1:4321/v1/organizations/{org}/databases/{db}`), always
|
|
106
|
+
fetches the details at connect. A reply with `serviceVersion: 1` is a local service.
|
|
107
|
+
The client then negotiates its capabilities and uses the 64 KiB service request
|
|
108
|
+
format, with no warm request. Any other reply is Cloud running locally, which keeps
|
|
109
|
+
the Cloud request format. So an application can use the same organization URLs for a
|
|
110
|
+
local directory and for Cloud.
|
|
111
|
+
|
|
112
|
+
## Values and results
|
|
113
|
+
|
|
114
|
+
Results use positional rows and keep duplicate columns. Integer results are `bigint`.
|
|
115
|
+
Number results are `Float64` instances with a `.value` number. They keep their exact
|
|
116
|
+
float type when you bind them again, integral floats and negative zero included.
|
|
117
|
+
|
|
118
|
+
Encoded vectors and the dense float32, float64 and sparse-entry factories
|
|
119
|
+
work without native code. `null` is a present field. `undefined` and array holes are
|
|
120
|
+
refused, so no data disappears without an error.
|
|
121
|
+
|
|
122
|
+
## Errors and timeouts
|
|
123
|
+
|
|
124
|
+
Requests and responses have finite byte and row limits. Each call times out after 20
|
|
125
|
+
seconds by default and accepts `signal` and `timeoutMs`. An HTTP error reply with a
|
|
126
|
+
`Retry-After` header sets `ClientError.retryAfterMs`. A transport or response failure
|
|
127
|
+
without a database reply keeps the underlying error as `ClientError.cause`, for
|
|
128
|
+
example a `fetch failed` TypeError with `ECONNREFUSED`.
|
|
129
|
+
|
|
130
|
+
`rql.sequenceKnown` is `true` once a reply has given the current sequence. `rql.cloud`
|
|
131
|
+
tells a Cloud database from a local service. A write cancelled after it was sent stays
|
|
132
|
+
unknown until a receipt confirms it. Cloud capabilities are marked as documented,
|
|
133
|
+
because its API does not negotiate the local capability object. See the
|
|
134
|
+
[service contract](https://github.com/romedb/romedb/blob/main/romedb/docs/service-protocol.md) for limits, receipt rules and
|
|
135
|
+
compatibility gaps.
|
|
136
|
+
|
|
137
|
+
## More
|
|
138
|
+
|
|
139
|
+
The [Node.js guide](https://github.com/romedb/romedb/blob/main/romedb/bindings/node/README.md#url-client)
|
|
140
|
+
has the full client reference, including saved requests, query versions and file
|
|
141
|
+
exports. The client methods are the same in both packages.
|