Skip to content

Commit

Permalink
Improve type inference for SDK and docs revision
Browse files Browse the repository at this point in the history
  • Loading branch information
1pxone committed Feb 2, 2025
1 parent 3b08457 commit f159dfa
Show file tree
Hide file tree
Showing 12 changed files with 205 additions and 145 deletions.
9 changes: 9 additions & 0 deletions .changeset/tough-wombats-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@rushdb/javascript-sdk': minor
'rushdb-docs': minor
'rushdb-core': minor
'rushdb-dashboard': minor
'rushdb-website': minor
---

Improve type inference for SDK
36 changes: 16 additions & 20 deletions docs/docs/basic-concepts/records.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -170,26 +170,22 @@ it as a "dictionary", "map", "hash table", or "associative array" depending on y
</TabsList>
<TabsContent value="sdk">
```typescript
await db.records.createMany({
label: "PRODUCT",
payload: [
{
title: 'T-Shirt',
price: 50,
},
{
title: 'Sneakers',
price: 135,
// Nested Records `SIZE`
SIZE: [
{
uk: 8.5,
qty: 5
}
]
}
]
})
await db.records.createMany("PRODUCT", [
{
title: "T-Shirt",
price: 50
},
{
title: "Sneakers",
price: 135,
SIZE: [
{
uk: 8.5,
qty: 5
}
]
}
])
```
</TabsContent>
<TabsContent value="api">
Expand Down
31 changes: 14 additions & 17 deletions docs/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,22 @@ import RushDB from '@rushdb/javascript-sdk';
const db = new RushDB("API_TOKEN")

// Push any data to RushDB the way you perceive it
await db.records.createMany({
label: "PRODUCT",
payload: [
await db.records.createMany("PRODUCT", [
{
title: "T-Shirt",
price: 50
},
{
title: "Sneakers",
price: 135,
SIZE: [
{
title: 'T-Shirt',
price: 50,
},
{
title: 'Sneakers',
price: 135,
SIZE: [
{
uk: 8.5,
qty: 5
}
]
uk: 8.5,
qty: 5
}
]
})
]
}
])

