-
Notifications
You must be signed in to change notification settings - Fork 73
Expand file tree
/
Copy pathsurreal.ts
More file actions
266 lines (232 loc) · 8.47 KB
/
Copy pathsurreal.ts
File metadata and controls
266 lines (232 loc) · 8.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
import { CborCodec } from "../cbor";
import { ConnectionController } from "../controller";
import { UnavailableFeatureError, UnsupportedFeatureError } from "../errors";
import { FlatBufferCodec } from "../flatbuffer/codec";
import type { Feature } from "../internal/feature";
import { getIncrementalID } from "../internal/get-incremental-id";
import { parseEndpoint } from "../internal/http";
import type {
CodecRegistry,
ConnectionStatus,
ConnectOptions,
DriverOptions,
EventPublisher,
SqlExportOptions,
VersionInfo,
} from "../types";
import { Publisher } from "../utils/publisher";
import type { Uuid } from "../value";
import { type SessionEvents, SurrealSession } from "./session";
export type SurrealEvents = SessionEvents & {
connecting: [];
connected: [string];
reconnecting: [];
disconnected: [];
error: [Error];
};
/**
* The Surreal class provides methods to connect to a SurrealDB instance,
* execute database queries, subscribe to events, and manage database sessions.
*
* Note that most methods in this class are dispatched once you subscribe to the
* returned Promise and offer various chainable configuration methods before
* making the actual request.
*
* By default the Surreal instance is scoped to a default session, however you
* can create a new session by calling the `newSession` or `forkSession` methods.
*/
export class Surreal extends SurrealSession implements EventPublisher<SurrealEvents> {
readonly #publisher = new Publisher<SurrealEvents>();
readonly #connection: ConnectionController;
override subscribe<K extends keyof SurrealEvents>(
event: K,
listener: (...payload: SurrealEvents[K]) => void,
): () => void {
return this.#publisher.subscribe(event, listener);
}
/**
* Construct a new Surreal instance with the provided options
*
* @param options Driver wide configuration options
*/
constructor(options?: DriverOptions) {
const driverOptions = options ?? {};
const connection = new ConnectionController({
options: driverOptions,
uniqueId: getIncrementalID,
codecs: Surreal.#compileCodecs(driverOptions),
});
super(connection, undefined);
connection.subscribe("connecting", () => {
this.#publisher.publish("connecting");
});
connection.subscribe("connected", (version) => {
this.#publisher.publish("connected", version);
});
connection.subscribe("disconnected", () => {
this.#publisher.publish("disconnected");
});
connection.subscribe("reconnecting", () => {
this.#publisher.publish("reconnecting");
});
connection.subscribe("error", (error) => {
this.#publisher.publish("error", error);
});
super.subscribe("auth", (token) => {
this.#publisher.publish("auth", token);
});
super.subscribe("using", (using) => {
this.#publisher.publish("using", using);
});
this.#connection = connection;
}
static #compileCodecs(options: DriverOptions): CodecRegistry {
const userCodecs = options.codecs ?? {};
const codecOptions = options.codecOptions ?? {};
return {
cbor: userCodecs.cbor?.(codecOptions) ?? new CborCodec(codecOptions),
flatbuffer: userCodecs.flatbuffer?.(codecOptions) ?? new FlatBufferCodec(codecOptions),
};
}
/**
* Returns the status of the connection
*/
get status(): ConnectionStatus {
return this.#connection.status;
}
/**
* Returns whether the connection is considered connected
*
* Equivalent to `this.status === "connected"`
*/
get isConnected(): boolean {
return this.#connection.status === "connected";
}
/**
* A promise which resolves when the connection is ready, or rejects
* if a connection error occurs.
*/
get ready(): Promise<void> {
return this.#connection.ready();
}
/**
* Returns the url of the database used for the current connection
*/
get url(): URL | undefined {
return this.#connection.state?.url;
}
// =========================================================== //
// //
// Connection Methods //
// //
// =========================================================== //
/**
* Connect to a local or remote SurrealDB instance using the provided URL.
*
* Calling `connect()` will reset and dispose any existing sessions created with `newSession()`.
*
* @param url The endpoint to connect to
* @param opts Options to configure the connection
*/
async connect(url: string | URL, opts: ConnectOptions = {}): Promise<true> {
return this.#connection.connect(parseEndpoint(url), opts);
}
/**
* Disconnect from the active SurrealDB instance
*/
async close(): Promise<true> {
return this.#connection.disconnect();
}
/**
* Check the health of the connected SurrealDB instance
*
* @returns The health of the connected SurrealDB instance
*/
health(): Promise<void> {
return this.#connection.health();
}
/**
* Retrieves the version of the connected SurrealDB instance
*
* @example { version: "surrealdb-2.1.0" }
*/
version(): Promise<VersionInfo> {
return this.#connection.version();
}
/**
* Checks whether a feature is available in the current connection
*
* @param feature The feature to check
*/
isFeatureSupported(feature: Feature): boolean {
try {
this.#connection.assertFeature(feature);
return true;
} catch (error) {
if (
error instanceof UnavailableFeatureError ||
error instanceof UnsupportedFeatureError
) {
return false;
}
throw error;
}
}
// =========================================================== //
// //
// Session Management Methods //
// //
// =========================================================== //
/**
* Lists all sessions created on the current connection.
*
* @returns A list of active session IDs
*/
sessions(): Promise<Uuid[]> {
return this.#connection.sessions();
}
/**
* Create a fresh new session on this connection and return a dedicated `Surreal` instance scoped to it.
*
* This session will contain its own copy of global variables, namespace, database, and authentication state.
* Connection related functions and event subscriptions will be shared with the original session. When the
* connection reconnects, the session will be automatically restored.
*
* You can invoke `reset()` on the created session to destroy it, after which it cannot be used again.
*
* @returns The new session
*/
async newSession(): Promise<SurrealSession> {
const created = await this.#connection.createSession(null);
return SurrealSession.of(this, created);
}
/**
* Stop the primary session. This is equivalent to calling `close()` on the connection.
*/
override async closeSession(): Promise<void> {
await this.close();
}
// =========================================================== //
// //
// Data Management Methods //
// //
// =========================================================== //
/**
* Export the database and return the result as a string
*
* @param options Optional export options
*/
public async export(options?: Partial<SqlExportOptions>): Promise<string> {
await this.ready;
return this.#connection.exportSql(options ?? {});
}
/**
* Import an existing export into the database
*
* @param input The data to import
*/
public async import(input: string): Promise<void> {
await this.ready;
return this.#connection.importSql(input);
}
}