Skip to content

Commit

Permalink
Merge pull request #207 from oliver-oloughlin/float16array-support
Browse files Browse the repository at this point in the history
feat: support for Float16Array
  • Loading branch information
oliver-oloughlin authored May 4, 2024
2 parents 357312e + 86f3f48 commit a5c5fe0
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 416 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ collections and serialization/compression, while maintaining as much of the
native functionality as possible, like atomic operations, real-time data updates
and queue listeners. Also works with other runtimes such as Node.js and Bun.

_Supported Deno verisons:_ **^1.42.0**
_Supported Deno verisons:_ **^1.43.0**

## Highlights

Expand Down
4 changes: 2 additions & 2 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@olli/kvdex",
"version": "1.0.0",
"version": "1.0.1",
"exports": {
".": "./mod.ts",
"./ext/zod": "./ext/zod.ts",
"./ext/migrate": "./ext/migrate.ts"
},
"tasks": {
"check": "deno check mod.ts src/*.ts ext/*.ts tests/*.ts tests/**/*.ts benchmarks/**/*ts",
"test": "deno test --allow-write --allow-read --unstable-kv --trace-leaks",
"test": "deno test --allow-write --allow-read --allow-ffi --allow-sys --unstable-kv --trace-leaks",
"bench": "deno bench --unstable-kv",
"prep": "deno task check && deno fmt && deno lint && deno publish --dry-run --allow-dirty && deno task test",
"cache": "deno cache -r mod.ts && deno cache -r ext/zod.ts && deno cache -r ext/migrate.ts"
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ export type KvValue =
| Uint32Array
| BigUint64Array
| Uint8ClampedArray
| Float16Array
| Float32Array
| Float64Array
| ArrayBuffer
Expand Down
14 changes: 14 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export function isKvObject(value: unknown) {
value instanceof Uint32Array ||
value instanceof BigUint64Array ||
value instanceof Uint8ClampedArray ||
value instanceof Float16Array ||
value instanceof Float32Array ||
value instanceof Float64Array ||
value instanceof ArrayBuffer ||
Expand Down Expand Up @@ -590,6 +591,7 @@ export enum TypeKey {
Uint32Array = "__uint32array__",
BigUint64Array = "__biguint64array__",
Uint8ClampedArray = "__uint8clampedarray__",
Float16Array = "__float16array__",
Float32Array = "__float32array__",
Float64Array = "__float64array__",
ArrayBuffer = "__arraybuffer__",
Expand Down Expand Up @@ -949,6 +951,13 @@ export function _replacer(value: unknown): unknown {
}
}

// Float16Array
if (value instanceof Float16Array) {
return {
[TypeKey.Float16Array]: Array.from(value),
}
}

// Float32Array
if (value instanceof Float32Array) {
return {
Expand Down Expand Up @@ -1089,6 +1098,11 @@ export function _reviver(value: unknown): unknown {
return Uint8ClampedArray.from(mapValue(TypeKey.Uint8ClampedArray, value))
}

// Float16Array
if (TypeKey.Float16Array in value) {
return Float16Array.from(mapValue(TypeKey.Float16Array, value))
}

// Float32Array
if (TypeKey.Float32Array in value) {
return Float32Array.from(mapValue(TypeKey.Float32Array, value))
Expand Down
216 changes: 15 additions & 201 deletions tests/collection/types.test.ts
Original file line number Diff line number Diff line change
@@ -1,215 +1,29 @@
import { collection, kvdex, model } from "../../mod.ts"
import { assert } from "../test.deps.ts"
import { assert, assertEquals } from "../test.deps.ts"
import { useKv } from "../utils.ts"
import { VALUES } from "../values.ts"

Deno.test("collection - types", async (t) => {
await t.step(
"Should allow and properly store/retrieve all primitive types",
"Should allow and properly store/retrieve all KvValue types",
async () => {
await useKv(async (kv) => {
const db = kvdex(kv, {
nulls: collection(model<null>()),
undefineds: collection(model<undefined>()),
strings: collection(model<string>()),
numbers: collection(model<number>()),
bigints: collection(model<bigint>()),
u64s: collection(model<Deno.KvU64>()),
})

const cr1 = await db.nulls.add(null)
const cr2 = await db.undefineds.add(undefined)
const cr3 = await db.strings.add("str1")
const cr4 = await db.numbers.add(1)
const cr5 = await db.bigints.add(1n)
const cr6 = await db.u64s.add(new Deno.KvU64(1n))

assert(cr1.ok)
assert(cr2.ok)
assert(cr3.ok)
assert(cr4.ok)
assert(cr5.ok)
assert(cr6.ok)

await db.nulls.forEach((doc) => assert(doc.value === null))
await db.undefineds.forEach((doc) => assert(doc.value === undefined))
await db.strings.forEach((doc) => assert(typeof doc.value === "string"))
await db.numbers.forEach((doc) => assert(typeof doc.value === "number"))
await db.bigints.forEach((doc) => assert(typeof doc.value === "bigint"))
await db.u64s.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Deno.KvU64,
)
)
})
},
)

await t.step(
"Should allow and properly store/retrieve built-in object types",
async () => {
await useKv(async (kv) => {
const db = kvdex(kv, {
dates: collection(model<Date>()),
sets: collection(model<Set<string>>()),
maps: collection(model<Map<string, number>>()),
regExps: collection(model<RegExp>()),
dataVeiws: collection(model<DataView>()),
errors: collection(model<Error>()),
})

const cr1 = await db.dates.add(new Date())
const cr2 = await db.sets.add(new Set())
const cr3 = await db.maps.add(new Map())
const cr4 = await db.regExps.add(new RegExp("^[0-9]$"))
const cr5 = await db.dataVeiws.add(new DataView(new ArrayBuffer(16)))
const cr6 = await db.errors.add(new Error("error"))

assert(cr1.ok)
assert(cr2.ok)
assert(cr3.ok)
assert(cr4.ok)
assert(cr5.ok)
assert(cr6.ok)

await db.dates.forEach((doc) =>
assert(typeof doc.value === "object" && doc.value instanceof Date)
const schema = Object.fromEntries(
VALUES.map((
val,
i,
) => [i, collection(model<typeof val>())]),
)

await db.sets.forEach((doc) =>
assert(typeof doc.value === "object" && doc.value instanceof Set)
)
const db = kvdex(kv, schema)

await db.maps.forEach((doc) =>
assert(typeof doc.value === "object" && doc.value instanceof Map)
)
const crs = await Promise.all(VALUES.map((val, i) => db[i].add(val)))
assert(crs.every((cr) => cr.ok))

await db.regExps.forEach((doc) =>
assert(typeof doc.value === "object" && doc.value instanceof RegExp)
)

await db.dataVeiws.forEach((doc) =>
assert(typeof doc.value === "object" && doc.value instanceof DataView)
)

await db.errors.forEach((doc) =>
assert(typeof doc.value === "object" && doc.value instanceof Error)
)
})
},
)

await t.step(
"Should allow and properly store/retrieve array types",
async () => {
await useKv(async (kv) => {
const db = kvdex(kv, {
arrs: collection(model<Array<string>>()),
i8arrs: collection(model<Int8Array>()),
i16arrs: collection(model<Int16Array>()),
i32arrs: collection(model<Int32Array>()),
i64arrs: collection(model<BigInt64Array>()),
u8arrs: collection(model<Uint8Array>()),
u16arrs: collection(model<Uint16Array>()),
u32arrs: collection(model<Uint32Array>()),
u64arrs: collection(model<BigUint64Array>()),
u8carrs: collection(model<Uint8ClampedArray>()),
f32arrs: collection(model<Float32Array>()),
f64arrs: collection(model<Float64Array>()),
buffers: collection(model<ArrayBuffer>()),
})

const cr1 = await db.arrs.add(["str1", "str2", "str3"])
const cr2 = await db.i8arrs.add(new Int8Array([1, 2, 3]))
const cr3 = await db.i16arrs.add(new Int16Array([1, 2, 3]))
const cr4 = await db.i32arrs.add(new Int32Array([1, 2, 3]))
const cr5 = await db.i64arrs.add(new BigInt64Array([1n, 2n, 3n]))
const cr6 = await db.u8arrs.add(new Uint8Array([1, 2, 3]))
const cr7 = await db.u16arrs.add(new Uint16Array([1, 2, 3]))
const cr8 = await db.u32arrs.add(new Uint32Array([1, 2, 3]))
const cr9 = await db.u64arrs.add(new BigUint64Array([1n, 2n, 3n]))
const cr10 = await db.u8carrs.add(new Uint8ClampedArray([1, 2, 3]))
const cr11 = await db.f32arrs.add(new Float32Array([1.0, 2.0, 3.0]))
const cr12 = await db.f64arrs.add(new Float64Array([1.0, 2.0, 3.0]))
const cr13 = await db.buffers.add(new ArrayBuffer(16))

assert(cr1.ok)
assert(cr2.ok)
assert(cr3.ok)
assert(cr4.ok)
assert(cr5.ok)
assert(cr6.ok)
assert(cr7.ok)
assert(cr8.ok)
assert(cr9.ok)
assert(cr10.ok)
assert(cr11.ok)
assert(cr12.ok)
assert(cr13.ok)

await db.arrs.forEach((doc) =>
assert(typeof doc.value === "object" && doc.value instanceof Array)
)
await db.i8arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Int8Array,
)
)
await db.i16arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Int16Array,
)
)
await db.i32arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Int32Array,
)
)
await db.i64arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof BigInt64Array,
)
)
await db.u8arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Uint8Array,
)
)
await db.u16arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Uint16Array,
)
)
await db.u32arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Uint32Array,
)
)
await db.u64arrs.forEach((doc) =>
assert(
typeof doc.value === "object" &&
doc.value instanceof BigUint64Array,
)
)
await db.u8carrs.forEach((doc) =>
assert(
typeof doc.value === "object" &&
doc.value instanceof Uint8ClampedArray,
)
)
await db.f32arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Float32Array,
)
)
await db.f64arrs.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof Float64Array,
)
)
await db.buffers.forEach((doc) =>
assert(
typeof doc.value === "object" && doc.value instanceof ArrayBuffer,
)
await Promise.all(
VALUES.map((_, i) =>
db[i].forEach((doc) => assertEquals(doc.value, VALUES[i]))
),
)
})
},
Expand Down
18 changes: 10 additions & 8 deletions tests/db/properties.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import type { DenoKv } from "../../mod.ts"
import type { Kv } from "../test.deps.ts"