// Find it with granular precision and without any query language
await db.records.find("PRODUCT", {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,19 @@ const data = JSON.parse(fs.readFileSync('data.json', 'utf8'));
}
*/

// Convert JSON data to RushDB records
const usersData = data.users.map(user => ({ label: 'user', payload: user }));
const postsData = data.posts.map(post => ({ label: 'post', payload: post }));
const blogsData = data.blogs.map(blog => ({ label: 'blog', payload: blog }));

// Function to import data
async function importData() {
try {
// Import users
const importedUsers = await db.records.createMany(usersData);
const importedUsers = await db.records.createMany('user', data.users);
console.log('Imported Users:', importedUsers.data);

// Import posts
const importedPosts = await db.records.createMany(postsData);
const importedPosts = await db.records.createMany('post', data.posts);
console.log('Imported Posts:', importedPosts.data);

// Import blogs
const importedBlogs = await db.records.createMany(blogsData);
const importedBlogs = await db.records.createMany('blog', data.blogs);
console.log('Imported Blogs:', importedBlogs.data);
} catch (error) {
console.error('Error importing data:', error);
Expand Down
31 changes: 26 additions & 5 deletions packages/javascript-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,34 @@
"name": "@rushdb/javascript-sdk",
"description": "RushDB Javascript SDK",
"keywords": [
"neo4j",
"database",
"firebase-alternative",
"firebase",
"cypher",
"instant",
"graph database",
"instant database",
"instant-database",
"instantdatabase",
"instant db",
"instant-db",
"instantdb",
"neo4j",
"cypher",
"ai",
"ai database",
"etl",
"data-pipeline",
"data science",
"data-science",
"data management",
"data-management",
"machine learning",
"machine-learning",
"persistence",
"db",
"graph",
"graphs",
"graph-database",
"self-hosted",
"rush-db",
"rush db",
"rushdb"
],
"license": "Apache-2.0",
Expand Down
36 changes: 18 additions & 18 deletions packages/javascript-sdk/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,20 +249,20 @@ export class RestAPI {
return this.api?.records.export(searchParams, transaction)
},

find: async <S extends Schema = any>(
labelOrSearchParams?: SearchQuery<S> | string,
searchParamsOrTransaction?: SearchQuery<S> | Transaction | string,
find: async <S extends Schema = any, Q extends SearchQuery<S> = SearchQuery<S>>(
labelOrSearchParams?: Q | string,
searchParamsOrTransaction?: Q | Transaction | string,
transaction?: Transaction | string
): Promise<DBRecordsArrayInstance<S>> => {
): Promise<DBRecordsArrayInstance<S, Q>> => {
const isTransactionParam = isTransaction(searchParamsOrTransaction)
const { id, searchParams } = createSearchParams<S>(labelOrSearchParams, searchParamsOrTransaction)
const tx = isTransactionParam ? searchParamsOrTransaction : transaction
const response = await this.api?.records.find<S>({ id, searchParams }, tx)
const response = await this.api?.records.find<S, Q>({ id, searchParams: searchParams as Q }, tx)

const result = new DBRecordsArrayInstance<S>(
const result = new DBRecordsArrayInstance<S, Q>(
response.data,
response.total,
searchParamsOrTransaction as SearchQuery<S>
searchParamsOrTransaction as Q
)
result.init(this)
return result
Expand Down Expand Up @@ -293,32 +293,32 @@ export class RestAPI {
}
},

findOne: async <S extends Schema = any>(
labelOrSearchParams?: SearchQuery<S> | string,
searchParamsOrTransaction?: SearchQuery<S> | Transaction | string,
findOne: async <S extends Schema = any, Q extends SearchQuery<S> = SearchQuery<S>>(
labelOrSearchParams?: Q | string,
searchParamsOrTransaction?: Q | Transaction | string,
transaction?: Transaction | string
): Promise<DBRecordInstance<S>> => {
const isTransactionParam = isTransaction(searchParamsOrTransaction)
const { searchParams } = createSearchParams<S>(labelOrSearchParams, searchParamsOrTransaction)
const tx = isTransactionParam ? searchParamsOrTransaction : transaction
const response = await this.api?.records.findOne<S>(searchParams, tx)
const response = await this.api?.records.findOne<S, Q>(searchParams as Q, tx)

const result = new DBRecordInstance<S>(response.data)
const result = new DBRecordInstance<S, Q>(response.data)
result.init(this)
return result
},

findUniq: async <S extends Schema = any>(
labelOrSearchParams?: SearchQuery<S> | string,
searchParamsOrTransaction?: SearchQuery<S> | Transaction | string,
findUniq: async <S extends Schema = any, Q extends SearchQuery<S> = SearchQuery<S>>(
labelOrSearchParams?: Q | string,
searchParamsOrTransaction?: Q | Transaction | string,
transaction?: Transaction | string
): Promise<DBRecordInstance<S>> => {
): Promise<DBRecordInstance<S, Q>> => {
const isTransactionParam = isTransaction(searchParamsOrTransaction)
const { searchParams } = createSearchParams<S>(labelOrSearchParams, searchParamsOrTransaction)
const tx = isTransactionParam ? searchParamsOrTransaction : transaction
const response = await this.api?.records.findUniq<S>(searchParams, tx)
const response = await this.api?.records.findUniq<S, Q>(searchParams as Q, tx)

const result = new DBRecordInstance<S>(response.data)
const result = new DBRecordInstance<S, Q>(response.data)
result.init(this)
return result
},
Expand Down
29 changes: 17 additions & 12 deletions packages/javascript-sdk/src/api/create-api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { createFetcher } from '../network/index.js'
import type {
DBRecord,
DBRecordInferred,
DBRecordTarget,
Relation,
RelationDetachOptions,
Expand All @@ -23,8 +24,6 @@ import { DBRecordsBatchDraft, DBRecordDraft } from '../sdk/record.js'
import { buildTransactionHeader, pickRecordId, pickTransactionId } from './utils.js'
import type { Logger } from '../sdk/types.js'

// POST /api/v1/records/:id @TODO

export const createApi = (fetcher: ReturnType<typeof createFetcher>, logger?: Logger) => ({
labels: {
async find<S extends Schema = any>(searchParams: SearchQuery<S>, transaction?: Transaction | string) {
Expand Down Expand Up @@ -225,10 +224,10 @@ export const createApi = (fetcher: ReturnType<typeof createFetcher>, logger?: Lo
logger?.({ path, ...payload })
return fetcher<ApiResponse<{ dateTime: string; fileContent: string }>>(path, payload)
},
find<S extends Schema = any>(
params?: { id?: string; searchParams: SearchQuery<S> },
find<S extends Schema = any, Q extends SearchQuery<S> = SearchQuery<S>>(
params?: { id?: string; searchParams: Q },
transaction?: Transaction | string
) {
): Promise<ApiResponse<DBRecordInferred<S, Q>[]>> {
const txId = pickTransactionId(transaction)
const path = params?.id ? `/records/${params.id}/search` : `/records/search`
const payload = {
Expand All @@ -238,7 +237,7 @@ export const createApi = (fetcher: ReturnType<typeof createFetcher>, logger?: Lo
}

logger?.({ path, ...payload })
return fetcher<ApiResponse<DBRecord<S>[]>>(path, payload)
return fetcher<ApiResponse<DBRecordInferred<S, Q>[]>>(path, payload)
},
findById<S extends Schema = any>(idOrIds: MaybeArray<string>, transaction?: Transaction | string) {
const txId = pickTransactionId(transaction)
Expand All @@ -252,7 +251,10 @@ export const createApi = (fetcher: ReturnType<typeof createFetcher>, logger?: Lo
logger?.({ path, ...payload })
return fetcher<ApiResponse<DBRecord<S>[] | DBRecord<S>>>(path, payload)
},
async findOne<S extends Schema = any>(searchParams: SearchQuery<S>, transaction?: Transaction | string) {
async findOne<S extends Schema = any, Q extends SearchQuery<S> = SearchQuery<S>>(
searchParams: Q,
transaction?: Transaction | string
) {
const txId = pickTransactionId(transaction)
const path = `/records/search`
const payload = {
Expand All @@ -262,11 +264,14 @@ export const createApi = (fetcher: ReturnType<typeof createFetcher>, logger?: Lo
}

logger?.({ path, ...payload })
const response = await fetcher<ApiResponse<DBRecord<S>[]>>(path, payload)
const response = await fetcher<ApiResponse<DBRecordInferred<S, Q>[]>>(path, payload)
const [record] = response.data
return { ...response, data: record } as ApiResponse<DBRecord<S>>
return { ...response, data: record } as ApiResponse<DBRecordInferred<S, Q>>
},
async findUniq<S extends Schema = any>(searchParams: SearchQuery<S>, transaction?: Transaction | string) {
async findUniq<S extends Schema = any, Q extends SearchQuery<S> = SearchQuery<S>>(
searchParams: Q,
transaction?: Transaction | string
) {
const txId = pickTransactionId(transaction)
const path = `/records/search`
const payload = {
Expand All @@ -276,14 +281,14 @@ export const createApi = (fetcher: ReturnType<typeof createFetcher>, logger?: Lo
}

logger?.({ path, ...payload })
const response = await fetcher<ApiResponse<DBRecord<S>[]>>(path, payload)
const response = await fetcher<ApiResponse<DBRecordInferred<S, Q>[]>>(path, payload)

if (typeof response.total !== 'undefined' && response.total > 1) {
throw new NonUniqueResultError(response.total, searchParams)
}

const [record] = response.data
return { ...response, data: record } as ApiResponse<DBRecord<S>>
return { ...response, data: record } as ApiResponse<DBRecordInferred<S, Q>>
},
properties(target: string, transaction?: Transaction | string) {
const txId = pickTransactionId(transaction)
Expand Down
Loading

0 comments on commit f159dfa

Please sign in to comment.