fastkv 1.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,13 +6,12 @@
6
6
 
7
7
  FastKV is a key-value store which offers the following features:
8
8
 
9
- - Supports temporary in-memory storage 🕒
10
- - Supports persistent storage with JSON files 📁
11
- - Lightweight with no dependencies ⚡
9
+ - Supports storage in memory and in JSON files
10
+ - Lightweight with zero dependencies
12
11
 
13
12
  ## Installation
14
13
 
15
- Get FastKV via npm using your favourite package manager:
14
+ Get FastKV via your package manager.
16
15
 
17
16
  ```sh
18
17
  npm install fastkv
@@ -20,29 +19,47 @@ npm install fastkv
20
19
  yarn add fastkv
21
20
  # or
22
21
  pnpm add fastkv
22
+ # or
23
+ bun add fastkv
23
24
  ```
24
25
 
25
26
  ## Example
26
27
 
27
- ```js
28
- import { KV } from 'fastkv';
28
+ ```ts
29
+ import { KV } from "fastkv";
30
+
31
+ // Type safety (optional; for TypeScript)
32
+ interface User {
33
+ name: string;
34
+ age?: number;
35
+ settings?: { theme: string };
36
+ }
37
+
38
+ const kv = new KV<User>({ path: "./db.json" }); // Persistent storage
39
+ const cache = new KV<User>(); // In-memory store (no path provided)
40
+
41
+ // Set or overwrite data
42
+ await kv.set("user1", { name: "Alice", age: 25 });
29
43
 
30
- // For TypeScript users, the KV supports generics:
31
- // const example = new KV<string>();
32
- // Or: example.get<string>('my-key-name');
44
+ // Get data by key
45
+ const user = await kv.get("user1"); // -> { __id: ..., key: 'user1', value: { name: 'Alice', age: 25 } }
33
46
 
34
- const kv = new KV('./db.json'); // Save the data. Path resolves with process.cwd()
35
- const cache = new KV('::memory::'); // Keep the data in the system's memory.
47
+ // Get nested values
48
+ const theme = await kv.get("user1.settings.theme"); // -> 'dark'
36
49
 
37
- // Set data
38
- kv.set('userSettings', { theme: 'dark' }); // -> KV
50
+ // Upsert (update or create)
51
+ await kv.upsert({
52
+ where: { name: "Alice" }, // filter
53
+ create: { name: "Alice", age: 25, settings: { theme: "dark" } }, // if not exists
54
+ update: { age: 26 }, // partial update if exists
55
+ });
39
56
 
40
- // Retreive data by a key
41
- kv.get('userSettings'); // -> { theme: 'dark' }
57
+ // Find entries by key or value
58
+ const usersNamedAlice = await kv.find({ where: "Alice", in: "value" });
42
59
 
43
- // Retreive all data
44
- kv.all(); // -> [{ key: 'userSettings', value: { theme: 'dark' } }]
60
+ // Get all entries
61
+ const allEntries = await kv.all();
45
62
 
