Skip to content

Commit 5331505

Browse files
committed
Added ability to provide custom cbor replacer for encoding/decoding
1 parent 3c9be01 commit 5331505

File tree

4 files changed

+47
-17
lines changed

4 files changed

+47
-17
lines changed

src/data/cbor.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Tagged, decode, encode } from "../cbor";
1+
import { type Replacer, Tagged, decode, encode } from "../cbor";
22
import {
33
cborCustomDateToDate,
44
dateToCborCustomDate,
@@ -55,7 +55,10 @@ const TAG_GEOMETRY_MULTILINE = 92;
5555
const TAG_GEOMETRY_MULTIPOLYGON = 93;
5656
const TAG_GEOMETRY_COLLECTION = 94;
5757

58-
export const replacer = {
58+
export const replacer: {
59+
encode: Replacer;
60+
decode: Replacer;
61+
} = {
5962
encode(v: unknown): unknown {
6063
if (v instanceof Date) {
6164
return new Tagged(TAG_CUSTOM_DATETIME, dateToCborCustomDate(v));

src/data/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ export {
2525
GeometryPoint,
2626
GeometryPolygon,
2727
} from "./types/geometry.ts";
28-
export { encodeCbor, decodeCbor } from "./cbor.ts";
28+
export { encodeCbor, decodeCbor, replacer } from "./cbor.ts";

src/surreal.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ import {
33
Table,
44
type Uuid,
55
RecordId as _RecordId,
6-
decodeCbor,
7-
encodeCbor,
86
} from "./data";
97
import {
108
type AbstractEngine,
@@ -34,7 +32,13 @@ import {
3432
convertAuth,
3533
} from "./types.ts";
3634

37-
import { type Fill, partiallyEncodeObject } from "./cbor";
35+
import {
36+
type Fill,
37+
type Replacer,
38+
decode,
39+
encode,
40+
partiallyEncodeObject,
41+
} from "./cbor";
3842
import { replacer } from "./data/cbor.ts";
3943
import type { RecordIdRange } from "./data/types/range.ts";
4044
import { HttpEngine } from "./engines/http.ts";
@@ -51,6 +55,17 @@ import {
5155
type R = Prettify<Record<string, unknown>>;
5256
type RecordId<Tb extends string = string> = _RecordId<Tb> | StringRecordId;
5357

58+
export type SurrealOptions = {
59+
engines?: Engines;
60+
61+
replacer?: ReplacerOptions;
62+
};
63+
64+
export type ReplacerOptions = {
65+
encode: Replacer;
66+
decode: Replacer;
67+
};
68+
5469
export class Surreal {
5570
public connection: AbstractEngine | undefined;
5671
ready?: Promise<void>;
@@ -61,12 +76,9 @@ export class Surreal {
6176
http: HttpEngine,
6277
https: HttpEngine,
6378
};
79+
protected replacer: ReplacerOptions;
6480

65-
constructor({
66-
engines,
67-
}: {
68-
engines?: Engines;
69-
} = {}) {
81+
constructor({ engines, replacer: customReplacer }: SurrealOptions = {}) {
7082
this.emitter = new Emitter();
7183
this.emitter.subscribe(ConnectionStatus.Disconnected, () => this.clean());
7284
this.emitter.subscribe(ConnectionStatus.Error, () => this.close());
@@ -77,6 +89,11 @@ export class Surreal {
7789
...engines,
7890
};
7991
}
92+
93+
this.replacer = customReplacer ?? {
94+
encode: replacer.encode,
95+
decode: replacer.decode,
96+
};
8097
}
8198

8299
/**
@@ -116,8 +133,8 @@ export class Surreal {
116133
// to ensure that everything is using the same instance of classes that these methods depend on.
117134
const context = new EngineContext({
118135
emitter: this.emitter,
119-
encodeCbor,
120-
decodeCbor,
136+
encodeCbor: (data) => encode(data, { replacer: this.replacer?.encode }),
137+
decodeCbor: (data) => decode(data, { replacer: this.replacer?.decode }),
121138
});
122139

123140
// The promise does not know if `this.connection` is undefined or not, but it does about `connection`

src/util/prepared-query.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
type Fill,
44
Gap,
55
type PartiallyEncoded,
6+
type Replacer,
67
Writer,
78
encode,
89
partiallyEncodeObject,
@@ -19,13 +20,19 @@ export type ConvertMethod<T = unknown> = (result: unknown[]) => T;
1920
export class PreparedQuery {
2021
private _query: Uint8Array;
2122
private _bindings: Record<string, PartiallyEncoded>;
23+
private _replacer: Replacer;
2224
private length: number;
2325

24-
constructor(query: string, bindings?: Record<string, unknown>) {
26+
constructor(
27+
query: string,
28+
bindings?: Record<string, unknown>,
29+
{ replacer: customReplacer }: { replacer?: Replacer } = {},
30+
) {
2531
textEncoder ??= new TextEncoder();
2632
this._query = textEncoder.encode(query);
33+
this._replacer = customReplacer ?? replacer.encode;
2734
this._bindings = partiallyEncodeObject(bindings ?? {}, {
28-
replacer: replacer.encode,
35+
replacer: this._replacer,
2936
});
3037
this.length = Object.keys(this._bindings).length;
3138
}
@@ -53,7 +60,10 @@ export class PreparedQuery {
5360
* @param fills - The gap values to fill
5461
*/
5562
build(fills?: Fill[]): ArrayBuffer {
56-
return encode([this.query, this.bindings], { fills });
63+
return encode([this.query, this.bindings], {
64+
fills,
65+
replacer: this._replacer,
66+
});
5767
}
5868

5969
/**
@@ -92,7 +102,7 @@ export class PreparedQuery {
92102

93103
for (const [k, v] of mapped_bindings) {
94104
this._bindings[k] = encode(v, {
95-
replacer: replacer.encode,
105+
replacer: this._replacer,
96106
partial: true,
97107
});
98108
}

0 commit comments

Comments
 (0)