Skip to content

Commit

Permalink
Add CI workflow and fix tests (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulLeCam authored Apr 9, 2024
1 parent 7dd17e3 commit 91de0e4
Show file tree
Hide file tree
Showing 14 changed files with 1,249 additions and 518 deletions.
55 changes: 55 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Build and test
on: [push, pull_request]
env:
CI: true
jobs:
build:
name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}

runs-on: ${{ matrix.os }}
strategy:
matrix:
node: [20]
os: [ubuntu-latest, macOS-latest]

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Use Node ${{ matrix.node }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}

- name: Install pnpm
id: pnpm-install
uses: pnpm/action-setup@v2
with:
version: 8
run_install: false

- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies and build
run: pnpm install --frozen-lockfile

- name: Build
run: pnpm run build

- name: Lint
run: pnpm run lint

- name: Test
run: pnpm run test:ci
4 changes: 2 additions & 2 deletions composites/points/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"devDependencies": {
"@composedb/types": "^0.7.1",
"@composexp/composite-utils": "workspace:^",
"@types/node": "^20.12.2",
"tsx": "^4.7.1"
"@types/node": "^20.12.5",
"tsx": "^4.7.2"
}
}
128 changes: 127 additions & 1 deletion composites/points/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,129 @@
// This is an auto-generated file, do not edit manually
import type { RuntimeCompositeDefinition } from '@composedb/types'
export const definition: RuntimeCompositeDefinition = {"models":{"GenericPointAllocation":{"interface":true,"implements":[],"id":"kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4","accountRelation":{"type":"none"}},"MultiplePoints":{"interface":false,"implements":["kjzl6hvfrbw6ca7buvthejhv7vqr85vmpsepzj0mc6665y2zarvjbuvtm3v4kah","kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4"],"id":"kjzl6hvfrbw6c9fmjjdsbuxnewf0yhvco3dn5mihiogeso6i1csdbw2fq8oeijy","accountRelation":{"type":"list"}},"MultiplePointsAllocation":{"interface":true,"implements":["kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4"],"id":"kjzl6hvfrbw6ca7buvthejhv7vqr85vmpsepzj0mc6665y2zarvjbuvtm3v4kah","accountRelation":{"type":"none"}},"PointsAggregation":{"interface":true,"implements":[],"id":"kjzl6hvfrbw6cb6393dpd8blke5w8r7pvbl4449mxetuibcav3oab8fnxmys6d6","accountRelation":{"type":"none"}},"SinglePoint":{"interface":false,"implements":["kjzl6hvfrbw6c7ilzfpjw96drd04jadb0aybiklk70ys2imxp5mjbjmgkecgddf","kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4"],"id":"kjzl6hvfrbw6c9332q9di7qfshxczet94w2tzeubvkbkk9vtuwmya6s9f1bvx9p","accountRelation":{"type":"list"}},"SinglePointAllocation":{"interface":true,"implements":["kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4"],"id":"kjzl6hvfrbw6c7ilzfpjw96drd04jadb0aybiklk70ys2imxp5mjbjmgkecgddf","accountRelation":{"type":"none"}},"TotalPoints":{"interface":false,"implements":["kjzl6hvfrbw6cb6393dpd8blke5w8r7pvbl4449mxetuibcav3oab8fnxmys6d6"],"id":"kjzl6hvfrbw6c5be4exsm7nkkksnqatki8bceyvbgtmcu2bu5vign23b7x4emlb","accountRelation":{"type":"set","fields":["recipient"]}}},"objects":{"GenericPointAllocation":{"recipient":{"type":"did","required":true,"immutable":false},"issuer":{"type":"view","viewType":"documentAccount"}},"MultiplePoints":{"points":{"type":"integer","required":true,"immutable":false},"recipient":{"type":"did","required":true,"immutable":false},"issuer":{"type":"view","viewType":"documentAccount"}},"MultiplePointsAllocation":{"points":{"type":"integer","required":true,"immutable":false},"recipient":{"type":"did","required":true,"immutable":false},"issuer":{"type":"view","viewType":"documentAccount"}},"PointsAggregation":{"date":{"type":"datetime","required":true,"immutable":false},"points":{"type":"integer","required":true,"immutable":false},"recipient":{"type":"did","required":true,"immutable":false},"issuer":{"type":"view","viewType":"documentAccount"}},"SinglePoint":{"recipient":{"type":"did","required":true,"immutable":false},"issuer":{"type":"view","viewType":"documentAccount"}},"SinglePointAllocation":{"recipient":{"type":"did","required":true,"immutable":false},"issuer":{"type":"view","viewType":"documentAccount"}},"TotalPoints":{"date":{"type":"datetime","required":true,"immutable":false},"points":{"type":"integer","required":true,"immutable":false},"recipient":{"type":"did","required":true,"immutable":true},"issuer":{"type":"view","viewType":"documentAccount"}}},"enums":{},"accountData":{"genericPointAllocationList":{"type":"connection","name":"GenericPointAllocation"},"multiplePointsAllocationList":{"type":"connection","name":"MultiplePointsAllocation"},"multiplePointsList":{"type":"connection","name":"MultiplePoints"},"pointsAggregationList":{"type":"connection","name":"PointsAggregation"},"recipientOfGenericPointAllocationList":{"type":"account","name":"GenericPointAllocation","property":"recipient"},"recipientOfMultiplePointsAllocationList":{"type":"account","name":"MultiplePointsAllocation","property":"recipient"},"recipientOfMultiplePointsList":{"type":"account","name":"MultiplePoints","property":"recipient"},"recipientOfPointsAggregationList":{"type":"account","name":"PointsAggregation","property":"recipient"},"recipientOfSinglePointAllocationList":{"type":"account","name":"SinglePointAllocation","property":"recipient"},"recipientOfSinglePointList":{"type":"account","name":"SinglePoint","property":"recipient"},"recipientOfTotalPoints":{"type":"account-set","name":"TotalPoints","property":"recipient"},"recipientOfTotalPointsList":{"type":"account","name":"TotalPoints","property":"recipient"},"singlePointAllocationList":{"type":"connection","name":"SinglePointAllocation"},"singlePointList":{"type":"connection","name":"SinglePoint"},"totalPoints":{"type":"set","name":"TotalPoints"},"totalPointsList":{"type":"connection","name":"TotalPoints"}}}
export const definition: RuntimeCompositeDefinition = {
models: {
GenericPointAllocation: {
interface: true,
implements: [],
id: 'kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4',
accountRelation: { type: 'none' },
},
MultiplePoints: {
interface: false,
implements: [
'kjzl6hvfrbw6ca7buvthejhv7vqr85vmpsepzj0mc6665y2zarvjbuvtm3v4kah',
'kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4',
],
id: 'kjzl6hvfrbw6c9fmjjdsbuxnewf0yhvco3dn5mihiogeso6i1csdbw2fq8oeijy',
accountRelation: { type: 'list' },
},
MultiplePointsAllocation: {
interface: true,
implements: ['kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4'],
id: 'kjzl6hvfrbw6ca7buvthejhv7vqr85vmpsepzj0mc6665y2zarvjbuvtm3v4kah',
accountRelation: { type: 'none' },
},
PointsAggregation: {
interface: true,
implements: [],
id: 'kjzl6hvfrbw6cb6393dpd8blke5w8r7pvbl4449mxetuibcav3oab8fnxmys6d6',
accountRelation: { type: 'none' },
},
SinglePoint: {
interface: false,
implements: [
'kjzl6hvfrbw6c7ilzfpjw96drd04jadb0aybiklk70ys2imxp5mjbjmgkecgddf',
'kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4',
],
id: 'kjzl6hvfrbw6c9332q9di7qfshxczet94w2tzeubvkbkk9vtuwmya6s9f1bvx9p',
accountRelation: { type: 'list' },
},
SinglePointAllocation: {
interface: true,
implements: ['kjzl6hvfrbw6c6m3n64vb2h4n8nxq9jjfb7sf7a9y893spm1pjd0enrsdlyphg4'],
id: 'kjzl6hvfrbw6c7ilzfpjw96drd04jadb0aybiklk70ys2imxp5mjbjmgkecgddf',
accountRelation: { type: 'none' },
},
TotalPoints: {
interface: false,
implements: ['kjzl6hvfrbw6cb6393dpd8blke5w8r7pvbl4449mxetuibcav3oab8fnxmys6d6'],
id: 'kjzl6hvfrbw6c5be4exsm7nkkksnqatki8bceyvbgtmcu2bu5vign23b7x4emlb',
accountRelation: { type: 'set', fields: ['recipient'] },
},
},
objects: {
GenericPointAllocation: {
recipient: { type: 'did', required: true, immutable: false },
issuer: { type: 'view', viewType: 'documentAccount' },
},
MultiplePoints: {
points: { type: 'integer', required: true, immutable: false },
recipient: { type: 'did', required: true, immutable: false },
issuer: { type: 'view', viewType: 'documentAccount' },
},
MultiplePointsAllocation: {
points: { type: 'integer', required: true, immutable: false },
recipient: { type: 'did', required: true, immutable: false },
issuer: { type: 'view', viewType: 'documentAccount' },
},
PointsAggregation: {
date: { type: 'datetime', required: true, immutable: false },
points: { type: 'integer', required: true, immutable: false },
recipient: { type: 'did', required: true, immutable: false },
issuer: { type: 'view', viewType: 'documentAccount' },
},
SinglePoint: {
recipient: { type: 'did', required: true, immutable: false },
issuer: { type: 'view', viewType: 'documentAccount' },
},
SinglePointAllocation: {
recipient: { type: 'did', required: true, immutable: false },
issuer: { type: 'view', viewType: 'documentAccount' },
},
TotalPoints: {
date: { type: 'datetime', required: true, immutable: false },
points: { type: 'integer', required: true, immutable: false },
recipient: { type: 'did', required: true, immutable: true },
issuer: { type: 'view', viewType: 'documentAccount' },
},
},
enums: {},
accountData: {
genericPointAllocationList: { type: 'connection', name: 'GenericPointAllocation' },
multiplePointsAllocationList: { type: 'connection', name: 'MultiplePointsAllocation' },
multiplePointsList: { type: 'connection', name: 'MultiplePoints' },
pointsAggregationList: { type: 'connection', name: 'PointsAggregation' },
recipientOfGenericPointAllocationList: {
type: 'account',
name: 'GenericPointAllocation',
property: 'recipient',
},
recipientOfMultiplePointsAllocationList: {
type: 'account',
name: 'MultiplePointsAllocation',
property: 'recipient',
},
recipientOfMultiplePointsList: {
type: 'account',
name: 'MultiplePoints',
property: 'recipient',
},
recipientOfPointsAggregationList: {
type: 'account',
name: 'PointsAggregation',
property: 'recipient',
},
recipientOfSinglePointAllocationList: {
type: 'account',
name: 'SinglePointAllocation',
property: 'recipient',
},
recipientOfSinglePointList: { type: 'account', name: 'SinglePoint', property: 'recipient' },
recipientOfTotalPoints: { type: 'account-set', name: 'TotalPoints', property: 'recipient' },
recipientOfTotalPointsList: { type: 'account', name: 'TotalPoints', property: 'recipient' },
singlePointAllocationList: { type: 'connection', name: 'SinglePointAllocation' },
singlePointList: { type: 'connection', name: 'SinglePoint' },
totalPoints: { type: 'set', name: 'TotalPoints' },
totalPointsList: { type: 'connection', name: 'TotalPoints' },
},
}
2 changes: 1 addition & 1 deletion demo/simple/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "demo",
"version": "1.0.0",
"dependencies": {
"@ceramicnetwork/http-client": "^5.5.0",
"@ceramicnetwork/http-client": "^5.6.0",
"@composexp/did-utils": "workspace:^",
"@composexp/points": "workspace:^",
"uint8arrays": "^5.0.3"
Expand Down
4 changes: 2 additions & 2 deletions libraries/points/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@
"prepublishOnly": "package-check"
},
"dependencies": {
"@ceramicnetwork/http-client": "^5.5.0",
"@ceramicnetwork/http-client": "^5.6.0",
"@composedb/loader": "^0.7.1",
"@composexp/points-composite": "workspace:^",
"dids": "^5.0.2",
"key-did-provider-ed25519": "^4.0.2",
"key-did-resolver": "^4.0.0"
},
"devDependencies": {
"@ceramicnetwork/common": "^5.4.0",
"@ceramicnetwork/common": "^5.5.0",
"@composedb/types": "^0.7.1",
"@composexp/ceramic-utils": "workspace:^",
"@composexp/composite-utils": "workspace:^",
Expand Down
26 changes: 16 additions & 10 deletions libraries/points/src/points-reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { getCeramic } from './ceramic.js'
import { getQueryForRecipient, queryConnection } from './query.js'
import type { QueryDocumentsOptions, QueryDocumentsResult } from './types.js'

export function toUniqueArg(value: string | Array<string>): Array<string> {
return Array.isArray(value) ? value : [value]
}

export type MultiplePointsContent = {
recipient: string
points: number
Expand Down Expand Up @@ -40,8 +44,8 @@ export class PointsReader<

constructor(params: PointsReaderParams) {
const ceramic = getCeramic(params.ceramic)
const aggregationModelID = params.aggregationModelID ?? definition.models.TotalPoints!.id
const allocationModelID = params.allocationModelID ?? definition.models.MultiplePoints!.id
const aggregationModelID = params.aggregationModelID ?? definition.models.TotalPoints.id
const allocationModelID = params.allocationModelID ?? definition.models.MultiplePoints.id

this.#aggregationBaseQuery = { account: params.issuer, models: [aggregationModelID] }
this.#aggregationModelID = aggregationModelID
Expand Down Expand Up @@ -69,25 +73,27 @@ export class PointsReader<
}

async loadAggregationDocumentFor(
setFields: Array<string>,
didOrValues: string | Array<string>,
options: DeterministicLoadOptions = {},
): Promise<ModelInstanceDocument<AggregationContent> | null> {
return await this.#loader.loadSet(this.#issuer, this.#aggregationModelID, setFields, {
ignoreEmpty: true,
...options,
})
return await this.#loader.loadSet(
this.#issuer,
this.#aggregationModelID,
toUniqueArg(didOrValues),
{ ignoreEmpty: true, ...options },
)
}