46
- // Clear the store
47
- kv.clear(); // -> KV
63
+ // Clear all entries
64
+ await kv.clear();
48
65
  ```
package/dist/index.d.mts CHANGED
@@ -1,43 +1,32 @@
1
- type Entry<T> = {
1
+ interface KVOptions {
2
+ path?: string;
3
+ prettify?: boolean;
4
+ }
5
+ type Entry<T = any> = {
6
+ __id: string;
2
7
  key: string;
3
8
  value: T;
4
9
  };
5
- /**
6
- * Represents a key-value store.
7
- * Initializing with `::memory::` uses in-memory storage.
8
- */
10
+ type DeepPartial<T> = {
11
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
12
+ };
9
13
  declare class KV<T = any> {
10
14
  #private;
11
- /**
12
- * Creates a new instance of the class.
13
- * @param location - Where the data will be stored.
14
- * Can be `::memory::` or a file location.
15
- */
16
- constructor(location?: string);
17
- /**
18
- * Sets a value to a key.
19
- * @param key - The name of the key.
20
- * @param value - The value to store.
21
- * @returns The value.
22
- */
23
- set(key: string, value: T): T;
24
- /**
25
- * Gets data by a key.
26
- * @param key - The existing key's name.
27
- * @returns The found data, or null.
28
- */
29
- get<U = T>(key: string): U | null;
30
- /**
31
- * Gets all data in the store.
32
- * @returns An array of Entry objects [{ key: string, value: T }].
33
- */
34
- all(): Entry<T>[];
35
- /**
36
- * Clears all data in the store.
37
- * @returns The KV instance.
38
- */
39
- clear(): this;
15
+ path?: string;
16
+ constructor(options?: KVOptions);
17
+ set(key: string, value: T): Promise<Entry<T>>;
18
+ upsert(options: {
19
+ where: DeepPartial<T> | string;
20
+ create?: DeepPartial<T>;
21
+ update?: DeepPartial<T>;
22
+ }): Promise<Entry<T>>;
23
+ find(options: {
24
+ in?: "key" | "value";
25
+ where: T | string | number | boolean;
26
+ }): Promise<Entry<T>[]>;
27
+ get(query: string): Promise<Entry<T> | T | null>;
28
+ all(): Promise<Entry<T>[]>;
29
+ clear(): Promise<void>;
40
30
  }
41
- declare const _default: KV<any>;
42
31
 
43
- export { KV, _default as default };
32
+ export { KV, KV as default };
package/dist/index.d.ts CHANGED
@@ -1,43 +1,32 @@
1
- type Entry<T> = {
1
+ interface KVOptions {
2
+ path?: string;
3
+ prettify?: boolean;
4
+ }
5
+ type Entry<T = any> = {
6
+ __id: string;
2
7
  key: string;
3
8
  value: T;
4
9
  };
5
- /**
6
- * Represents a key-value store.
7
- * Initializing with `::memory::` uses in-memory storage.
8
- */
10
+ type DeepPartial<T> = {
11
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
12
+ };
9
13
  declare class KV<T = any> {
10
14
  #private;
11
- /**
12
- * Creates a new instance of the class.
13
- * @param location - Where the data will be stored.
14
- * Can be `::memory::` or a file location.
15
- */
16
- constructor(location?: string);
17
- /**
18
- * Sets a value to a key.
19
- * @param key - The name of the key.
20
- * @param value - The value to store.
21
- * @returns The value.
22
- */
23
- set(key: string, value: T): T;
24
- /**
25
- * Gets data by a key.
26
- * @param key - The existing key's name.
27
- * @returns The found data, or null.
28
- */
29
- get<U = T>(key: string): U | null;
30
- /**
31
- * Gets all data in the store.
32
- * @returns An array of Entry objects [{ key: string, value: T }].
33
- */
34
- all(): Entry<T>[];
35
- /**
36
- * Clears all data in the store.
37
- * @returns The KV instance.
38
- */
39
- clear(): this;
15
+ path?: string;
16
+ constructor(options?: KVOptions);
17
+ set(key: string, value: T): Promise<Entry<T>>;
18
+ upsert(options: {
19
+ where: DeepPartial<T> | string;
20
+ create?: DeepPartial<T>;
21
+ update?: DeepPartial<T>;
22
+ }): Promise<Entry<T>>;
23
+ find(options: {
24
+ in?: "key" | "value";
25
+ where: T | string | number | boolean;
26
+ }): Promise<Entry<T>[]>;
27
+ get(query: string): Promise<Entry<T> | T | null>;
28
+ all(): Promise<Entry<T>[]>;
29
+ clear(): Promise<void>;
40
30
  }
41
- declare const _default: KV<any>;
42
31
 
43
- export { KV, _default as default };
32
+ export { KV, KV as default };
package/dist/index.js CHANGED
@@ -1 +1,218 @@
1
- "use strict";var l=Object.create;var e=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var y=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var d=(r,t)=>{for(var i in t)e(r,i,{get:t[i],enumerable:!0})},c=(r,t,i,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of m(t))!f.call(r,s)&&s!==i&&e(r,s,{get:()=>t[s],enumerable:!(o=p(t,s))||o.enumerable});return r};var u=(r,t,i)=>(i=r!=null?l(y(r)):{},c(t||!r||!r.__esModule?e(i,"default",{value:r,enumerable:!0}):i,r)),g=r=>c(e({},"__esModule",{value:!0}),r);var b={};d(b,{KV:()=>n,default:()=>T});module.exports=g(b);var h=u(require("fs")),a=u(require("path")),n=class{#t;#r;constructor(t="::memory::"){this.#t=t,this.#r={},t!=="::memory::"&&(this.#t=a.default.resolve(process.cwd(),this.#t),this.#r=this.#s())}#s(){if(this.#t==="::memory::")return{};try{let t=h.default.readFileSync(this.#t,"utf8");return JSON.parse(t)||{}}catch{return{}}}#i(){this.#t!=="::memory::"&&h.default.writeFileSync(this.#t,JSON.stringify(this.#r),"utf8")}set(t,i){return this.#r[t]=i,this.#i(),i}get(t){return this.#r[t]??null}all(){return Object.entries(this.#r).map(([t,i])=>({key:t,value:i}))}clear(){return this.#r={},this.#i(),this}},T=new n;0&&(module.exports={KV});
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ KV: () => KV,
34
+ default: () => index_default
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+ var import_node_crypto = require("crypto");
38
+ var import_node_path = __toESM(require("path"));
39
+ var import_promises = __toESM(require("fs/promises"));
40
+ var KV = class {
41
+ path;
42
+ #data = [];
43
+ #ready;
44
+ #prettify;
45
+ /**
46
+ * Create a new KV instance
47
+ * @param options Configuration options
48
+ */
49
+ constructor(options) {
50
+ if (options?.prettify) {
51
+ this.#prettify = options?.prettify;
52
+ } else {
53
+ this.#prettify = false;
54
+ }
55
+ if (options?.path) {
56
+ this.path = import_node_path.default.resolve(process.cwd(), options.path);
57
+ this.#ready = this.#loadFromFile();
58
+ } else {
59
+ this.#ready = Promise.resolve();
60
+ }
61
+ }
62
+ /**
63
+ * Load stored data from disk into memory, create a new empty store if file doesn't exist
64
+ */
65
+ async #loadFromFile() {
66
+ try {
67
+ const content = await import_promises.default.readFile(this.path, "utf8");
68
+ this.#data = JSON.parse(content);
69
+ } catch (error) {
70
+ if (error.code === "ENOENT") {
71
+ this.#data = [];
72
+ await this.#saveToFile();
73
+ } else {
74
+ throw new Error("Failed to load database file: " + error.message);
75
+ }
76
+ }
77
+ }
78
+ /**
79
+ * Save in-memory data to disk if file path is provided
80
+ */
81
+ async #saveToFile() {
82
+ if (!this.path) return;
83
+ await import_promises.default.writeFile(
84
+ this.path,
85
+ JSON.stringify(this.#data, null, this.#prettify ? 2 : 0),
86
+ "utf8"
87
+ );
88
+ }
89
+ /**
90
+ * Resolves dot-notation paths within objects
91
+ * @param object Base object
92
+ * @param path Dot-separated path string
93
+ * @returns Resolved value, or undefined
94
+ */
95
+ #resolvePath(object, path2) {
96
+ return path2.split(".").reduce((acc, part) => acc ? acc[part] : void 0, object);
97
+ }
98
+ /**
99
+ * Compare a value against a partial filter object
100
+ * @param value Actual stored value
101
+ * @param where Partial value to match against
102
+ * @returns
103
+ */
104
+ #matches(value, where) {
105
+ if (where === null) return value === null;
106
+ if (typeof value !== typeof where) return false;
107
+ if (typeof value === "object" && value !== null && where !== null) {
108
+ return Object.entries(where).every(([k, v]) => this.#matches(value[k], v));
109
+ }
110
+ return value === where;
111
+ }
112
+ /**
113
+ * Set a value by key, creates a new entry or overrides existing one
114
+ * @param key Unique identifier
115
+ * @param value Data to store
116
+ * @returns
117
+ */
118
+ async set(key, value) {
119
+ if (!key) throw new Error("Key cannot be empty");
120
+ await this.#ready;
121
+ const entry = this.#data.find((entry2) => entry2.key === key);
122
+ if (entry) {
123
+ entry.value = value;
124
+ await this.#saveToFile();
125
+ return entry;
126
+ }
127
+ const newEntry = { __id: (0, import_node_crypto.randomUUID)(), key, value };
128
+ this.#data.push(newEntry);
129
+ await this.#saveToFile();
130
+ return newEntry;
131
+ }
132
+ /**
133
+ * Update an existing entry or create a new one if not found
134
+ * @param options Upserting options
135
+ */
136
+ async upsert(options) {
137
+ if (!options.create && !options.update) {
138
+ throw new Error("Upsert requires at least create or update to be provided");
139
+ }
140
+ if (typeof options.where === "string" && !options.where) {
141
+ throw new Error("Upsert key cannot be empty");
142
+ }
143
+ await this.#ready;
144
+ let entry;
145
+ if (typeof options.where === "string") {
146
+ entry = this.#data.find((entry2) => entry2.key === options.where);
147
+ } else {
148
+ entry = this.#data.find((entry2) => this.#matches(entry2.value, options.where));
149
+ }
150
+ if (entry) {
151
+ if (options.update) {
152
+ entry.value = { ...entry.value, ...options.update };
153
+ }
154
+ } else {
155
+ const key = typeof options.where === "string" ? options.where : (0, import_node_crypto.randomUUID)();
156
+ const baseValue = options.create ?? options.update ?? {};
157
+ entry = {
158
+ __id: (0, import_node_crypto.randomUUID)(),
159
+ key,
160
+ value: { ...baseValue }
161
+ };
162
+ this.#data.push(entry);
163
+ }
164
+ await this.#saveToFile();
165
+ return entry;
166
+ }
167
+ /**
168
+ * Find entries by matching key or value
169
+ * @param options Search options
170
+ */
171
+ async find(options) {
172
+ if (options.in && options.in !== "key" && options.in !== "value") {
173
+ throw new Error(`Invalid search field: ${options.in}`);
174
+ }
175
+ await this.#ready;
176
+ const field = options.in ?? "value";
177
+ const where = options.where;
178
+ return this.#data.filter((entry) => {
179
+ if (field === "key") {
180
+ return typeof where === "string" && entry.key.includes(where);
181
+ }
182
+ return this.#matches(entry.value, where);
183
+ });
184
+ }
185
+ /**
186
+ * Get an entry, supports nested values with dot notation
187
+ * @param query Key or path via dot notation
188
+ */
189
+ async get(query) {
190
+ if (!query) throw new Error("Query string cannot be empty");
191
+ await this.#ready;
192
+ const [baseKey, ...rest] = query.split(".");
193
+ const entry = this.#data.find((entry2) => entry2.key === baseKey);
194
+ if (!entry) return null;
195
+ if (rest.length === 0) return entry;
196
+ return this.#resolvePath({ value: entry.value }, rest.join(".")) ?? null;
197
+ }
198
+ /**
199
+ * Get all stored entries
200
+ */
201
+ async all() {
202
+ await this.#ready;
203
+ return [...this.#data];
204
+ }
205
+ /**
206
+ * Remove all entries
207
+ */
208
+ async clear() {
209
+ await this.#ready;
210
+ this.#data = [];
211
+ await this.#saveToFile();
212
+ }
213
+ };
214
+ var index_default = KV;
215
+ // Annotate the CommonJS export names for ESM import in node:
216
+ 0 && (module.exports = {
217
+ KV
218
+ });
package/dist/index.mjs CHANGED
@@ -1 +1,183 @@
1
- import s from"node:fs";import e from"node:path";var i=class{#t;#r;constructor(t="::memory::"){this.#t=t,this.#r={},t!=="::memory::"&&(this.#t=e.resolve(process.cwd(),this.#t),this.#r=this.#s())}#s(){if(this.#t==="::memory::")return{};try{let t=s.readFileSync(this.#t,"utf8");return JSON.parse(t)||{}}catch{return{}}}#i(){this.#t!=="::memory::"&&s.writeFileSync(this.#t,JSON.stringify(this.#r),"utf8")}set(t,r){return this.#r[t]=r,this.#i(),r}get(t){return this.#r[t]??null}all(){return Object.entries(this.#r).map(([t,r])=>({key:t,value:r}))}clear(){return this.#r={},this.#i(),this}},a=new i;export{i as KV,a as default};
1
+ // src/index.ts
2
+ import { randomUUID } from "crypto";
3
+ import path from "path";
4
+ import fs from "fs/promises";
5
+ var KV = class {
6
+ path;
7
+ #data = [];
8
+ #ready;
9
+ #prettify;
10
+ /**
11
+ * Create a new KV instance
12
+ * @param options Configuration options
13
+ */
14
+ constructor(options) {
15
+ if (options?.prettify) {
16
+ this.#prettify = options?.prettify;
17
+ } else {
18
+ this.#prettify = false;
19
+ }
20
+ if (options?.path) {
21
+ this.path = path.resolve(process.cwd(), options.path);
22
+ this.#ready = this.#loadFromFile();
23
+ } else {
24
+ this.#ready = Promise.resolve();
25
+ }
26
+ }
27
+ /**
28
+ * Load stored data from disk into memory, create a new empty store if file doesn't exist
29
+ */
30
+ async #loadFromFile() {
31
+ try {
32
+ const content = await fs.readFile(this.path, "utf8");
33
+ this.#data = JSON.parse(content);
34
+ } catch (error) {
35
+ if (error.code === "ENOENT") {
36
+ this.#data = [];
37
+ await this.#saveToFile();
38
+ } else {
39
+ throw new Error("Failed to load database file: " + error.message);
40
+ }
41
+ }
42
+ }
43
+ /**
44
+ * Save in-memory data to disk if file path is provided
45
+ */
46
+ async #saveToFile() {
47
+ if (!this.path) return;
48
+ await fs.writeFile(
49
+ this.path,
50
+ JSON.stringify(this.#data, null, this.#prettify ? 2 : 0),
51
+ "utf8"
52
+ );
53
+ }
54
+ /**
55
+ * Resolves dot-notation paths within objects
56
+ * @param object Base object
57
+ * @param path Dot-separated path string
58
+ * @returns Resolved value, or undefined
59
+ */
60
+ #resolvePath(object, path2) {
61
+ return path2.split(".").reduce((acc, part) => acc ? acc[part] : void 0, object);
62
+ }
63
+ /**
64
+ * Compare a value against a partial filter object
65
+ * @param value Actual stored value
66
+ * @param where Partial value to match against
67
+ * @returns
68
+ */
69
+ #matches(value, where) {
70
+ if (where === null) return value === null;
71
+ if (typeof value !== typeof where) return false;
72
+ if (typeof value === "object" && value !== null && where !== null) {
73
+ return Object.entries(where).every(([k, v]) => this.#matches(value[k], v));
74
+ }
75
+ return value === where;
76
+ }
77
+ /**
78
+ * Set a value by key, creates a new entry or overrides existing one
79
+ * @param key Unique identifier
80
+ * @param value Data to store
81
+ * @returns
82
+ */
83
+ async set(key, value) {
84
+ if (!key) throw new Error("Key cannot be empty");
85
+ await this.#ready;
86
+ const entry = this.#data.find((entry2) => entry2.key === key);
87
+ if (entry) {
88
+ entry.value = value;
89
+ await this.#saveToFile();
90
+ return entry;
91
+ }
92
+ const newEntry = { __id: randomUUID(), key, value };
93
+ this.#data.push(newEntry);
94
+ await this.#saveToFile();
95
+ return newEntry;
96
+ }
97
+ /**
98
+ * Update an existing entry or create a new one if not found
99
+ * @param options Upserting options
100
+ */
101
+ async upsert(options) {
102
+ if (!options.create && !options.update) {
103
+ throw new Error("Upsert requires at least create or update to be provided");
104
+ }
105
+ if (typeof options.where === "string" && !options.where) {
106
+ throw new Error("Upsert key cannot be empty");
107
+ }
108
+ await this.#ready;
109
+ let entry;
110
+ if (typeof options.where === "string") {
111
+ entry = this.#data.find((entry2) => entry2.key === options.where);
112
+ } else {
113
+ entry = this.#data.find((entry2) => this.#matches(entry2.value, options.where));
114
+ }
115
+ if (entry) {
116
+ if (options.update) {
117
+ entry.value = { ...entry.value, ...options.update };
118
+ }
119
+ } else {
120
+ const key = typeof options.where === "string" ? options.where : randomUUID();
121
+ const baseValue = options.create ?? options.update ?? {};
122
+ entry = {
123
+ __id: randomUUID(),
124
+ key,
125
+ value: { ...baseValue }
126
+ };
127
+ this.#data.push(entry);
128
+ }
129
+ await this.#saveToFile();
130
+ return entry;
131
+ }
132
+ /**
133
+ * Find entries by matching key or value
134
+ * @param options Search options
135
+ */
136
+ async find(options) {
137
+ if (options.in && options.in !== "key" && options.in !== "value") {
138
+ throw new Error(`Invalid search field: ${options.in}`);
139
+ }
140
+ await this.#ready;
141
+ const field = options.in ?? "value";
142
+ const where = options.where;
143
+ return this.#data.filter((entry) => {
144
+ if (field === "key") {
145
+ return typeof where === "string" && entry.key.includes(where);
146
+ }
147
+ return this.#matches(entry.value, where);
148
+ });
149
+ }
150
+ /**
151
+ * Get an entry, supports nested values with dot notation
152
+ * @param query Key or path via dot notation
153
+ */
154
+ async get(query) {
155
+ if (!query) throw new Error("Query string cannot be empty");
156
+ await this.#ready;
157
+ const [baseKey, ...rest] = query.split(".");
158
+ const entry = this.#data.find((entry2) => entry2.key === baseKey);
159
+ if (!entry) return null;
160
+ if (rest.length === 0) return entry;
161
+ return this.#resolvePath({ value: entry.value }, rest.join(".")) ?? null;
162
+ }
163
+ /**
164
+ * Get all stored entries
165
+ */
166
+ async all() {
167
+ await this.#ready;
168
+ return [...this.#data];
169
+ }
170
+ /**
171
+ * Remove all entries
172
+ */
173
+ async clear() {
174
+ await this.#ready;
175
+ this.#data = [];
176
+ await this.#saveToFile();
177
+ }
178
+ };
179
+ var index_default = KV;
180
+ export {
181
+ KV,
182
+ index_default as default
183
+ };
package/package.json CHANGED
@@ -1,11 +1,18 @@
1
1
  {
2
2
  "name": "fastkv",
3
- "version": "1.0.0",
3
+ "version": "2.0.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "description": "A key-value store, helpful for caches in apps.",
8
- "main": "dist/index.js",
7
+ "files": [
8
+ "dist",
9
+ "package.json",
10
+ "README.md"
11
+ ],
12
+ "description": "A simple key-value store with optional JSON file storing",
13
+ "main": "./dist/index.js",
14
+ "module": "./dist/index.mjs",
15
+ "types": "./dist/index.d.ts",
9
16
  "repository": {
10
17
  "url": "https://github.com/m1-dev/fastkv"
11
18
  },
@@ -14,16 +21,29 @@
14
21
  "database",
15
22
  "json"
16
23
  ],
24
+ "prettier": {
25
+ "tabWidth": 4,
26
+ "printWidth": 95,
27
+ "arrowParens": "always",
28
+ "trailingComma": "es5",
29
+ "singleQuote": false,
30
+ "jsxSingleQuote": false,
31
+ "useTabs": false,
32
+ "semi": true
33
+ },
17
34
  "license": "MIT",
18
35
  "devDependencies": {
19
- "@types/node": "^20.10.5",
20
- "@underctrl/tsconfig": "^0.0.1",
36
+ "@types/node": "^20.11.16",
37
+ "prettier": "^3.2.5",
21
38
  "tsup": "^8.0.1",
22
39
  "typescript": "^5.3.3"
23
40
  },
24
41
  "scripts": {
25
42
  "build": "tsup",
26
- "lint": "tsc --noEmit true",
27
- "prepublish": "pnpm run build"
43
+ "lint": "tsc --noEmit; prettier . --check --ignore-path=.prettierignore",
44
+ "prepublish": "pnpm run build",
45
+ "format": "prettier . --write --ignore-path=.prettierignore",
46
+ "deploy:fastkv:beta": "pnpm publish --no-git-checks --access public --tag beta",
47
+ "deploy:fastkv:stable": "pnpm publish --no-git-checks --access public"
28
48
  }
29
49
  }