diff --git a/integ/browser-tests/package.json b/integ/browser-tests/package.json index 5a5000fe..daeb1a37 100644 --- a/integ/browser-tests/package.json +++ b/integ/browser-tests/package.json @@ -25,15 +25,15 @@ "devDependencies": { "@nodelib/fs.walk": "^3.0.1", "@types/webpack": "^5.28.5", - "@zenfs/core": "^1.6.5", + "@zenfs/core": "^1.6.6", "@zenfs/dom": "^1.0.7", "fork-ts-checker-webpack-plugin": "^9.0.2", "html-webpack-plugin": "^5.6.3", - "puppeteer": "^23.9.0", + "puppeteer": "^23.10.1", "ts-loader": "^9.5.1", "tslib": "^2.8.1", "type-fest": "^4.30.0", - "webpack": "^5.96.1", + "webpack": "^5.97.1", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.1.0" } diff --git a/integ/cxx-tests/package.json b/integ/cxx-tests/package.json index 803a83e4..c3aabe7c 100644 --- a/integ/cxx-tests/package.json +++ b/integ/cxx-tests/package.json @@ -14,7 +14,7 @@ "tslib": "^2.8.1" }, "devDependencies": { - "execa": "^9.5.1", + "execa": "^9.5.2", "streaming-iterables": "^8.0.1" } } diff --git a/package.json b/package.json index 507f7788..ebf0ff2b 100644 --- a/package.json +++ b/package.json @@ -13,16 +13,16 @@ "test": "vitest", "typedoc": "bash mk/typedoc.sh" }, - "packageManager": "pnpm@9.14.4+sha512.c8180b3fbe4e4bca02c94234717896b5529740a6cbadf19fa78254270403ea2f27d4e1d46a08a0f56c89b63dc8ebfd3ee53326da720273794e6200fcf0d184ab", + "packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c", "devDependencies": { "@types/node": "^22.10.1", "@types/wtfnode": "^0.7.3", - "@typescript/lib-dom": "npm:@types/web@0.0.185", + "@typescript/lib-dom": "npm:@types/web@0.0.186", "@vitest/coverage-v8": "^2.1.8", "@yoursunny/xo-config": "0.59.0", "codedown": "^3.2.1", "tslib": "^2.8.1", - "typedoc": "^0.27.2", + "typedoc": "^0.27.4", "typescript": "~5.7.2", "vitest": "^2.1.8" }, @@ -39,7 +39,6 @@ }, "updateConfig": { "ignoreDependencies": [ - "abstract-level-1", "graphql-request" ] } diff --git a/pkg/cli-common/package.json b/pkg/cli-common/package.json index 41e63dbd..dd6152b2 100644 --- a/pkg/cli-common/package.json +++ b/pkg/cli-common/package.json @@ -32,7 +32,7 @@ "@ndn/node-transport": "workspace:*", "@ndn/packet": "workspace:*", "@ndn/util": "workspace:*", - "dotenv": "^16.4.6", + "dotenv": "^16.4.7", "env-var": "^7.5.0", "tslib": "^2.8.1", "wtfnode": "^0.9.4" diff --git a/pkg/fileserver/package.json b/pkg/fileserver/package.json index 041b2987..f5eb9c0f 100644 --- a/pkg/fileserver/package.json +++ b/pkg/fileserver/package.json @@ -32,7 +32,7 @@ "@ndn/segmented-object": "workspace:*", "@ndn/tlv": "workspace:*", "@ndn/util": "workspace:*", - "@zenfs/core": "^1.6.5", + "@zenfs/core": "^1.6.6", "mnemonist": "^0.39.8", "obliterator": "^2.0.4", "streaming-iterables": "^8.0.1", diff --git a/pkg/ndnsec/package.json b/pkg/ndnsec/package.json index 0301466b..a9bba3d2 100644 --- a/pkg/ndnsec/package.json +++ b/pkg/ndnsec/package.json @@ -30,7 +30,7 @@ "@ndn/tlv": "workspace:*", "@ndn/util": "workspace:*", "@yoursunny/asn1": "0.0.20200718", - "execa": "^9.5.1", + "execa": "^9.5.2", "tslib": "^2.8.1" } } \ No newline at end of file diff --git a/pkg/pyrepo/package.json b/pkg/pyrepo/package.json index 2f7ec8d3..d7e3c4c6 100644 --- a/pkg/pyrepo/package.json +++ b/pkg/pyrepo/package.json @@ -45,7 +45,7 @@ "@ndn/ndnsec": "workspace:^", "@ndn/nfdmgmt": "workspace:^", "@types/netmask": "^2.0.5", - "execa": "^9.5.1", + "execa": "^9.5.2", "netmask": "^2.0.2" } } \ No newline at end of file diff --git a/pkg/repo/README.md b/pkg/repo/README.md index e4097ef6..284d07a5 100644 --- a/pkg/repo/README.md +++ b/pkg/repo/README.md @@ -19,7 +19,7 @@ import assert from "node:assert/strict"; ## DataStore -**DataStore** is a Data packet storage, based on an [abstract-level](https://www.npmjs.com/package/abstract-level) compatible key-value database. +**DataStore** is a Data packet storage, based on an [abstract-level](https://www.npmjs.com/package/abstract-level) 2.x compatible key-value database. It implements most of `DataStore` interfaces defined in `@ndn/repo-api` package, offering APIs to insert and delete Data packets. `DataStore.create()` function creates a **DataStore** instance, but it's more convenient to use a helper function: diff --git a/pkg/repo/package.json b/pkg/repo/package.json index d6a86063..3cee7f7a 100644 --- a/pkg/repo/package.json +++ b/pkg/repo/package.json @@ -32,8 +32,7 @@ "@ndn/tlv": "workspace:*", "@ndn/util": "workspace:*", "abstract-level": "^2.0.1", - "abstract-level-1": "npm:abstract-level@^1.0.4", - "level": "^8.0.1", + "level": "^9.0.0", "memory-level": "^2.0.0", "streaming-iterables": "^8.0.1", "tslib": "^2.8.1", diff --git a/pkg/repo/src/data-store.ts b/pkg/repo/src/data-store.ts index e9185544..706fbe4a 100644 --- a/pkg/repo/src/data-store.ts +++ b/pkg/repo/src/data-store.ts @@ -69,10 +69,10 @@ export class DataStore extends TypedEventTarget return this.db.close(); } - private async *iterRecords(prefix?: Name): AsyncGenerator { + private async *iterRecords(prefix?: Name): AsyncGenerator { const range = prefix ? { gte: prefix } : {}; - const it = (this.db as DB.Db2).iterator(range); - for await (const [name, record] of it as unknown as AsyncIterable<[Name, DB.Record]>) { + const it = this.db.iterator(range); + for await (const [name, record] of it as unknown as AsyncIterable<[Name, DB.Value]>) { if (prefix?.isPrefixOf(name) === false) { break; } @@ -101,20 +101,8 @@ export class DataStore extends TypedEventTarget /** Retrieve Data by exact name. */ public async get(name: Name): Promise { - let record: DB.Record | undefined; - try { - record = await this.db.get(name); - // if record does not exist: - // - abstract-level@1 throws not-found error - // - abstract-level@2 returns undefined - } catch (err: unknown) { - if (DB.isNotFound(err)) { - return undefined; - } - throw err; - } - - return record === undefined || DB.isExpired(record) ? undefined : record.data; + const record = await this.db.get(name) as DB.Value | undefined; + return !record || DB.isExpired(record) ? undefined : record.data; } /** Find Data that satisfies Interest. */ @@ -140,7 +128,6 @@ export class DataStore extends TypedEventTarget */ public async insert(...args: S.Insert.Args): Promise { const { opts, pkts } = S.Insert.parseArgs(args); - await this.db.open(); // workaround for constructor(AbstractLevelDOWN) const tx = this.tx(); for await (const pkt of pkts) { tx.insert(pkt, opts); @@ -153,7 +140,6 @@ export class DataStore extends TypedEventTarget * @see {@link Transaction.delete} */ public async delete(...names: readonly Name[]): Promise { - await this.db.open(); // workaround for constructor(AbstractLevelDOWN) const tx = this.tx(); for (const name of names) { tx.delete(name); @@ -163,7 +149,6 @@ export class DataStore extends TypedEventTarget /** Delete all expired records. */ public async clearExpired(): Promise { - await this.db.open(); // workaround for constructor(AbstractLevelDOWN) const tx = this.tx(); const it = filter(DB.filterExpired(true), this.iterRecords()); for await (const { name } of it) { diff --git a/pkg/repo/src/db.ts b/pkg/repo/src/db.ts index a4712717..708bc27c 100644 --- a/pkg/repo/src/db.ts +++ b/pkg/repo/src/db.ts @@ -2,11 +2,10 @@ import { Data, Name } from "@ndn/packet"; import { Decoder, Encoder } from "@ndn/tlv"; import { assert, fromUtf8 } from "@ndn/util"; import type { AbstractChainedBatch, AbstractDatabaseOptions, AbstractLevel } from "abstract-level"; -import type { AbstractChainedBatch as Batch1, AbstractLevel as Level1 } from "abstract-level-1"; import type { Promisable } from "type-fest"; /** Value stored in database. */ -export interface Record { +export interface Value { readonly data: Data; readonly name: Name; readonly insertTime: number; @@ -15,7 +14,7 @@ export interface Record { const textEncoder = new TextEncoder(); /** Required options when creating abstract-level compatible key-value database. */ -export const AbstractLevelOptions: AbstractDatabaseOptions = { +export const AbstractLevelOptions: AbstractDatabaseOptions = { keyEncoding: { name: "d6d494ba-4d45-4b51-a102-26b8867c5034", format: "view", @@ -29,9 +28,9 @@ export const AbstractLevelOptions: AbstractDatabaseOptions = { valueEncoding: { name: "bb613530-3278-45f1-b5ae-7ced392eb602", format: "view", - encode(record: Record): Uint8Array { + encode(record: Value): Uint8Array { const encoder = new Encoder(); - const jText = JSON.stringify(record, ["insertTime", "expireTime"] satisfies Array); + const jText = JSON.stringify(record, ["insertTime", "expireTime"] satisfies Array); const jBufCap = 3 * jText.length; const jBuf = encoder.prependRoom(jBufCap); const { read: jTextLen = 0, written: jBufLen = 0 } = textEncoder.encodeInto(jText, jBuf); @@ -39,9 +38,9 @@ export const AbstractLevelOptions: AbstractDatabaseOptions = { encoder.encode(record.data); return encoder.output.subarray(0, encoder.size - jBufCap + jBufLen); }, - decode(stored: Uint8Array): Record { + decode(stored: Uint8Array): Value { const tlv = new Decoder(stored).read(); - const record = JSON.parse(fromUtf8(tlv.after)) as Record; + const record = JSON.parse(fromUtf8(tlv.after)) as Value; Object.defineProperties(record, { data: { configurable: true, @@ -64,13 +63,11 @@ export const AbstractLevelOptions: AbstractDatabaseOptions = { }, }; -export type Db2 = AbstractLevel; - /** An abstract-level compatible key-value database. */ -export type Db = Db2 | Level1; +export type Db = AbstractLevel; /** Function to create Db. */ -export type DbOpener = (opts: AbstractDatabaseOptions) => Promisable; +export type DbOpener = (opts: AbstractDatabaseOptions) => Promisable; /** * Constructor of AbstractLevel subclass. @@ -78,23 +75,17 @@ export type DbOpener = (opts: AbstractDatabaseOptions) => Promisab * @typeParam O - Last constructor argument, which must be the options object. */ export type DbCtor = - new(...a: [...A, O & AbstractDatabaseOptions]) => Db; + new(...a: [...A, O & AbstractDatabaseOptions]) => Db; /** A transaction chain in key-value database. */ -export type DbChain = AbstractChainedBatch | Batch1; - -/** Determine whether `err` represents "not found". */ -export function isNotFound(err: unknown): boolean { - const { code, notFound } = err as { code?: string; notFound?: true }; - return code === "LEVEL_NOT_FOUND" || notFound === true; -} +export type DbChain = AbstractChainedBatch; /** Determine whether a record has expired. */ -export function isExpired({ expireTime = Infinity }: Record, now = Date.now()): boolean { +export function isExpired({ expireTime = Infinity }: Value, now = Date.now()): boolean { return expireTime < now; } /** Create a filter function for either expired or unexpired records. */ -export function filterExpired(expired: boolean, now = Date.now()): (record: Record) => boolean { - return (record: Record) => isExpired(record, now) === expired; +export function filterExpired(expired: boolean, now = Date.now()): (record: Value) => boolean { + return (record: Value) => isExpired(record, now) === expired; } diff --git a/pkg/segmented-object/package.json b/pkg/segmented-object/package.json index 7f4a2fba..d394db71 100644 --- a/pkg/segmented-object/package.json +++ b/pkg/segmented-object/package.json @@ -31,7 +31,7 @@ "@ndn/naming-convention2": "workspace:*", "@ndn/packet": "workspace:*", "@ndn/util": "workspace:*", - "@zenfs/core": "^1.6.5", + "@zenfs/core": "^1.6.6", "it-keepalive": "^1.2.0", "mnemonist": "^0.39.8", "obliterator": "^2.0.4",