UNPKG

@metamask/ocap-kernel

Version:
1 lines 11.1 kB
{"version":3,"file":"base.mjs","sourceRoot":"","sources":["../../../src/store/methods/base.ts"],"names":[],"mappings":"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","sourcesContent":["import type { KVStore } from '@metamask/kernel-store';\n\nimport type { EndpointId, KRef } from '../../types.ts';\nimport type { StoredQueue, StoredValue } from '../types.ts';\n\n/**\n * Get the base store methods for managing stored values and queues.\n *\n * @param kv - The key/value store to provide the underlying persistence mechanism.\n * @returns An object with methods for managing stored values and queues.\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function getBaseMethods(kv: KVStore) {\n /**\n * Get the key for the reachable flag and vatSlot for a given endpoint and kref.\n *\n * @param endpointId - The endpoint for which the reachable flag is being set.\n * @param kref - The kref.\n * @returns The key for the reachable flag and vatSlot.\n */\n function getSlotKey(endpointId: EndpointId, kref: KRef): string {\n return `${endpointId}.c.${kref}`;\n }\n\n /**\n * Generate the storage key for a kernel entity's reference count.\n *\n * @param kref - The KRef of interest.\n * @returns the key to store the indicated reference count at.\n */\n function refCountKey(kref: KRef): string {\n return `${kref}.refCount`;\n }\n\n /**\n * Generate the storage key for a kernel entity's owner.\n *\n * @param kref - The KRef of interest.\n * @returns the key to store the indicated owner at.\n */\n function getOwnerKey(kref: KRef): string {\n return `${kref}.owner`;\n }\n\n /**\n * Generate the storage key for a kernel entity's revoked flag.\n *\n * @param kref - The KRef of interest.\n * @returns the key to store the indicated revoked flag at.\n */\n function getRevokedKey(kref: KRef): string {\n return `${kref}.revoked`;\n }\n\n /**\n * Increment the value of a persistently stored counter.\n *\n * Note that the while the value is interpreted as an integer (in order to\n * enable it to be incremented), it is stored and returned in the form of a\n * string. This is because (a) our persistent storage only stores strings, and\n * (b) the sole purpose of one of these counters is simply to provide an\n * unending sequence of unique values; we don't actually use them as numbers\n * or, indeed, even care at all if this sequence is produced using numbers.\n *\n * @param value - Reference to the stored value to be incremented.\n * @returns The value as it was prior to being incremented.\n */\n function incCounter(value: StoredValue): string {\n const current = value.get();\n const next = `${Number(current) + 1}`;\n value.set(next);\n return current as string;\n }\n\n /**\n * Provide a stored value object for which we keep an in-memory cache. We only\n * touch persistent storage if the value hasn't ever been read of if it is\n * modified; otherwise we can service read requests from memory.\n *\n * IMPORTANT NOTE: in order for the cache to work, all subsequent accesses to\n * the value MUST be made through a common stored value object.\n *\n * @param key - A key string that identifies the value.\n * @param init - If provided, an initial setting if the stored entity does not exist.\n * @returns An object for interacting with the value.\n */\n function provideCachedStoredValue(key: string, init?: string): StoredValue {\n let value: string | undefined = kv.get(key);\n if (value === undefined && init !== undefined) {\n kv.set(key, init);\n value = init;\n }\n return harden({\n get(): string | undefined {\n return value;\n },\n set(newValue: string): void {\n value = newValue;\n kv.set(key, value);\n },\n delete(): void {\n value = undefined;\n kv.delete(key);\n },\n });\n }\n\n /**\n * Provide a stored value object that is kept in persistent storage without caching.\n *\n * @param key - A key string that identifies the value.\n * @param init - If provided, an initial setting if the stored entity does not exist.\n * @returns An object for interacting with the value.\n */\n function provideRawStoredValue(key: string, init?: string): StoredValue {\n if (kv.get(key) === undefined && init !== undefined) {\n kv.set(key, init);\n }\n return harden({\n get: () => kv.get(key),\n set: (newValue: string) => kv.set(key, newValue),\n delete: () => kv.delete(key),\n });\n }\n\n /**\n * Produce an object to access a persistently stored queue.\n *\n * @param queueName - The name for the queue (must be unique among queues).\n * @param cached - Optional flag: set to true if the queue should cache its\n * limit indices in memory (only do this if the queue is going to be accessed or\n * checked frequently).\n * @returns An object for interacting with the queue.\n */\n function provideStoredQueue(\n queueName: string,\n cached: boolean = false,\n ): StoredQueue {\n const qk = `queue.${queueName}`;\n // Note: cached=true ==> caches only the head & tail indices, NOT the queue entries themselves\n const provideValue = cached\n ? provideCachedStoredValue\n : provideRawStoredValue;\n const head = provideValue(`${qk}.head`, '1');\n const tail = provideValue(`${qk}.tail`, '1');\n if (head.get() === undefined || tail.get() === undefined) {\n throw Error(`queue ${queueName} not initialized`);\n }\n return {\n enqueue(item: object): void {\n if (head.get() === undefined) {\n throw Error(`enqueue into deleted queue ${queueName}`);\n }\n const entryPos = incCounter(head);\n kv.set(`${qk}.${entryPos}`, JSON.stringify(item));\n },\n dequeue(): object | undefined {\n const headPos = head.get();\n if (headPos === undefined) {\n return undefined;\n }\n const tailPos = tail.get();\n if (tailPos !== headPos) {\n const entry = kv.getRequired(`${qk}.${tailPos}`);\n kv.delete(`${qk}.${tailPos}`);\n incCounter(tail);\n return JSON.parse(entry) as object;\n }\n return undefined;\n },\n delete(): void {\n const headPos = head.get();\n if (headPos !== undefined) {\n let tailPos = tail.get();\n while (tailPos !== headPos) {\n kv.delete(`${qk}.${tailPos}`);\n tailPos = `${Number(tailPos) + 1}`;\n }\n head.delete();\n tail.delete();\n }\n },\n };\n }\n\n /**\n * Generator that yields all the keys beginning with a given prefix.\n *\n * @param prefix - The prefix of interest.\n *\n * @yields the keys that start with `prefix`.\n */\n function* getPrefixedKeys(prefix: string): Generator<string> {\n let key: string | undefined = prefix;\n for (;;) {\n key = kv.getNextKey(key);\n if (!key) {\n break;\n }\n if (!key.startsWith(prefix)) {\n break;\n }\n yield key;\n }\n }\n\n return {\n getSlotKey,\n refCountKey,\n getOwnerKey,\n getRevokedKey,\n incCounter,\n provideCachedStoredValue,\n provideRawStoredValue,\n provideStoredQueue,\n getPrefixedKeys,\n };\n}\n"]}