diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 54610f1..d2de653 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -20,6 +20,7 @@ jobs: cache: npm node-version: 16 - run: npm ci + - run: npm run build - run: npm run test - run: npx semantic-release env: diff --git a/.gitignore b/.gitignore index a432289..961bc0c 100644 --- a/.gitignore +++ b/.gitignore @@ -138,3 +138,6 @@ junit.xml .DS_Store .vscode + +# Exclude generated type declarations +src/**/*.d.ts diff --git a/.npmignore b/.npmignore index e552e69..bd4bae6 100644 --- a/.npmignore +++ b/.npmignore @@ -2,3 +2,4 @@ examples test commitlint.config.js +tsconfig.json diff --git a/package-lock.json b/package-lock.json index 028877b..2f217a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,8 @@ "@commitlint/cli": "^17.3.0", "@commitlint/config-conventional": "^17.3.0", "husky": "^8.0.2", - "jest": "^27.5.1" + "jest": "^27.5.1", + "typescript": "^4.9.4" }, "engines": { "node": ">=14.20.0" @@ -6106,9 +6107,9 @@ } }, "node_modules/typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -11152,9 +11153,9 @@ } }, "typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true }, "universalify": { diff --git a/package.json b/package.json index a79bafd..06fa990 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,12 @@ "version": "0.0.27", "description": "SDK for interacting with Cyclic.sh (https://cyclic.sh) app AWS DynamoDB databases", "main": "src/index.js", + "types": "src/index.d.ts", "scripts": { - "test": "jest", - "prepare": "husky install" + "clean": "find ./src -name '*.d.ts.map' -delete && find ./src -name '*.d.ts' -delete", + "build": "tsc", + "test": "jest", + "prepare": "husky install" }, "repository": { "type": "git", @@ -40,7 +43,8 @@ "@commitlint/cli": "^17.3.0", "@commitlint/config-conventional": "^17.3.0", "husky": "^8.0.2", - "jest": "^27.5.1" + "jest": "^27.5.1", + "typescript": "^4.9.4" }, "dependencies": { "@aws-sdk/client-dynamodb": "3.82.0", diff --git a/src/cy_db_collection.js b/src/cy_db_collection.js index 1daeb73..386f303 100644 --- a/src/cy_db_collection.js +++ b/src/cy_db_collection.js @@ -10,15 +10,31 @@ const { gen_expression } = require('./expressions') -class CyclicCollection{ +class CyclicCollection { + /* + * Constructs a CyclicCollection that can be used to interact with collection. + * @arg {string} collection - name of the collection + * @arg {object} props - optional + */ constructor(collection, props={}){ validate_strings(collection, 'Collection Name') - - this.collection = collection + this.collection = collection } + + /* + * Constructs a new CyclicItem addressed by key inside of this collection + * @arg {string} key - the key to assign to the new item + * @returns {CyclicItem} - new item for the key in this collection + */ item(key){ return new CyclicItem(this.collection,key) - } + } + + /* + * Retrieve data from dynamodb associated to key instead of this collection. + * @arg {string} key - the key to lookup the item + * @returns {CyclicItem} - retrieves the data associated with key from dynamodb + */ async get(key){ let item = new CyclicItem(this.collection,key) return item.get() @@ -27,7 +43,7 @@ class CyclicCollection{ let item = new CyclicItem(this.collection,key) return item.set(props,opts) } - + async delete(key, props, opts){ let item = new CyclicItem(this.collection,key) return item.delete() @@ -40,36 +56,36 @@ class CyclicCollection{ } let scans = Array.from({length: segments}, (_, index) => index + 1); - + let filter = gen_expression(q) filter.expression = `${filter.expression} AND cy_meta.#kc = :vcol` filter.attr_names[`#kc`] = 'c' filter.attr_vals[`:vcol`] = this.collection - + let r = { results: [] } let segment_results = await Promise.all(scans.map(s=>{ return this.parallel_scan(filter, s-1, segments) - + })) segment_results.forEach(s=>{ s.results.forEach(sr=>{r.results.push(sr)}) }) - + return r } - + async parallel_scan(filter, segment, total_segments, limit=50000 , next = undefined){ let results = [] do{ var params = { TableName: process.env.CYCLIC_DB, - Limit: limit, + Limit: limit, ScanIndexForward:false, Segment: segment, TotalSegments:total_segments, @@ -175,4 +191,4 @@ class CyclicCollection{ } -module.exports = CyclicCollection \ No newline at end of file +module.exports = CyclicCollection diff --git a/src/index.js b/src/index.js index 608b673..b7105a7 100644 --- a/src/index.js +++ b/src/index.js @@ -9,23 +9,32 @@ class CyclicDb extends Function{ this._bound = this.bind(this) return this._bound } - + _call(table_name) { process.env.CYCLIC_DB = table_name return new CyclicDb } + /** + * @type {CyclicItem} + */ item(collection,key){ return new CyclicItem(collection, key) } - + + /** + * @type {CyclicCollection} + */ collection(collection){ return new CyclicCollection(collection) } + /** + * @type {CyclicIndex} + */ index(name){ return new CyclicIndex(name) } } -module.exports = new CyclicDb \ No newline at end of file +module.exports = new CyclicDb diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..970ea57 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "include": [ + "src/**/*.js" + ], + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "allowJs": true, + "declarationMap": true + } +}