function check(_: DenoKv) {}
import { openKv } from "npm:@deno/kv"
import { kvdex } from "../../mod.ts"

Deno.test("db - properties", async (t) => {
await t.step("Should allow native Deno KV type", () => {
check(null as unknown as Deno.Kv)
await t.step("Should allow native Deno KV type", async () => {
const kv = await Deno.openKv()
kvdex(kv, {})
kv.close()
})

await t.step("Should allow NPM Deno KV type", () => {
check(null as unknown as Kv)
await t.step("Should allow NPM Deno KV type", async () => {
const kv = await openKv()
kvdex(kv, {})
kv.close()
})
})
28 changes: 28 additions & 0 deletions tests/indexable_collection/types.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { collection, kvdex, model } from "../../mod.ts"
import { assert, assertEquals } from "../test.deps.ts"
import { useKv } from "../utils.ts"
import { TObject } from "../values.ts"

Deno.test("indexable_collection - types", async (t) => {
await t.step(
"Should allow and properly store/retrieve all KvValue types",
async () => {
await useKv(async (kv) => {
const db = kvdex(kv, {
objects: collection(model<typeof TObject>(), {
indices: {
TString: "primary",
TNumber: "secondary",
},
}),
})

const cr = await db.objects.add(TObject)
assert(cr.ok)

const doc = await db.objects.find(cr.id)
assertEquals(doc?.value, TObject)
})
},
)
})
Loading

0 comments on commit a5c5fe0

Please sign in to comment.