{"id":13687275,"url":"https://github.com/kitsonk/kv-toolbox","last_synced_at":"2025-04-08T03:09:20.209Z","repository":{"id":162960956,"uuid":"638201771","full_name":"kitsonk/kv-toolbox","owner":"kitsonk","description":"Utilities for working with Deno KV 🦕🗝️","archived":false,"fork":false,"pushed_at":"2025-03-01T01:58:51.000Z","size":8375,"stargazers_count":80,"open_issues_count":2,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-31T17:19:19.082Z","etag":null,"topics":["deno","deploy","kv"],"latest_commit_sha":null,"homepage":"https://kview.deno.dev/kv-toolbox","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kitsonk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-09T09:44:38.000Z","updated_at":"2025-03-06T07:40:12.000Z","dependencies_parsed_at":"2023-12-17T02:30:37.360Z","dependency_job_id":"c0cd5896-bba9-4d14-9ad5-18f709c92b1c","html_url":"https://github.com/kitsonk/kv-toolbox","commit_stats":{"total_commits":95,"total_committers":3,"mean_commits":"31.666666666666668","dds":"0.021052631578947323","last_synced_commit":"b9b37016294ac9cf46d4c5fbcd4957e5f3d4d0e6"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitsonk%2Fkv-toolbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitsonk%2Fkv-toolbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitsonk%2Fkv-toolbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kitsonk%2Fkv-toolbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kitsonk","download_url":"https://codeload.github.com/kitsonk/kv-toolbox/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247767234,"owners_count":20992547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","deploy","kv"],"created_at":"2024-08-02T15:00:51.435Z","updated_at":"2025-04-08T03:09:20.179Z","avatar_url":"https://github.com/kitsonk.png","language":"TypeScript","funding_links":[],"categories":["Utilities","TypeScript"],"sub_categories":[],"readme":"# kv-toolbox\n\n[![jsr.io/@kitsonk/kv-toolbox](https://jsr.io/badges/@kitsonk/kv-toolbox)](https://jsr.io/@kitsonk/kv-toolbox)\n[![jsr.io/@kitsonk/kv-toolbox score](https://jsr.io/badges/@kitsonk/kv-toolbox/score)](https://jsr.io/@kitsonk/kv-toolbox)\n[![kv-toolbox ci](https://github.com/kitsonk/kv-toolbox/workflows/ci/badge.svg)](https://github.com/kitsonk/kv-toolbox)\n\nA set of tools for working with Deno KV.\n\n## Toolbox\n\nThe default export of the library is the encapsulation of major functionality of\nthe library into classes which enhance the capabilities of working with a Deno\nKV store, which are also available as individual named exports of the the\nlibrary.\n\nThere are to variants of the toolbox: `KvToolbox` and `CryptoKvToolbox`. These\nprovide all the APIs of a `Deno.Kv` and the additional APIs offered by the rest\nof the library. The `CryptoKvToolbox` also attempts to encrypt and decrypt blob\nvalues.\n\nOpening a toolbox is similar to opening a `Deno.Kv` store:\n\n```ts\nimport { openKvToolbox } from \"jsr:@kitsonk/kv-toolbox\";\n\nconst kv = await openKvToolbox();\n```\n\nIf an encryption key is passed as an option, a `CryptoKvToolbox` instance will\nbe returned, where when storing and retrieving blobs in the store, they will be\nencrypted and decrypted by default:\n\n```ts\nimport { generateKey, openKvToolbox } from \"jsr:@kitsonk/kv-toolbox\";\n\nconst encryptWith = generateKey();\nconst kv = await openKvToolbox({ encryptWith });\n```\n\n\u003e [!NOTE]\n\u003e In practice, encryption keys would need to be persisted from session to\n\u003e session. The code above would generate a new key every execution and any\n\u003e values stored could not be decrypted. To be practical, generated encryption\n\u003e keys need to be stored securely as a secret.\n\n## Batched Atomic\n\nA set of APIs for dealing with the limitation of atomic commit sizes in Deno KV.\nDeno KV limits the number of checks and mutations as well as the overall byte\nsize of each commit and the byte size of the keys.\n\nThese limits are currently high for most workloads, but if you are dealing with\nlarge transactions where if you need to perform more than 100 checks, 1000\nmutations, using over 80k of key sizes or have an overall payload of over 800k,\nthen `batchedAtomic()` will avoid the transaction throwing by breaking up the\ntransaction into as many separate commits as necessary.\n\n### `batchedAtomic()`\n\nSimilar to `Deno.Kv#atomic()`, but will batch individual transactions across as\nmany atomic operations as necessary.\n\nThere are three additional methods supported on batched atomics not supported by\nDeno KV atomic transactions:\n\n- `.checkBlob({ key, versionstamp })` - Allows performing checks on blob entries\n  previously set with blob's `set()` function or via `.setBlob()` as part of a\n  transaction.\n\n- `.setBlob(key, value, options?)` - Allows setting of arbitrarily size blob\n  values as part of an atomic transaction. The values can be a byte\n  `ReadableStream`, array buffer like, a `Blob` or a `File`. It will work around\n  the constraints of Deno KV value sizes by splitting the value across multiple\n  keys.\n\n- `.deleteBlob(key)` - Allows deletion of all parts of a blob value as part of\n  an atomic transaction.\n\nThe `commit()` method will return a promise which resolves with an array of\nresults based on how many batches the operations was broken up into.\n\n## Blob\n\nA set of APIs for storing arbitrarily sized blobs in Deno KV. Currently Deno KV\nhas a limit of key values being 64k. The `set()` function breaks down a blob\ninto chunks and manages sub-keys to store the complete value. The `get()`,\n`getAsBlob()` and `getAsStream()` functions reverse that process, and `remove()`\nwill delete the key, sub-keys and values.\n\n### `set()`\n\nSimilar to `Deno.Kv.prototype.set()`, in that it stores a blob value with an\nassociated key. In order to deal with the size limitations of values, `set()`\nwill transparently chunk up the blob into parts that can be handled by Deno KV.\n\nThe blob can be a byte `ReadableStream`, array buffer like, a `Blob` or a\n`File`.\n\nWhen the value is being set is a `Blob` or `File` the meta data will also be\npreserved (like the `type` property).\n\nThe resolved `Deno.KvCommitResult` will contain the `versionstamp` of the blob's\nmeta data, which can be used for consistency checks.\n\n### `get()`\n\nSimilar to `Deno.Kv.prototype.get()`, in that it retrieves a blob entry based on\nthe provided key. If a previous blob value has been set with `set()`, it will be\nretrieved.\n\nBy default the value of the entry is resolved as a `Uint8Array` but if the\noption `stream` is set to `true`, then a byte `ReadableStream` is provided to\nread out the blob. If the option `blob` is set to `true`, then a `Blob` or\n`File` will be the value of the entry. If the value originally set was a `File`\nor `Blob` the resolved value instance will be that of the original value\nincluding restoring the additional properties, like `type`. If the value wasn't\na `Blob` or `File` originally, the function will resolve to a `Blob` with an\nempty `type`.\n\n### `getAsBlob()`\n\nRetrieves a blob value based on the provided key and resolves with a `Blob` or\n`File`. If the value originally set was a `File` or `Blob` the resolved instance\nwill be that of the original value including restoring the additional\nproperties, like `type`. If the value wasn't a `Blob` or `File` originally, the\nfunction will resolve to a `Blob` with an empty `type`.\n\n### `getAsJSON()`\n\nRetrieve a blob value based on the provided key and resolve with its JSON\nrepresentation.\n\n### `getAsResponse()`\n\nRetrieve a blob entry as a `Response` which will stream the value from the store\nto a client. If the entry does not exist, the response will be a\n`404 Not Found`. There are several options to configure how the response is set.\n\n### `getAsStream()`\n\nRetrieves a blob value based on the provided key and returns a byte\n`ReadableStream` which the binary data can be read from. If there is no value\npresent, the stream will be empty.\n\n### `getMeta()`\n\nRetrieves the meta data entry of a blob value based on the key provided. The\nentries `versionstamp` is considered the version of the blob.\n\n### `remove()`\n\nSimilar to `Deno.Kv.prototype.delete()`, in that it deletes a blob key and value\nform the data store. If a blob value isn't stored for the given key, it resolves\nin a noop.\n\n### `toBlob()`\n\nA convenience function which takes a string value, and optional media type, and\nconverts it into a `Blob` which then can be stored via `set()`.\n\n### `toJSON()`\n\nConvert an array buffer, typed array, `Blob` or `File` to a format which can be\nstringified into a JSON string.\n\n### `toValue()`\n\nConvert a JSON representation of a blob back into a value. Depending on what\nkind of value the JSON represents, either a `Uint8Array`, `Blob` or `File` is\nreturned.\n\n## Crypto\n\nAPIs which allow you to encrypt and decrypt values within a Deno KV datastore.\n\n### `generateKey()`\n\nGenerate a random crypto key which can be used with `CryptoKv`. The value\nreturned will be a hex encoded string. It defaults to 256 bits long. A value of\n128, 192, 256 bits can be supplied as an argument to the function to change the\nkey length.\n\n### `openCryptoKv()`\n\nLike `Deno.openKv()` but returns an instance of `CryptoKv`. `encryptWith`\nargument needs to be supplied, which is either a hex encoded string or\n`Uint8Array` that is 128, 192, 256 bits in length or an object which conforms to\nthe `Encryptor` interface. The `path` option works just like `path` option for\n`Deno.openKv()`.\n\n### `CryptoKv`\n\nA class which currently provides the ability to set, get and delete encrypted\nblob values. If created directly, an instance of `Deno.Kv` needs to be passed to\nthe constructor along with a value for `encryptWith`.\n\nWhen a key is supplied,\n\n### `Encryptor`\n\nAn interface which specifies two methods of `encrypt()` and `decrypt()` which\nwill be used for encrypting and decrypting values. This can be used to provide\nalternative\n\n## NDJSON\n\n\u003e [!IMPORTANT]\n\u003e The ability to import and export NDJSON has been contributed to\n\u003e [@deno/kv-utils](https://jsr.io/@deno/kv-utils/) and will be maintained there.\n\u003e The toolbox includes this capability, but this package does not contain the\n\u003e utilities anymore.\n\n## Keys\n\nAPIs for dealing with Deno KV keys.\n\n### `equals()`\n\nCompares the equality of two `Deno.KvKey`s, returning `true` if they are equal\nand `false` if they are not. This is more specialized than other forms of deeply\nequal comparison.\n\n### `partEquals()`\n\nCompares the equality of two `Deno.KvKeyPart`s, returning `true` if they are\nequal and `false` if they are not. This is more specialized than other forms of\nequality comparison.\n\n### `startsWith()`\n\nDetermines if the `key` starts with the `prefix` provided, returning `true` if\nit does, otherwise `false`.\n\n### `keys()`\n\nSimilar to `Deno.Kv.prototype.list()`, in that is takes a selector, but instead\nof returning an async iterator of matched values, it resolves with an array of\nmatching keys.\n\n### `tree()`\n\nThis resolves with the key parts in an tree like structure, where each branch of\nthe tree contains the children indexed by key part. The interface of the\nresolved value is:\n\n```ts\ninterface KeyTreeNode {\n  part: Deno.KvKeyPart;\n  children?: KeyTreeNode[];\n}\n\ninterface KeyTree {\n  prefix: Deno.KvKey;\n  children?: KeyTreeNode[];\n}\n```\n\n### `unique()`\n\nResolves with an array of unique sub keys/prefixes for the provided prefix.\n\nThis is useful when storing keys and values in a hierarchical/tree view, where\nyou are retrieving a list and you want to know all the unique _descendants_ of a\nkey in order to be able to enumerate them.\n\n### `uniqueCount()`\n\nResolves with an array of values which contain the unique sub keys/prefixes for\nthe provided prefix along with a count of how many keys there are.\n\nThis is useful when storing keys and values in a hierarchical/tree view, where\nyou are retrieving a list and you want to know all the unique _descendants_ of a\nkey (and the count of keys that match that prefix) in order to be able to\nenumerate them or provide information about them.\n\n## Querying\n\n### `query()`\n\nCreates a `Query` instance which can be used to filter a list of entries from a\nstore.\n\n### `PropertyPath`\n\nAn encapsulation of a property name with multiple parts. For example to\nreference property `c` in the following object:\n\n```ts\n{\n  a: {\n    b: {\n      c: 1;\n    }\n  }\n}\n```\n\nYou would create a property path like:\n\n```ts\nimport { PropertyPath } from \"@kitsonk/kv-toolbox/query\";\n\nconst propertyPath = new PropertyPath(\"a\", \"b\", \"c\");\n```\n\n### `Filter`\n\nThe encapsulation of a condition which is used to filter values from a Deno KV\nstore. Users should utilize the static methods to create instances of a filter.\nCurrent static methods are:\n\n- `.and(...filters)` - ensures that all filters passed are `true` to be included\n  in the results.\n- `.or(...filters)` - ensures that any one of the filters passed are `true` to\n  be included in the results.\n- `.value(operation, value)` - validates that value of the entry meets the\n  condition.\n- `.where(property, operations, value)` - validates that a property of the value\n  of the entry meets the condition.\n\n\u003e [!NOTE]\n\u003e Parts of `kv-toolbox` have been contributed to\n\u003e [`@deno/kv-utils`](https://jsr.io/@deno/kv-utils). This includes the JSON\n\u003e serialization library and the ability to estimate the size of keys and values\n\u003e when stored in Deno KV. This package now leverages that package and the\n\u003e functionality no longer is contained within `kv-toolbox`.\n\n---\n\nCopyright 2023 - 2024 Kitson P. Kelly - All rights reserved.\n\nMIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkitsonk%2Fkv-toolbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkitsonk%2Fkv-toolbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkitsonk%2Fkv-toolbox/lists"}