Skip to content

Commit

Permalink
DRY kv/set (#2319)
Browse files Browse the repository at this point in the history
* DRY kv/set

* Fix missing selector

* Rename selector

* Add comments
  • Loading branch information
corrideat authored Sep 17, 2024
1 parent c93398f commit e03e16b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 18 deletions.
33 changes: 15 additions & 18 deletions frontend/controller/actions/identity-kv.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,11 @@ export default (sbp('sbp/selectors/register', {
// because it uses fields of the identity contract state including height, cek, csk
// this conflict error can cause the heisenbug mostly in Cypress
// https://okturtles.slack.com/archives/C0EH7P20Y/p1720053305870019?thread_ts=1720025185.746849&cid=C0EH7P20Y
return sbp('chelonia/queueInvocation', identityContractID, () => {
return sbp('chelonia/kv/set', identityContractID, KV_KEYS.UNREAD_MESSAGES, data, {
encryptionKeyId: sbp('chelonia/contract/currentKeyIdByName', identityContractID, 'cek'),
signingKeyId: sbp('chelonia/contract/currentKeyIdByName', identityContractID, 'csk'),
onconflict
})
return sbp('chelonia/kv/queuedSet', {
contractID: identityContractID,
key: KV_KEYS.UNREAD_MESSAGES,
data,
onconflict
})
},
'gi.actions/identity/kv/loadChatRoomUnreadMessages': () => {
Expand Down Expand Up @@ -183,12 +182,11 @@ export default (sbp('sbp/selectors/register', {
throw new Error('Unable to update preferences without an active session')
}

return sbp('chelonia/queueInvocation', identityContractID, () => {
return sbp('chelonia/kv/set', identityContractID, KV_KEYS.PREFERENCES, data, {
encryptionKeyId: sbp('chelonia/contract/currentKeyIdByName', identityContractID, 'cek'),
signingKeyId: sbp('chelonia/contract/currentKeyIdByName', identityContractID, 'csk'),
onconflict
})
return sbp('chelonia/kv/queuedSet', {
contractID: identityContractID,
key: KV_KEYS.PREFERENCES,
data,
onconflict
})
},
'gi.actions/identity/kv/loadPreferences': () => {
Expand Down Expand Up @@ -243,12 +241,11 @@ export default (sbp('sbp/selectors/register', {
return null
}

return sbp('chelonia/queueInvocation', identityContractID, () => {
return sbp('chelonia/kv/set', identityContractID, KV_KEYS.NOTIFICATIONS, applyStorageRules(data), {
encryptionKeyId: sbp('chelonia/contract/currentKeyIdByName', identityContractID, 'cek'),
signingKeyId: sbp('chelonia/contract/currentKeyIdByName', identityContractID, 'csk'),
onconflict: updatedOnConflict
})
return sbp('chelonia/kv/queuedSet', {
contractID: identityContractID,
key: KV_KEYS.NOTIFICATIONS,
data: applyStorageRules(data),
onconflict: updatedOnConflict
})
},
'gi.actions/identity/kv/loadNotificationStatus': () => {
Expand Down
20 changes: 20 additions & 0 deletions shared/domains/chelonia/chelonia-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import sbp from '@sbp/sbp'

export default (sbp('sbp/selectors/register', {
// This selector is a wrapper for the `chelonia/kv/set` selector that uses
// the contract queue and allows referring to keys by name, with default key
// names set to `csk` and `cek` for signatures and encryption, respectively.
// For most 'simple' use cases, this selector is a better choice than
// `chelonia/kv/set`. However, the `chelonia/kv/set` primitive is needed if
// the queueing logic needs to be more advanced, the key to use requires
// custom logic or _if the `onconflict` callback also needs to be queued_.
'chelonia/kv/queuedSet': ({ contractID, key, data, onconflict, encryptionKeyName = 'cek', signingKeyName = 'csk' }) => {
return sbp('chelonia/queueInvocation', contractID, () => {
return sbp('chelonia/kv/set', contractID, key, data, {
encryptionKeyId: sbp('chelonia/contract/currentKeyIdByName', contractID, encryptionKeyName),
signingKeyId: sbp('chelonia/contract/currentKeyIdByName', contractID, signingKeyName),
onconflict
})
})
}
}): string[])
9 changes: 9 additions & 0 deletions shared/domains/chelonia/chelonia.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { CHELONIA_RESET, CONTRACTS_MODIFIED, CONTRACT_REGISTERED } from './event
// TODO: rename this to ChelMessage
import { GIMessage } from './GIMessage.js'
import type { Secret } from './Secret.js'
import './chelonia-utils.js'
import type { EncryptedData } from './encryptedData.js'
import { encryptedOutgoingData, isEncryptedData, maybeEncryptedIncomingData, unwrapMaybeEncryptedData } from './encryptedData.js'
import './files.js'
Expand Down Expand Up @@ -1466,6 +1467,14 @@ export default (sbp('sbp/selectors/register', {
})
this.pubsub.pub(contractID, serializedData)
},
// Note: This is a bare-bones function designed for precise control. In many
// situations, the `chelonia/kv/queuedSet` selector (in chelonia-utils.js)
// will be simpler and more appropriate to use.
// In most situations, you want to use some queuing strategy (which this
// selector doesn't provide) alongside writing to the KV store. Therefore, as
// a general rule, you shouldn't be calling this selector directly unless
// you're building a utility library or if you have very specific needs. In
// this case, see if `chelonia/kv/queuedSet` covers your needs.
'chelonia/kv/set': async function (contractID: string, key: string, data: Object, {
innerSigningKeyId,
encryptionKeyId,
Expand Down

0 comments on commit e03e16b

Please sign in to comment.