Skip to content

Commit

Permalink
Revert to collection (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
calummoore authored Nov 2, 2022
1 parent 28ed5c4 commit 23d7f33
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 218 deletions.
6 changes: 3 additions & 3 deletions packages/client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ const db = new Polybase({

## Get a single record

You can read data once, by calling the `.doc(id: string).get()` method on a contract.
You can read data once, by calling the `.doc(id: string).get()` method on a collection.

```ts
const colRef = db.contract("org/places")
const colRef = db.collection("org/places")
const record = await colRef.doc("id").get()

const { id, ...data } = record
Expand All @@ -37,7 +37,7 @@ const { id, ...data } = record
## Write data

```ts
const colRef = db.contract("org/places")
const colRef = db.collection("org/places")
const doc = await colRef.doc("london").set({
name: "London",
country: "UK",
Expand Down
44 changes: 22 additions & 22 deletions packages/client/e2e/e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import Wallet from 'ethereumjs-wallet'
import { ethPersonalSign } from '@polybase/eth'
import { Polybase, Contract } from '../src'
import { Polybase, Collection } from '../src'

jest.setTimeout(10000)

const BASE_API_URL = process.env.E2E_API_URL ?? 'http://localhost:8080'
const API_URL = `${BASE_API_URL}/v0`
const wait = (time: number) => new Promise((resolve) => { setTimeout(resolve, time) })
const createContract = async (s: Polybase, namespace: string, extraFields?: string) => {
const contracts = await s.applySchema(`
contract Col {
const createCollection = async (s: Polybase, namespace: string, extraFields?: string) => {
const collections = await s.applySchema(`
collection Col {
id: string;
name: string;
publicKey: string;
Expand Down Expand Up @@ -40,7 +40,7 @@ const createContract = async (s: Polybase, namespace: string, extraFields?: stri
}
`, namespace)

return contracts[0]
return collections[0]
}

const prefix = `test-${Date.now()}`
Expand All @@ -53,16 +53,16 @@ beforeEach(() => {
})
})

test('create contract', async () => {
const namespace = `${prefix}-create-contract`
const c = await createContract(s, namespace)
expect(c).toBeInstanceOf(Contract)
test('create collection', async () => {
const namespace = `${prefix}-create-collection`
const c = await createCollection(s, namespace)
expect(c).toBeInstanceOf(Collection)
expect(c.id).toBe(namespace + '/Col')
})

test('create data on contract', async () => {
test('create data on collection', async () => {
const namespace = `${prefix}-create-data`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])
const res = await c.doc('id1').get()
Expand All @@ -79,9 +79,9 @@ test('create data on contract', async () => {
})
})

test('call setName on contract', async () => {
test('call setName on collection', async () => {
const namespace = `${prefix}-update-data`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])
await c.doc('id1').call('setName', ['Calum2'])
Expand All @@ -99,9 +99,9 @@ test('call setName on contract', async () => {
})
})

test('list data from contract', async () => {
test('list data from collection', async () => {
const namespace = `${prefix}-list-data`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])
await c.create(['id2', 'Sally'])
Expand Down Expand Up @@ -137,7 +137,7 @@ test('list data from contract', async () => {

test('list data with == where clause', async () => {
const namespace = `${prefix}-list-where-eq-data`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])
await c.create(['id2', 'Sally'])
Expand Down Expand Up @@ -174,7 +174,7 @@ test('list data with == where clause', async () => {

test('list data with > where clause', async () => {
const namespace = `${prefix}-list-where-gt-data`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])
await c.create(['id2', 'Sally'])
Expand Down Expand Up @@ -211,7 +211,7 @@ test('list data with > where clause', async () => {

test('list data with sort clause', async () => {
const namespace = `${prefix}-list-sorts-data`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])
await c.create(['id2', 'Sally'])
Expand Down Expand Up @@ -257,7 +257,7 @@ test('list data with sort clause', async () => {

test('list data with snapshot', async () => {
const namespace = `${prefix}-list-with-snapshot`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])

Expand Down Expand Up @@ -293,7 +293,7 @@ test('list data with snapshot', async () => {

test('list data with cursor', async () => {
const namespace = `${prefix}-list-with-cursor`
const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum'])
await c.create(['id2', 'Sally'])
Expand Down Expand Up @@ -369,7 +369,7 @@ test('signing', async () => {
},
})

const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum2'], pk)

Expand Down Expand Up @@ -401,7 +401,7 @@ test('signing', async () => {
test('delete', async () => {
const namespace = `${prefix}-delete`

const c = await createContract(s, namespace)
const c = await createCollection(s, namespace)

await c.create(['id1', 'Calum2'])
await c.doc('id1').call('destroy', [])
Expand Down
2 changes: 1 addition & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
},
"dependencies": {
"@polybase/eth": "^0.3.0",
"@polybase/polylang": "^0.3.0",
"@polybase/polylang": "^0.3.1",
"axios": "^0.27.2",
"lodash.merge": "^4.6.2"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { Doc } from './Doc'
import { Query } from './Query'
import { Subscription, SubscriptionFn, SubscriptionErrorFn } from './Subscription'
import { Client } from './Client'
import { BasicValue, ContractMeta, ContractDocument, ContractList, QueryWhereOperator, CallArgs } from './types'
import { BasicValue, CollectionMeta, CollectionDocument, CollectionList, QueryWhereOperator, CallArgs } from './types'
import { parse, validateSet } from '@polybase/polylang'
import { validateCallParameters, getContractAST } from './util'
import { validateCallParameters, getCollectionAST } from './util'

export class Contract<T> {
export class Collection<T> {
id: string
private querySubs: Record<string, Subscription<ContractList<T>>> = {}
private docSubs: Record<string, Subscription<ContractDocument<T>>> = {}
private meta?: ContractMeta
private querySubs: Record<string, Subscription<CollectionList<T>>> = {}
private docSubs: Record<string, Subscription<CollectionDocument<T>>> = {}
private meta?: CollectionMeta
private validator?: (data: Partial<T>) => Promise<boolean>
private client: Client

Expand All @@ -30,13 +30,13 @@ export class Contract<T> {
try {
if (this.meta) return this.meta
const res = await this.client.request({
url: `/contracts/$Contract/${encodeURIComponent(this.id)}`,
url: `/collections/Collection/${encodeURIComponent(this.id)}`,
method: 'GET',
}).send()
this.meta = res.data?.data as ContractMeta
this.meta = res.data?.data as CollectionMeta
return this.meta
} catch (e) {
// TODO: handle missing contract
// TODO: handle missing collection
throw new Error('Unable to fetch metadata')
}
}
Expand All @@ -48,7 +48,7 @@ export class Contract<T> {
const ast = await parse(meta.code)
this.validator = async (data: Partial<T>) => {
try {
await validateSet(getContractAST(this.id, ast), data)
await validateSet(getCollectionAST(this.id, ast), data)
return true
} catch {
return false
Expand All @@ -63,13 +63,13 @@ export class Contract<T> {
return await validator(data)
}

create = async (args: CallArgs, pk?: string): Promise<ContractDocument<T>> => {
create = async (args: CallArgs, pk?: string): Promise<CollectionDocument<T>> => {
const meta = await this.getMeta()
const ast = await parse(meta.code)
validateCallParameters(this.id, 'constructor', ast, args)

const res = await this.client.request({
url: `/contracts/${encodeURIComponent(this.id)}`,
url: `/collections/${encodeURIComponent(this.id)}`,
method: 'POST',
data: {
args,
Expand All @@ -79,9 +79,9 @@ export class Contract<T> {
return res.data
}

get = async (): Promise<ContractList<T>> => {
get = async (): Promise<CollectionList<T>> => {
const res = await this.client.request({
url: `/contracts/${encodeURIComponent(this.id)}`,
url: `/collections/${encodeURIComponent(this.id)}`,
method: 'GET',
}).send()

Expand All @@ -104,7 +104,7 @@ export class Contract<T> {
return this.createQuery().limit(limit)
}

onSnapshot = (fn: SubscriptionFn<ContractList<T>>) => {
onSnapshot = (fn: SubscriptionFn<CollectionList<T>>) => {
return this.createQuery().onSnapshot(fn)
}

Expand All @@ -117,25 +117,25 @@ export class Contract<T> {
}

key = () => {
return `contract:${this.id}`
return `collection:${this.id}`
}

private createQuery () {
return new Query<T>(this.id, this.client, this.onQuerySnapshotRegister)
}

private onQuerySnapshotRegister = (q: Query<T>, fn: SubscriptionFn<ContractList<T>>, errFn?: SubscriptionErrorFn) => {
private onQuerySnapshotRegister = (q: Query<T>, fn: SubscriptionFn<CollectionList<T>>, errFn?: SubscriptionErrorFn) => {
const k = q.key()
if (!this.querySubs[k]) {
this.querySubs[k] = new Subscription<ContractList<T>>(q.request(), this.client)
this.querySubs[k] = new Subscription<CollectionList<T>>(q.request(), this.client)
}
return this.querySubs[k].subscribe(fn, errFn)
}

private onDocSnapshotRegister = (d: Doc<T>, fn: SubscriptionFn<ContractDocument<T>>, errFn?: SubscriptionErrorFn) => {
private onDocSnapshotRegister = (d: Doc<T>, fn: SubscriptionFn<CollectionDocument<T>>, errFn?: SubscriptionErrorFn) => {
const k = d.key()
if (!this.docSubs[k]) {
this.docSubs[k] = new Subscription<ContractDocument<T>>(d.request(), this.client)
this.docSubs[k] = new Subscription<CollectionDocument<T>>(d.request(), this.client)
}
return this.docSubs[k].subscribe(fn, errFn)
}
Expand Down
30 changes: 15 additions & 15 deletions packages/client/src/Doc.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
import { parse } from '@polybase/polylang'
import { Contract } from './Contract'
import { Collection } from './Collection'
import { SubscriptionErrorFn, SubscriptionFn } from './Subscription'
import { Client } from './Client'
import { Request, ContractDocument } from './types'
import { Request, CollectionDocument } from './types'
import { validateCallParameters } from './util'

export type DocSnapshotRegister<T> = (d: Doc<T>, fn: SubscriptionFn<ContractDocument<T>>, errFn?: SubscriptionErrorFn) => (() => void)
export type DocSnapshotRegister<T> = (d: Doc<T>, fn: SubscriptionFn<CollectionDocument<T>>, errFn?: SubscriptionErrorFn) => (() => void)

export class Doc<T> {
id: string
private contract: Contract<T>
private collection: Collection<T>
private client: Client
private onSnapshotRegister: DocSnapshotRegister<T>

constructor (id: string, contract: Contract<T>, client: Client, onSnapshotRegister: DocSnapshotRegister<T>) {
constructor (id: string, collection: Collection<T>, client: Client, onSnapshotRegister: DocSnapshotRegister<T>) {
this.id = id
this.contract = contract
this.collection = collection
this.client = client
this.onSnapshotRegister = onSnapshotRegister
}

// delete = async (): Promise<ContractDocument<T>> => {
// delete = async (): Promise<CollectionDocument<T>> => {
// const res = await this.client.request({
// ...this.request(),
// method: 'DELETE',
// }).send()
// return res.data
// }

call = async (functionName: string, args: (string | number | Doc<any>)[] = [], pk?: string): Promise<ContractDocument<T>> => {
const meta = await this.contract.getMeta()
call = async (functionName: string, args: (string | number | Doc<any>)[] = [], pk?: string): Promise<CollectionDocument<T>> => {
const meta = await this.collection.getMeta()
const ast = await parse(meta.code)
validateCallParameters(this.contract.id, functionName, ast, args)
validateCallParameters(this.collection.id, functionName, ast, args)

const res = await this.client.request({
url: `/contracts/${encodeURIComponent(this.contract.id)}/${encodeURIComponent(this.id)}/call/${encodeURIComponent(functionName)}`,
url: `/collections/${encodeURIComponent(this.collection.id)}/${encodeURIComponent(this.id)}/call/${encodeURIComponent(functionName)}`,
method: 'POST',
data: {
args: args.map(arg => {
Expand All @@ -50,21 +50,21 @@ export class Doc<T> {
return res.data
}

get = async (): Promise<ContractDocument<T>> => {
get = async (): Promise<CollectionDocument<T>> => {
const res = await this.client.request(this.request()).send()
return res.data
}

key = () => {
return `doc:${this.contract.id}/${this.id}`
return `doc:${this.collection.id}/${this.id}`
}

onSnapshot = (fn: SubscriptionFn<ContractDocument<T>>, errFn?: SubscriptionErrorFn) => {
onSnapshot = (fn: SubscriptionFn<CollectionDocument<T>>, errFn?: SubscriptionErrorFn) => {
return this.onSnapshotRegister(this, fn, errFn)
}

request = (): Request => ({
url: `/contracts/${encodeURIComponent(this.contract.id)}/${encodeURIComponent(this.id)}`,
url: `/collections/${encodeURIComponent(this.collection.id)}/${encodeURIComponent(this.id)}`,
method: 'GET',
})
}
Loading

0 comments on commit 23d7f33

Please sign in to comment.