Skip to content

Commit

Permalink
feat: emit updates from CoreOwnership and Roles, add CoreOwnership#get (
Browse files Browse the repository at this point in the history
#781)

This is part of the solution for [#268].

[#268]: #268

Co-authored-by: Gregor MacLennan <gmaclennan@digital-democracy.org>
  • Loading branch information
EvanHahn and gmaclennan committed Aug 27, 2024
1 parent 01e59ae commit ef555c7
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 11 deletions.
36 changes: 31 additions & 5 deletions src/core-ownership.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@ import { parseVersionId } from '@mapeo/schema'
import { defaultGetWinner } from '@mapeo/sqlite-indexer'
import assert from 'node:assert/strict'
import sodium from 'sodium-universal'
import { kTable, kSelect, kCreateWithDocId } from './datatype/index.js'
import {
kTable,
kSelect,
kCreateWithDocId,
kDataStore,
} from './datatype/index.js'
import { eq, or } from 'drizzle-orm'
import mapObject from 'map-obj'
import { discoveryKey } from 'hypercore-crypto'
import pDefer from 'p-defer'
import { NAMESPACES } from './constants.js'
import { TypedEmitter } from 'tiny-typed-emitter'
/**
* @import {
* CoreOwnershipWithSignatures,
Expand All @@ -18,7 +24,15 @@ import { NAMESPACES } from './constants.js'
* } from './types.js'
*/

export class CoreOwnership {
/**
* @typedef {object} CoreOwnershipEvents
* @property {(docIds: Set<string>) => void} update Emitted when new coreOwnership records are indexed
*/

/**
* @extends {TypedEmitter<CoreOwnershipEvents>}
*/
export class CoreOwnership extends TypedEmitter {
#dataType
#ownershipWriteDone
/**
Expand All @@ -35,8 +49,9 @@ export class CoreOwnership {
* @param {KeyPair} opts.identityKeypair
*/
constructor({ dataType, coreKeypairs, identityKeypair }) {
super()
this.#dataType = dataType
const authWriterCore = dataType.writerCore
const authWriterCore = dataType[kDataStore].writerCore
const deferred = pDefer()
this.#ownershipWriteDone = deferred.promise

Expand All @@ -55,6 +70,8 @@ export class CoreOwnership {
} else {
authWriterCore.once('ready', writeOwnership)
}

dataType[kDataStore].on('coreOwnership', this.emit.bind(this, 'update'))
}

/**
Expand Down Expand Up @@ -85,11 +102,20 @@ export class CoreOwnership {
* @returns {Promise<string>} coreId of core belonging to `deviceId` for `namespace`
*/
async getCoreId(deviceId, namespace) {
await this.#ownershipWriteDone
const result = await this.#dataType.getByDocId(deviceId)
const result = await this.get(deviceId)
return result[`${namespace}CoreId`]
}

/**
* Get capabilities for a given deviceId
*
* @param {string} deviceId
*/
async get(deviceId) {
await this.#ownershipWriteDone
return this.#dataType.getByDocId(deviceId)
}

/**
*
* @param {KeyPair} identityKeypair
Expand Down
5 changes: 3 additions & 2 deletions src/datatype/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface DataTypeEvents<TDoc extends MapeoDoc> {
export const kCreateWithDocId: unique symbol
export const kSelect: unique symbol
export const kTable: unique symbol
export const kDataStore: unique symbol

type OmitUnion<T, K extends keyof any> = T extends any ? Omit<T, K> : never
type ExcludeSchema<
Expand Down Expand Up @@ -62,12 +63,12 @@ export class DataType<

get [kTable](): TTable

get [kDataStore](): TDataStore

get schemaName(): TSchemaName

get namespace(): TDataStore.namespace

get writerCore(): Hypercore<'binary', Buffer>

[kCreateWithDocId](
docId: string,
value:
Expand Down
5 changes: 3 additions & 2 deletions src/datatype/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ function generateDate() {
export const kCreateWithDocId = Symbol('kCreateWithDocId')
export const kSelect = Symbol('select')
export const kTable = Symbol('table')
export const kDataStore = Symbol('dataStore')

/**
* @template {import('../datastore/index.js').DataStore} TDataStore
Expand Down Expand Up @@ -117,8 +118,8 @@ export class DataType extends TypedEmitter {
return this.#dataStore.namespace
}

get writerCore() {
return this.#dataStore.writerCore
get [kDataStore]() {
return this.#dataStore
}

/**
Expand Down
15 changes: 13 additions & 2 deletions src/roles.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { currentSchemaVersions } from '@mapeo/schema'
import mapObject from 'map-obj'
import { kCreateWithDocId } from './datatype/index.js'
import { kCreateWithDocId, kDataStore } from './datatype/index.js'
import { assert, setHas } from './utils.js'
import { TypedEmitter } from 'tiny-typed-emitter'
/** @import { Namespace } from './types.js' */

// Randomly generated 8-byte encoded as hex
Expand Down Expand Up @@ -214,7 +215,15 @@ export const ROLES = {
[NO_ROLE_ID]: NO_ROLE,
}

export class Roles {
/**
* @typedef {object} RolesEvents
* @property {(docIds: Set<string>) => void} update Emitted when new role records are indexed
*/

/**
* @extends {TypedEmitter<RolesEvents>}
*/
export class Roles extends TypedEmitter {
#dataType
#coreOwnership
#coreManager
Expand All @@ -239,11 +248,13 @@ export class Roles {
* @param {Buffer} opts.deviceKey public key of this device
*/
constructor({ dataType, coreOwnership, coreManager, projectKey, deviceKey }) {
super()
this.#dataType = dataType
this.#coreOwnership = coreOwnership
this.#coreManager = coreManager
this.#projectCreatorAuthCoreId = projectKey.toString('hex')
this.#ownDeviceId = deviceKey.toString('hex')
dataType[kDataStore].on('role', this.emit.bind(this, 'update'))
}

/**
Expand Down

0 comments on commit ef555c7

Please sign in to comment.