Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom CBOR encoding/decoding replacer #387

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/data/cbor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Tagged, decode, encode } from "../cbor";
import { type Replacer, Tagged, decode, encode } from "../cbor";
import {
cborCustomDateToDate,
dateToCborCustomDate,
Expand Down Expand Up @@ -55,7 +55,10 @@ const TAG_GEOMETRY_MULTILINE = 92;
const TAG_GEOMETRY_MULTIPOLYGON = 93;
const TAG_GEOMETRY_COLLECTION = 94;

export const replacer = {
export const replacer: {
encode: Replacer;
decode: Replacer;
} = {
encode(v: unknown): unknown {
if (v instanceof Date) {
return new Tagged(TAG_CUSTOM_DATETIME, dateToCborCustomDate(v));
Expand Down
2 changes: 1 addition & 1 deletion src/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ export {
GeometryPoint,
GeometryPolygon,
} from "./types/geometry.ts";
export { encodeCbor, decodeCbor } from "./cbor.ts";
export { encodeCbor, decodeCbor, replacer } from "./cbor.ts";
37 changes: 27 additions & 10 deletions src/surreal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
Table,
type Uuid,
RecordId as _RecordId,
decodeCbor,
encodeCbor,
} from "./data";
import {
type AbstractEngine,
Expand Down Expand Up @@ -34,7 +32,13 @@ import {
convertAuth,
} from "./types.ts";

import { type Fill, partiallyEncodeObject } from "./cbor";
import {
type Fill,
type Replacer,
decode,
encode,
partiallyEncodeObject,
} from "./cbor";
import { replacer } from "./data/cbor.ts";
import type { RecordIdRange } from "./data/types/range.ts";
import { HttpEngine } from "./engines/http.ts";
Expand All @@ -51,6 +55,17 @@ import {
type R = Prettify<Record<string, unknown>>;
type RecordId<Tb extends string = string> = _RecordId<Tb> | StringRecordId;

export type SurrealOptions = {
engines?: Engines;

replacer?: ReplacerOptions;
};

export type ReplacerOptions = {
encode: Replacer;
decode: Replacer;
};

export class Surreal {
public connection: AbstractEngine | undefined;
ready?: Promise<void>;
Expand All @@ -61,12 +76,9 @@ export class Surreal {
http: HttpEngine,
https: HttpEngine,
};
protected replacer: ReplacerOptions;

constructor({
engines,
}: {
engines?: Engines;
} = {}) {
constructor({ engines, replacer: customReplacer }: SurrealOptions = {}) {
this.emitter = new Emitter();
this.emitter.subscribe(ConnectionStatus.Disconnected, () => this.clean());
this.emitter.subscribe(ConnectionStatus.Error, () => this.close());
Expand All @@ -77,6 +89,11 @@ export class Surreal {
...engines,
};
}

this.replacer = customReplacer ?? {
encode: replacer.encode,
decode: replacer.decode,
};
}

/**
Expand Down Expand Up @@ -116,8 +133,8 @@ export class Surreal {
// to ensure that everything is using the same instance of classes that these methods depend on.
const context = new EngineContext({
emitter: this.emitter,
encodeCbor,
decodeCbor,
encodeCbor: (data) => encode(data, { replacer: this.replacer?.encode }),
decodeCbor: (data) => decode(data, { replacer: this.replacer?.decode }),
});

// The promise does not know if `this.connection` is undefined or not, but it does about `connection`
Expand Down
18 changes: 14 additions & 4 deletions src/util/prepared-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
type Fill,
Gap,
type PartiallyEncoded,
type Replacer,
Writer,
encode,
partiallyEncodeObject,
Expand All @@ -19,13 +20,19 @@ export type ConvertMethod<T = unknown> = (result: unknown[]) => T;
export class PreparedQuery {
private _query: Uint8Array;
private _bindings: Record<string, PartiallyEncoded>;
private _replacer: Replacer;
private length: number;

constructor(query: string, bindings?: Record<string, unknown>) {
constructor(
query: string,
bindings?: Record<string, unknown>,
{ replacer: customReplacer }: { replacer?: Replacer } = {},
) {
textEncoder ??= new TextEncoder();
this._query = textEncoder.encode(query);
this._replacer = customReplacer ?? replacer.encode;
this._bindings = partiallyEncodeObject(bindings ?? {}, {
replacer: replacer.encode,
replacer: this._replacer,
});
this.length = Object.keys(this._bindings).length;
}
Expand Down Expand Up @@ -53,7 +60,10 @@ export class PreparedQuery {
* @param fills - The gap values to fill
*/
build(fills?: Fill[]): ArrayBuffer {
return encode([this.query, this.bindings], { fills });
return encode([this.query, this.bindings], {
fills,
replacer: this._replacer,
});
}

/**
Expand Down Expand Up @@ -92,7 +102,7 @@ export class PreparedQuery {

for (const [k, v] of mapped_bindings) {
this._bindings[k] = encode(v, {
replacer: replacer.encode,
replacer: this._replacer,
partial: true,
});
}
Expand Down
Loading