async loadAggregationDocumentsFor(
did: string,
options?: QueryDocumentsOptions,
): Promise<QueryDocumentsResult<AggregationContent[]>> {
): Promise<QueryDocumentsResult<AggregationContent>> {
const query = getQueryForRecipient(this.#aggregationBaseQuery, did)
return await queryConnection(this.#loader, query, options)
}

async getAggregationPointsFor(did: string): Promise<number> {
const doc = await this.loadAggregationDocumentFor([did]) // Fix: Pass 'did' as an array
async getAggregationPointsFor(didOrValues: string | Array<string>): Promise<number> {
const doc = await this.loadAggregationDocumentFor(didOrValues)
return doc?.content?.points ?? 0
}

Expand Down
41 changes: 22 additions & 19 deletions libraries/points/src/points-writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
type MultiplePointsContent,
PointsReader,
type TotalPointsContent,
toUniqueArg,
} from './points-reader.js'

export type PointsWriterFromSeedParams = {
Expand Down Expand Up @@ -66,29 +67,31 @@ export class PointsWriter<
await doc.shouldIndex(false)
}

async setPointsAggregationFor(
setFields: string | Array<object>,
points: number,
content: Partial<AggregationContent> = {},
async updatePointsAggregationFor(
didOrValues: string | Array<string>,
update: (content: AggregationContent | null) => Partial<AggregationContent>,
): Promise<ModelInstanceDocument<AggregationContent>> {
const normalize = Array.isArray(setFields) ? setFields : [setFields]
let emptyObject = {}
const mapped = normalize.map((setFieldItem) => {
if (typeof setFieldItem === 'object') {
const value = Object.values(setFieldItem).join('')
emptyObject = { ...emptyObject, ...setFieldItem }
return value
}
return setFieldItem
})

const doc = await this.loadAggregationDocumentFor(mapped, {
const unique = toUniqueArg(didOrValues)
const doc = await this.loadAggregationDocumentFor(unique, {
ignoreEmpty: false,
onlyIndexed: false,
})
const date = new Date().toISOString()
points = (doc?.content?.points || 0) + points;
await doc!.replace({ date, ...content, points, ...emptyObject } as AggregationContent)
const content = doc!.content
await doc!.replace({
// Copy existing content or set recipient (assuming it's the first value)
...(content ?? { recipient: unique[0] }),
// Apply content update
...update(content),
} as AggregationContent)
return doc!
}

async setPointsAggregationFor(
didOrValues: string | Array<string>,
points: number,
content: Partial<AggregationContent> = {},
): Promise<ModelInstanceDocument<AggregationContent>> {
const date = new Date().toISOString()
return await this.updatePointsAggregationFor(didOrValues, () => ({ date, ...content, points }))
}
}
3 changes: 1 addition & 2 deletions libraries/points/src/single-reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import type { QueryDocumentsOptions, QueryDocumentsResult } from './types.js'

export type SinglePointContent = {
recipient: string
id: string
}

export type SinglePointReaderParams = {
Expand All @@ -27,7 +26,7 @@ export class SinglePointReader<Content extends SinglePointContent = SinglePointC

constructor(params: SinglePointReaderParams) {
const ceramic = getCeramic(params.ceramic)
const modelID = params.modelID ?? definition.models.SinglePoint!.id
const modelID = params.modelID ?? definition.models.SinglePoint.id

this.#baseQuery = { account: params.issuer, models: [modelID] }
this.#ceramic = ceramic
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
"@jest/globals": "^29.7.0",
"@skypack/package-check": "^0.2.2",
"@swc/cli": "^0.3.12",
"@swc/core": "^1.4.2",
"@swc/core": "^1.4.12",
"@swc/jest": "^0.2.36",
"@types/jest": "^29.5.12",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"del-cli": "^5.1.0",
"eslint": "^8.57.0",
"eslint-config-3box": "^1.0.0",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jest": "^28.2.0",
"jest": "^29.7.0",
"prettier": "^3.2.5",
"turbo": "^1.13.2",
"typedoc": "0.25.12",
"typedoc": "0.25.13",
"typedoc-plugin-markdown": "^3.17.1",
"typescript": "^5.4.3"
"typescript": "^5.4.4"
},
"pnpm": {
"overrides": {}
Expand Down
Loading

0 comments on commit 91de0e4

Please sign in to comment.