litle-indexeddb 0.0.0-stage → 1.0.0

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.
@@ -0,0 +1,69 @@
1
+ export interface EncryptedPayload {
2
+ iv: Uint8Array;
3
+ ciphertext: Uint8Array;
4
+ }
5
+ export interface StoredEntry<T = unknown> {
6
+ key: IDBValidKey;
7
+ value: T;
8
+ }
9
+ /**
10
+ * Basically IndexedDB with built-in AES-GCM encryption.
11
+ */
12
+ export default class LittleIndexedDB {
13
+ readonly dbName: string;
14
+ readonly storeName: string;
15
+ readonly version: number;
16
+ private db;
17
+ private cryptoKey;
18
+ /**
19
+ * @param dbName Database name.
20
+ * @param storeName Primary object store name.
21
+ * @param version Database schema version. Defaults to 1.
22
+ */
23
+ constructor(dbName: string, storeName: string, version?: number);
24
+ /**
25
+ * Derives an AES-GCM-256 key from a passphrase and a salt using PBKDF2.
26
+ */
27
+ private _deriveKey;
28
+ /**
29
+ * Encrypts any JSON serializable val ue.
30
+ */
31
+ private _encrypt;
32
+ /**
33
+ * Decrypts an encrypted payload back into its original parsed data structure.
34
+ */
35
+ private _decrypt;
36
+ /**
37
+ * Reads or creates the database PBKDF2 salt in the `__meta__` store.
38
+ */
39
+ private _getOrCreateSalt;
40
+ /**
41
+ * Initializes the IndexedDB instance, sets up metadata tables, and derives the session key.
42
+ * @param passphrase Passphrase used to derive encryption keys.
43
+ */
44
+ init(passphrase: string): Promise<this>;
45
+ /**
46
+ * Encrypts and persists a value by key.
47
+ */
48
+ setItem<T>(key: IDBValidKey, value: T): Promise<boolean>;
49
+ /**
50
+ * Retrieves and decrypts a value by key. Returns `null` if not found.
51
+ */
52
+ getItem<T>(key: IDBValidKey): Promise<T | null>;
53
+ /**
54
+ * Deletes an item by key.
55
+ */
56
+ removeItem(key: IDBValidKey): Promise<boolean>;
57
+ /**
58
+ * Clears all encrypted entries in the current object store.
59
+ */
60
+ clear(): Promise<boolean>;
61
+ /**
62
+ * Iterates through the store, decrypting and returning all key-value entries.
63
+ */
64
+ getAll<T>(): Promise<StoredEntry<T>[]>;
65
+ /**
66
+ * Closes the active database connection.
67
+ */
68
+ close(): void;
69
+ }
@@ -0,0 +1,169 @@
1
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/typeof.js
2
+ function e(t) {
3
+ "@babel/helpers - typeof";
4
+ return e = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(e) {
5
+ return typeof e;
6
+ } : function(e) {
7
+ return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
8
+ }, e(t);
9
+ }
10
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/toPrimitive.js
11
+ function t(t, n) {
12
+ if (e(t) != "object" || !t) return t;
13
+ var r = t[Symbol.toPrimitive];
14
+ if (r !== void 0) {
15
+ var i = r.call(t, n || "default");
16
+ if (e(i) != "object") return i;
17
+ throw TypeError("@@toPrimitive must return a primitive value.");
18
+ }
19
+ return (n === "string" ? String : Number)(t);
20
+ }
21
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/toPropertyKey.js
22
+ function n(n) {
23
+ var r = t(n, "string");
24
+ return e(r) == "symbol" ? r : r + "";
25
+ }
26
+ // \0@oxc-project+runtime@0.156.0/helpers/esm/defineProperty.js
27
+ function r(e, t, r) {
28
+ return (t = n(t)) in e ? Object.defineProperty(e, t, {
29
+ value: r,
30
+ enumerable: !0,
31
+ configurable: !0,
32
+ writable: !0
33
+ }) : e[t] = r, e;
34
+ }
35
+ // src/index.ts
36
+ var i = class {
37
+ constructor(e, t, n = 1) {
38
+ r(this, "dbName", void 0), r(this, "storeName", void 0), r(this, "version", void 0), r(this, "db", null), r(this, "cryptoKey", null), this.dbName = e, this.storeName = t, this.version = n;
39
+ }
40
+ async _deriveKey(e, t) {
41
+ let n = new TextEncoder(), r = await crypto.subtle.importKey("raw", n.encode(e), { name: "PBKDF2" }, !1, ["deriveKey"]);
42
+ return crypto.subtle.deriveKey({
43
+ name: "PBKDF2",
44
+ salt: t,
45
+ iterations: 1e5,
46
+ hash: "SHA-256"
47
+ }, r, {
48
+ name: "AES-GCM",
49
+ length: 256
50
+ }, !1, ["encrypt", "decrypt"]);
51
+ }
52
+ async _encrypt(e) {
53
+ if (!this.cryptoKey) throw Error("Key not initialized. Call init() first.");
54
+ let t = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(12)), n = new TextEncoder().encode(JSON.stringify(e)), r = await crypto.subtle.encrypt({
55
+ name: "AES-GCM",
56
+ iv: t
57
+ }, this.cryptoKey, n);
58
+ return {
59
+ iv: t,
60
+ ciphertext: new Uint8Array(r)
61
+ };
62
+ }
63
+ async _decrypt(e) {
64
+ if (!this.cryptoKey) throw Error("Key not initialized. Call init() first.");
65
+ let t = await crypto.subtle.decrypt({
66
+ name: "AES-GCM",
67
+ iv: e.iv
68
+ }, this.cryptoKey, e.ciphertext), n = new TextDecoder().decode(t);
69
+ return JSON.parse(n);
70
+ }
71
+ async _getOrCreateSalt() {
72
+ if (!this.db) throw Error("Database not connected.");
73
+ return new Promise((e, t) => {
74
+ let n = this.db.transaction("__meta__", "readwrite").objectStore("__meta__"), r = n.get("db_salt");
75
+ r.onsuccess = () => {
76
+ let t = r.result;
77
+ if (t?.value) e(new Uint8Array(t.value));
78
+ else {
79
+ let t = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
80
+ n.put({
81
+ id: "db_salt",
82
+ value: t
83
+ }), e(t);
84
+ }
85
+ }, r.onerror = () => t(r.error);
86
+ });
87
+ }
88
+ async init(e) {
89
+ return new Promise((t, n) => {
90
+ let r = indexedDB.open(this.dbName, this.version);
91
+ r.onupgradeneeded = (e) => {
92
+ let t = e.target.result;
93
+ t.objectStoreNames.contains("__meta__") || t.createObjectStore("__meta__", { keyPath: "id" }), t.objectStoreNames.contains(this.storeName) || t.createObjectStore(this.storeName);
94
+ }, r.onsuccess = async (r) => {
95
+ this.db = r.target.result;
96
+ try {
97
+ let n = await this._getOrCreateSalt();
98
+ this.cryptoKey = await this._deriveKey(e, n), t(this);
99
+ } catch (e) {
100
+ n(e);
101
+ }
102
+ }, r.onerror = (e) => {
103
+ n(e.target.error);
104
+ };
105
+ });
106
+ }
107
+ async setItem(e, t) {
108
+ if (!this.db) throw Error("Database not initialized.");
109
+ let n = await this._encrypt(t);
110
+ return new Promise((t, r) => {
111
+ let i = this.db.transaction(this.storeName, "readwrite").objectStore(this.storeName).put(n, e);
112
+ i.onsuccess = () => t(!0), i.onerror = () => r(i.error);
113
+ });
114
+ }
115
+ async getItem(e) {
116
+ if (!this.db) throw Error("Database not initialized.");
117
+ return new Promise((t, n) => {
118
+ let r = this.db.transaction(this.storeName, "readonly").objectStore(this.storeName).get(e);
119
+ r.onsuccess = async () => {
120
+ if (!r.result) return t(null);
121
+ try {
122
+ t(await this._decrypt(r.result));
123
+ } catch {
124
+ n(/* @__PURE__ */ Error("Decryption failed. Invalid passphrase or corrupted data."));
125
+ }
126
+ }, r.onerror = () => n(r.error);
127
+ });
128
+ }
129
+ async removeItem(e) {
130
+ if (!this.db) throw Error("Database not initialized.");
131
+ return new Promise((t, n) => {
132
+ let r = this.db.transaction(this.storeName, "readwrite").objectStore(this.storeName).delete(e);
133
+ r.onsuccess = () => t(!0), r.onerror = () => n(r.error);
134
+ });
135
+ }
136
+ async clear() {
137
+ if (!this.db) throw Error("Database not initialized.");
138
+ return new Promise((e, t) => {
139
+ let n = this.db.transaction(this.storeName, "readwrite").objectStore(this.storeName).clear();
140
+ n.onsuccess = () => e(!0), n.onerror = () => t(n.error);
141
+ });
142
+ }
143
+ async getAll() {
144
+ if (!this.db) throw Error("Database not initialized.");
145
+ return new Promise((e, t) => {
146
+ let n = this.db.transaction(this.storeName, "readonly").objectStore(this.storeName).openCursor(), r = [];
147
+ n.onsuccess = async (n) => {
148
+ let i = n.target.result;
149
+ if (i) try {
150
+ let e = await this._decrypt(i.value);
151
+ r.push({
152
+ key: i.key,
153
+ value: e
154
+ }), i.continue();
155
+ } catch (e) {
156
+ let n = e instanceof Error ? e.message : String(e);
157
+ t(/* @__PURE__ */ Error(`Failed to decrypt record under key '${String(i.key)}': ${n}`));
158
+ }
159
+ else e(r);
160
+ }, n.onerror = () => t(n.error);
161
+ });
162
+ }
163
+ close() {
164
+ this.db && (this.db.close(), this.db = null, this.cryptoKey = null);
165
+ }
166
+ };
167
+ export { i as default };
168
+
169
+ //# sourceMappingURL=little-indexeddb.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"little-indexeddb.es.js","names":["_typeof","o","toPrimitive","e","r","toPropertyKey","i","t","_defineProperty","LittleIndexedDB","dbName","storeName","version","enc","keyMaterial","passphrase","iv","encodedData","data","ciphertextBuffer","decryptedBuffer","encryptedRecord","jsonString","store","req","record","newSalt","resolve","reject","request","db","event","salt","err","value","key","results","cursor","decryptedValue","msg"],"sources":["../src/index.ts"],"sourcesContent":["export interface EncryptedPayload {\r\n iv: Uint8Array;\r\n ciphertext: Uint8Array;\r\n}\r\n\r\nexport interface StoredEntry<T = unknown> {\r\n key: IDBValidKey;\r\n value: T;\r\n}\r\n\r\ninterface MetaRecord {\r\n id: string;\r\n value: Uint8Array;\r\n}\r\n\r\n/**\r\n * Basically IndexedDB with built-in AES-GCM encryption.\r\n */\r\nexport default class LittleIndexedDB {\r\n private db: IDBDatabase | null = null;\r\n private cryptoKey: CryptoKey | null = null;\r\n\r\n /**\r\n * @param dbName Database name.\r\n * @param storeName Primary object store name.\r\n * @param version Database schema version. Defaults to 1.\r\n */\r\n constructor(\r\n public readonly dbName: string,\r\n public readonly storeName: string,\r\n public readonly version: number = 1\r\n ) {}\r\n\r\n /**\r\n * Derives an AES-GCM-256 key from a passphrase and a salt using PBKDF2.\r\n */\r\n private async _deriveKey(passphrase: string, salt: Uint8Array): Promise<CryptoKey> {\r\n const enc = new TextEncoder();\r\n const keyMaterial = await crypto.subtle.importKey(\r\n \"raw\",\r\n enc.encode(passphrase),\r\n { name: \"PBKDF2\" },\r\n false,\r\n [\"deriveKey\"]\r\n );\r\n\r\n return crypto.subtle.deriveKey(\r\n {\r\n name: \"PBKDF2\",\r\n salt: salt as BufferSource,\r\n iterations: 100_000,\r\n hash: \"SHA-256\",\r\n },\r\n keyMaterial,\r\n { name: \"AES-GCM\", length: 256 },\r\n false,\r\n [\"encrypt\", \"decrypt\"]\r\n );\r\n }\r\n\r\n /**\r\n * Encrypts any JSON serializable val ue.\r\n */\r\n private async _encrypt<T>(data: T): Promise<EncryptedPayload> {\r\n if (!this.cryptoKey) throw new Error(\"Key not initialized. Call init() first.\");\r\n\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n const encodedData = new TextEncoder().encode(JSON.stringify(data));\r\n\r\n const ciphertextBuffer = await crypto.subtle.encrypt(\r\n { name: \"AES-GCM\", iv },\r\n this.cryptoKey,\r\n encodedData\r\n );\r\n\r\n return {\r\n iv,\r\n ciphertext: new Uint8Array(ciphertextBuffer),\r\n };\r\n }\r\n\r\n /**\r\n * Decrypts an encrypted payload back into its original parsed data structure.\r\n */\r\n private async _decrypt<T>(encryptedRecord: EncryptedPayload): Promise<T> {\r\n if (!this.cryptoKey) throw new Error(\"Key not initialized. Call init() first.\");\r\n\r\n const decryptedBuffer = await crypto.subtle.decrypt(\r\n { name: \"AES-GCM\", iv: encryptedRecord.iv as BufferSource },\r\n this.cryptoKey,\r\n encryptedRecord.ciphertext as BufferSource\r\n );\r\n\r\n const jsonString = new TextDecoder().decode(decryptedBuffer);\r\n return JSON.parse(jsonString) as T;\r\n }\r\n\r\n /**\r\n * Reads or creates the database PBKDF2 salt in the `__meta__` store.\r\n */\r\n private async _getOrCreateSalt(): Promise<Uint8Array> {\r\n if (!this.db) throw new Error(\"Database not connected.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(\"__meta__\", \"readwrite\");\r\n const store = tx.objectStore(\"__meta__\");\r\n const req = store.get(\"db_salt\");\r\n\r\n req.onsuccess = () => {\r\n const record = req.result as MetaRecord | undefined;\r\n if (record?.value) {\r\n resolve(new Uint8Array(record.value));\r\n } else {\r\n const newSalt = crypto.getRandomValues(new Uint8Array(16));\r\n store.put({ id: \"db_salt\", value: newSalt });\r\n resolve(newSalt);\r\n }\r\n };\r\n\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Initializes the IndexedDB instance, sets up metadata tables, and derives the session key.\r\n * @param passphrase Passphrase used to derive encryption keys.\r\n */\r\n public async init(passphrase: string): Promise<this> {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.dbName, this.version);\r\n\r\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\r\n const db = (event.target as IDBOpenDBRequest).result;\r\n if (!db.objectStoreNames.contains(\"__meta__\")) {\r\n db.createObjectStore(\"__meta__\", { keyPath: \"id\" });\r\n }\r\n if (!db.objectStoreNames.contains(this.storeName)) {\r\n db.createObjectStore(this.storeName);\r\n }\r\n };\r\n\r\n request.onsuccess = async (event: Event) => {\r\n this.db = (event.target as IDBOpenDBRequest).result;\r\n try {\r\n const salt = await this._getOrCreateSalt();\r\n this.cryptoKey = await this._deriveKey(passphrase, salt);\r\n resolve(this);\r\n } catch (err) {\r\n reject(err);\r\n }\r\n };\r\n\r\n request.onerror = (event: Event) => {\r\n reject((event.target as IDBOpenDBRequest).error);\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Encrypts and persists a value by key.\r\n */\r\n public async setItem<T>(key: IDBValidKey, value: T): Promise<boolean> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n const encryptedRecord = await this._encrypt(value);\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readwrite\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.put(encryptedRecord, key);\r\n\r\n req.onsuccess = () => resolve(true);\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Retrieves and decrypts a value by key. Returns `null` if not found.\r\n */\r\n public async getItem<T>(key: IDBValidKey): Promise<T | null> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readonly\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.get(key);\r\n\r\n req.onsuccess = async () => {\r\n if (!req.result) return resolve(null);\r\n try {\r\n const decrypted = await this._decrypt<T>(req.result as EncryptedPayload);\r\n resolve(decrypted);\r\n } catch {\r\n reject(new Error(\"Decryption failed. Invalid passphrase or corrupted data.\"));\r\n }\r\n };\r\n\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Deletes an item by key.\r\n */\r\n public async removeItem(key: IDBValidKey): Promise<boolean> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readwrite\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.delete(key);\r\n\r\n req.onsuccess = () => resolve(true);\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Clears all encrypted entries in the current object store.\r\n */\r\n public async clear(): Promise<boolean> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readwrite\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.clear();\r\n\r\n req.onsuccess = () => resolve(true);\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Iterates through the store, decrypting and returning all key-value entries.\r\n */\r\n public async getAll<T>(): Promise<StoredEntry<T>[]> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readonly\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.openCursor();\r\n const results: StoredEntry<T>[] = [];\r\n\r\n req.onsuccess = async (event: Event) => {\r\n const cursor = (event.target as IDBRequest<IDBCursorWithValue | null>).result;\r\n if (cursor) {\r\n try {\r\n const decryptedValue = await this._decrypt<T>(cursor.value as EncryptedPayload);\r\n results.push({ key: cursor.key, value: decryptedValue });\r\n cursor.continue();\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n reject(new Error(`Failed to decrypt record under key '${String(cursor.key)}': ${msg}`));\r\n }\r\n } else {\r\n resolve(results);\r\n }\r\n };\r\n\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Closes the active database connection.\r\n */\r\n public close(): void {\r\n if (this.db) {\r\n this.db.close();\r\n this.db = null;\r\n this.cryptoKey = null;\r\n }\r\n }\r\n}"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?module.exports=t():typeof define==`function`&&define.amd?define([],t):(e=typeof globalThis<`u`?globalThis:e||self,e.LittleIndexedDB=t())})(this,function(){function e(t){"@babel/helpers - typeof";return e=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},e(t)}function t(t,n){if(e(t)!=`object`||!t)return t;var r=t[Symbol.toPrimitive];if(r!==void 0){var i=r.call(t,n||`default`);if(e(i)!=`object`)return i;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(n===`string`?String:Number)(t)}function n(n){var r=t(n,`string`);return e(r)==`symbol`?r:r+``}function r(e,t,r){return(t=n(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}return class{constructor(e,t,n=1){r(this,`dbName`,void 0),r(this,`storeName`,void 0),r(this,`version`,void 0),r(this,`db`,null),r(this,`cryptoKey`,null),this.dbName=e,this.storeName=t,this.version=n}async _deriveKey(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`PBKDF2`},!1,[`deriveKey`]);return crypto.subtle.deriveKey({name:`PBKDF2`,salt:t,iterations:1e5,hash:`SHA-256`},r,{name:`AES-GCM`,length:256},!1,[`encrypt`,`decrypt`])}async _encrypt(e){if(!this.cryptoKey)throw Error(`Key not initialized. Call init() first.`);let t=crypto.getRandomValues(new Uint8Array(12)),n=new TextEncoder().encode(JSON.stringify(e)),r=await crypto.subtle.encrypt({name:`AES-GCM`,iv:t},this.cryptoKey,n);return{iv:t,ciphertext:new Uint8Array(r)}}async _decrypt(e){if(!this.cryptoKey)throw Error(`Key not initialized. Call init() first.`);let t=await crypto.subtle.decrypt({name:`AES-GCM`,iv:e.iv},this.cryptoKey,e.ciphertext),n=new TextDecoder().decode(t);return JSON.parse(n)}async _getOrCreateSalt(){if(!this.db)throw Error(`Database not connected.`);return new Promise((e,t)=>{let n=this.db.transaction(`__meta__`,`readwrite`).objectStore(`__meta__`),r=n.get(`db_salt`);r.onsuccess=()=>{let t=r.result;if(t?.value)e(new Uint8Array(t.value));else{let t=crypto.getRandomValues(new Uint8Array(16));n.put({id:`db_salt`,value:t}),e(t)}},r.onerror=()=>t(r.error)})}async init(e){return new Promise((t,n)=>{let r=indexedDB.open(this.dbName,this.version);r.onupgradeneeded=e=>{let t=e.target.result;t.objectStoreNames.contains(`__meta__`)||t.createObjectStore(`__meta__`,{keyPath:`id`}),t.objectStoreNames.contains(this.storeName)||t.createObjectStore(this.storeName)},r.onsuccess=async r=>{this.db=r.target.result;try{let n=await this._getOrCreateSalt();this.cryptoKey=await this._deriveKey(e,n),t(this)}catch(e){n(e)}},r.onerror=e=>{n(e.target.error)}})}async setItem(e,t){if(!this.db)throw Error(`Database not initialized.`);let n=await this._encrypt(t);return new Promise((t,r)=>{let i=this.db.transaction(this.storeName,`readwrite`).objectStore(this.storeName).put(n,e);i.onsuccess=()=>t(!0),i.onerror=()=>r(i.error)})}async getItem(e){if(!this.db)throw Error(`Database not initialized.`);return new Promise((t,n)=>{let r=this.db.transaction(this.storeName,`readonly`).objectStore(this.storeName).get(e);r.onsuccess=async()=>{if(!r.result)return t(null);try{t(await this._decrypt(r.result))}catch{n(Error(`Decryption failed. Invalid passphrase or corrupted data.`))}},r.onerror=()=>n(r.error)})}async removeItem(e){if(!this.db)throw Error(`Database not initialized.`);return new Promise((t,n)=>{let r=this.db.transaction(this.storeName,`readwrite`).objectStore(this.storeName).delete(e);r.onsuccess=()=>t(!0),r.onerror=()=>n(r.error)})}async clear(){if(!this.db)throw Error(`Database not initialized.`);return new Promise((e,t)=>{let n=this.db.transaction(this.storeName,`readwrite`).objectStore(this.storeName).clear();n.onsuccess=()=>e(!0),n.onerror=()=>t(n.error)})}async getAll(){if(!this.db)throw Error(`Database not initialized.`);return new Promise((e,t)=>{let n=this.db.transaction(this.storeName,`readonly`).objectStore(this.storeName).openCursor(),r=[];n.onsuccess=async n=>{let i=n.target.result;if(i)try{let e=await this._decrypt(i.value);r.push({key:i.key,value:e}),i.continue()}catch(e){let n=e instanceof Error?e.message:String(e);t(Error(`Failed to decrypt record under key '${String(i.key)}': ${n}`))}else e(r)},n.onerror=()=>t(n.error)})}close(){this.db&&(this.db.close(),this.db=null,this.cryptoKey=null)}}});
2
+ //# sourceMappingURL=little-indexeddb.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"little-indexeddb.umd.js","names":["factory","global","_typeof","o","toPrimitive","e","r","toPropertyKey","i","t","_defineProperty","dbName","storeName","version","enc","keyMaterial","passphrase","iv","encodedData","data","ciphertextBuffer","decryptedBuffer","encryptedRecord","jsonString","store","req","record","resolve","newSalt","reject","request","db","event","salt","err","value","key","results","cursor","decryptedValue","msg"],"sources":["../src/index.ts"],"sourcesContent":["export interface EncryptedPayload {\r\n iv: Uint8Array;\r\n ciphertext: Uint8Array;\r\n}\r\n\r\nexport interface StoredEntry<T = unknown> {\r\n key: IDBValidKey;\r\n value: T;\r\n}\r\n\r\ninterface MetaRecord {\r\n id: string;\r\n value: Uint8Array;\r\n}\r\n\r\n/**\r\n * Basically IndexedDB with built-in AES-GCM encryption.\r\n */\r\nexport default class LittleIndexedDB {\r\n private db: IDBDatabase | null = null;\r\n private cryptoKey: CryptoKey | null = null;\r\n\r\n /**\r\n * @param dbName Database name.\r\n * @param storeName Primary object store name.\r\n * @param version Database schema version. Defaults to 1.\r\n */\r\n constructor(\r\n public readonly dbName: string,\r\n public readonly storeName: string,\r\n public readonly version: number = 1\r\n ) {}\r\n\r\n /**\r\n * Derives an AES-GCM-256 key from a passphrase and a salt using PBKDF2.\r\n */\r\n private async _deriveKey(passphrase: string, salt: Uint8Array): Promise<CryptoKey> {\r\n const enc = new TextEncoder();\r\n const keyMaterial = await crypto.subtle.importKey(\r\n \"raw\",\r\n enc.encode(passphrase),\r\n { name: \"PBKDF2\" },\r\n false,\r\n [\"deriveKey\"]\r\n );\r\n\r\n return crypto.subtle.deriveKey(\r\n {\r\n name: \"PBKDF2\",\r\n salt: salt as BufferSource,\r\n iterations: 100_000,\r\n hash: \"SHA-256\",\r\n },\r\n keyMaterial,\r\n { name: \"AES-GCM\", length: 256 },\r\n false,\r\n [\"encrypt\", \"decrypt\"]\r\n );\r\n }\r\n\r\n /**\r\n * Encrypts any JSON serializable val ue.\r\n */\r\n private async _encrypt<T>(data: T): Promise<EncryptedPayload> {\r\n if (!this.cryptoKey) throw new Error(\"Key not initialized. Call init() first.\");\r\n\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n const encodedData = new TextEncoder().encode(JSON.stringify(data));\r\n\r\n const ciphertextBuffer = await crypto.subtle.encrypt(\r\n { name: \"AES-GCM\", iv },\r\n this.cryptoKey,\r\n encodedData\r\n );\r\n\r\n return {\r\n iv,\r\n ciphertext: new Uint8Array(ciphertextBuffer),\r\n };\r\n }\r\n\r\n /**\r\n * Decrypts an encrypted payload back into its original parsed data structure.\r\n */\r\n private async _decrypt<T>(encryptedRecord: EncryptedPayload): Promise<T> {\r\n if (!this.cryptoKey) throw new Error(\"Key not initialized. Call init() first.\");\r\n\r\n const decryptedBuffer = await crypto.subtle.decrypt(\r\n { name: \"AES-GCM\", iv: encryptedRecord.iv as BufferSource },\r\n this.cryptoKey,\r\n encryptedRecord.ciphertext as BufferSource\r\n );\r\n\r\n const jsonString = new TextDecoder().decode(decryptedBuffer);\r\n return JSON.parse(jsonString) as T;\r\n }\r\n\r\n /**\r\n * Reads or creates the database PBKDF2 salt in the `__meta__` store.\r\n */\r\n private async _getOrCreateSalt(): Promise<Uint8Array> {\r\n if (!this.db) throw new Error(\"Database not connected.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(\"__meta__\", \"readwrite\");\r\n const store = tx.objectStore(\"__meta__\");\r\n const req = store.get(\"db_salt\");\r\n\r\n req.onsuccess = () => {\r\n const record = req.result as MetaRecord | undefined;\r\n if (record?.value) {\r\n resolve(new Uint8Array(record.value));\r\n } else {\r\n const newSalt = crypto.getRandomValues(new Uint8Array(16));\r\n store.put({ id: \"db_salt\", value: newSalt });\r\n resolve(newSalt);\r\n }\r\n };\r\n\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Initializes the IndexedDB instance, sets up metadata tables, and derives the session key.\r\n * @param passphrase Passphrase used to derive encryption keys.\r\n */\r\n public async init(passphrase: string): Promise<this> {\r\n return new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.dbName, this.version);\r\n\r\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\r\n const db = (event.target as IDBOpenDBRequest).result;\r\n if (!db.objectStoreNames.contains(\"__meta__\")) {\r\n db.createObjectStore(\"__meta__\", { keyPath: \"id\" });\r\n }\r\n if (!db.objectStoreNames.contains(this.storeName)) {\r\n db.createObjectStore(this.storeName);\r\n }\r\n };\r\n\r\n request.onsuccess = async (event: Event) => {\r\n this.db = (event.target as IDBOpenDBRequest).result;\r\n try {\r\n const salt = await this._getOrCreateSalt();\r\n this.cryptoKey = await this._deriveKey(passphrase, salt);\r\n resolve(this);\r\n } catch (err) {\r\n reject(err);\r\n }\r\n };\r\n\r\n request.onerror = (event: Event) => {\r\n reject((event.target as IDBOpenDBRequest).error);\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Encrypts and persists a value by key.\r\n */\r\n public async setItem<T>(key: IDBValidKey, value: T): Promise<boolean> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n const encryptedRecord = await this._encrypt(value);\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readwrite\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.put(encryptedRecord, key);\r\n\r\n req.onsuccess = () => resolve(true);\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Retrieves and decrypts a value by key. Returns `null` if not found.\r\n */\r\n public async getItem<T>(key: IDBValidKey): Promise<T | null> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readonly\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.get(key);\r\n\r\n req.onsuccess = async () => {\r\n if (!req.result) return resolve(null);\r\n try {\r\n const decrypted = await this._decrypt<T>(req.result as EncryptedPayload);\r\n resolve(decrypted);\r\n } catch {\r\n reject(new Error(\"Decryption failed. Invalid passphrase or corrupted data.\"));\r\n }\r\n };\r\n\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Deletes an item by key.\r\n */\r\n public async removeItem(key: IDBValidKey): Promise<boolean> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readwrite\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.delete(key);\r\n\r\n req.onsuccess = () => resolve(true);\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Clears all encrypted entries in the current object store.\r\n */\r\n public async clear(): Promise<boolean> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readwrite\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.clear();\r\n\r\n req.onsuccess = () => resolve(true);\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Iterates through the store, decrypting and returning all key-value entries.\r\n */\r\n public async getAll<T>(): Promise<StoredEntry<T>[]> {\r\n if (!this.db) throw new Error(\"Database not initialized.\");\r\n\r\n return new Promise((resolve, reject) => {\r\n const tx = this.db!.transaction(this.storeName, \"readonly\");\r\n const store = tx.objectStore(this.storeName);\r\n const req = store.openCursor();\r\n const results: StoredEntry<T>[] = [];\r\n\r\n req.onsuccess = async (event: Event) => {\r\n const cursor = (event.target as IDBRequest<IDBCursorWithValue | null>).result;\r\n if (cursor) {\r\n try {\r\n const decryptedValue = await this._decrypt<T>(cursor.value as EncryptedPayload);\r\n results.push({ key: cursor.key, value: decryptedValue });\r\n cursor.continue();\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n reject(new Error(`Failed to decrypt record under key '${String(cursor.key)}': ${msg}`));\r\n }\r\n } else {\r\n resolve(results);\r\n }\r\n };\r\n\r\n req.onerror = () => reject(req.error);\r\n });\r\n }\r\n\r\n /**\r\n * Closes the active database connection.\r\n */\r\n public close(): void {\r\n if (this.db) {\r\n this.db.close();\r\n this.db = null;\r\n this.cryptoKey = null;\r\n }\r\n }\r\n}"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,38 @@
1
1
  {
2
2
  "name": "litle-indexeddb",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "IndexedDb with AES-GCM encryption",
4
+ "private": false,
5
+ "version": "1.0.0",
6
+ "type": "module",
7
+ "main": "./dist/little-indexeddb.umd.js",
8
+ "module": "./dist/little-indexeddb.umd.js",
9
+ "types": "./dist/index.d.ts",
10
+ "unpkg": "./dist/little-indexeddb.umd.js",
11
+ "jsdeliver": "./dist/little-indexeddb.umd.js",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/little-indexeddb.es.js",
15
+ "require": "./dist/little-indexeddb.umd.js",
16
+ "types": "./dist/index.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "dev": "vite",
24
+ "build": "tsc --noEmit && vite build",
25
+ "preview": "vite preview",
26
+ "prepublishOnly": "yarn build"
27
+ },
28
+ "devDependencies": {
29
+ "@microsoft/api-extractor": "^7.60.1",
30
+ "@typescript/typescript6": "^6.0.2",
31
+ "typescript": "~7.0.2",
32
+ "vite": "^8.3.5"
33
+ },
34
+ "dependencies": {
35
+ "@types/node": "^26.6.6",
36
+ "vite-plugin-dts": "^5.1.2"
37
+ }
38
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.