openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
725 lines (724 loc) • 26.2 kB
JavaScript
import { C as resolveExpiresAtMsFromDurationMs } from "./number-coercion-CJQ8TR--.js";
import { c as resolveOpenClawStateSqlitePath, d as executeSqliteQuerySync, f as executeSqliteQueryTakeFirstSync, i as openOpenClawStateDatabase, n as closeOpenClawStateDatabase, o as runOpenClawStateWriteTransaction, p as getNodeSqliteKysely } from "./openclaw-state-db-ULtH_b7x.js";
import "./sqlite-wal-CP9DVd__.js";
//#region src/plugin-state/plugin-state-store.types.ts
/** Typed error thrown for plugin-state validation and sqlite failures. */
var PluginStateStoreError = class extends Error {
constructor(message, options) {
super(message, { cause: options.cause });
this.name = "PluginStateStoreError";
this.code = options.code;
this.operation = options.operation;
if (options.path) this.path = options.path;
}
};
const MAX_PLUGIN_STATE_ENTRIES_PER_PLUGIN = 5e4;
let cachedDatabase = null;
function normalizeNumber(value) {
if (typeof value === "bigint") return Number(value);
return typeof value === "number" ? value : void 0;
}
function createPluginStateError(params) {
return new PluginStateStoreError(params.message, {
code: params.code,
operation: params.operation,
...params.path ? { path: params.path } : {},
cause: params.cause
});
}
function resolvePluginStateExpiresAtMs(params) {
if (params.ttlMs == null) return null;
const expiresAt = resolveExpiresAtMsFromDurationMs(params.ttlMs, { nowMs: params.now });
if (expiresAt === void 0) throw createPluginStateError({
code: "PLUGIN_STATE_INVALID_INPUT",
operation: params.operation,
message: "Plugin state ttlMs cannot produce a valid expiry timestamp.",
...params.path ? { path: params.path } : {}
});
return expiresAt;
}
function wrapPluginStateError(error, operation, fallbackCode, message, pathname = resolveOpenClawStateSqlitePath(process.env)) {
if (error instanceof PluginStateStoreError) return error;
return createPluginStateError({
code: fallbackCode,
operation,
message,
path: pathname,
cause: error
});
}
function parseStoredJson(raw, operation) {
try {
return JSON.parse(raw);
} catch (error) {
throw createPluginStateError({
code: "PLUGIN_STATE_CORRUPT",
operation,
message: "Plugin state entry contains corrupt JSON.",
path: resolveOpenClawStateSqlitePath(process.env),
cause: error
});
}
}
function rowToEntry(row, operation) {
const expiresAt = normalizeNumber(row.expires_at);
return {
key: row.entry_key,
value: parseStoredJson(row.value_json, operation),
createdAt: normalizeNumber(row.created_at) ?? 0,
...expiresAt != null ? { expiresAt } : {}
};
}
function getPluginStateKysely(db) {
return getNodeSqliteKysely(db);
}
function bindPluginStateEntry(params) {
return {
plugin_id: params.pluginId,
namespace: params.namespace,
entry_key: params.key,
value_json: params.valueJson,
created_at: params.createdAt,
expires_at: params.expiresAt
};
}
function upsertPluginStateEntry(db, row) {
executeSqliteQuerySync(db, getPluginStateKysely(db).insertInto("plugin_state_entries").values(row).onConflict((conflict) => conflict.columns([
"plugin_id",
"namespace",
"entry_key"
]).doUpdateSet({
value_json: (eb) => eb.ref("excluded.value_json"),
created_at: (eb) => eb.ref("excluded.created_at"),
expires_at: (eb) => eb.ref("excluded.expires_at")
})));
}
function insertPluginStateEntryIfAbsent(db, row) {
const result = executeSqliteQuerySync(db, getPluginStateKysely(db).insertInto("plugin_state_entries").orIgnore().values(row));
return Number(result.numAffectedRows ?? 0) > 0;
}
function selectPluginStateEntry(db, params) {
return executeSqliteQueryTakeFirstSync(db, getPluginStateKysely(db).selectFrom("plugin_state_entries").select([
"plugin_id",
"namespace",
"entry_key",
"value_json",
"created_at",
"expires_at"
]).where("plugin_id", "=", params.pluginId).where("namespace", "=", params.namespace).where("entry_key", "=", params.key).where((eb) => eb.or([eb("expires_at", "is", null), eb("expires_at", ">", params.now)])));
}
function selectPluginStateEntries(db, params) {
return executeSqliteQuerySync(db, getPluginStateKysely(db).selectFrom("plugin_state_entries").select([
"plugin_id",
"namespace",
"entry_key",
"value_json",
"created_at",
"expires_at"
]).where("plugin_id", "=", params.pluginId).where("namespace", "=", params.namespace).where((eb) => eb.or([eb("expires_at", "is", null), eb("expires_at", ">", params.now)])).orderBy("created_at", "asc").orderBy("entry_key", "asc")).rows;
}
function deletePluginStateEntry(db, params) {
const result = executeSqliteQuerySync(db, getPluginStateKysely(db).deleteFrom("plugin_state_entries").where("plugin_id", "=", params.pluginId).where("namespace", "=", params.namespace).where("entry_key", "=", params.key));
return Number(result.numAffectedRows ?? 0);
}
function deleteExpiredPluginStateNamespaceEntries(db, params) {
executeSqliteQuerySync(db, getPluginStateKysely(db).deleteFrom("plugin_state_entries").where("plugin_id", "=", params.pluginId).where("namespace", "=", params.namespace).where("expires_at", "is not", null).where("expires_at", "<=", params.now));
}
function countLivePluginStateNamespaceEntries(db, params) {
return countRow(executeSqliteQueryTakeFirstSync(db, getPluginStateKysely(db).selectFrom("plugin_state_entries").select((eb) => eb.fn.countAll().as("count")).where("plugin_id", "=", params.pluginId).where("namespace", "=", params.namespace).where((eb) => eb.or([eb("expires_at", "is", null), eb("expires_at", ">", params.now)]))));
}
function countLivePluginStateEntries(db, params) {
return countRow(executeSqliteQueryTakeFirstSync(db, getPluginStateKysely(db).selectFrom("plugin_state_entries").select((eb) => eb.fn.countAll().as("count")).where("plugin_id", "=", params.pluginId).where((eb) => eb.or([eb("expires_at", "is", null), eb("expires_at", ">", params.now)]))));
}
function deleteOldestPluginStateNamespaceEntries(db, params) {
const keys = executeSqliteQuerySync(db, getPluginStateKysely(db).selectFrom("plugin_state_entries").select(["entry_key"]).where("plugin_id", "=", params.pluginId).where("namespace", "=", params.namespace).where("entry_key", "!=", params.protectedKey).where((eb) => eb.or([eb("expires_at", "is", null), eb("expires_at", ">", params.now)])).orderBy("created_at", "asc").orderBy("entry_key", "asc").limit(params.limit)).rows;
for (const row of keys) deletePluginStateEntry(db, {
pluginId: params.pluginId,
namespace: params.namespace,
key: row.entry_key
});
}
function sweepExpiredPluginStateEntriesFromDatabase(db, now) {
const result = executeSqliteQuerySync(db, getPluginStateKysely(db).deleteFrom("plugin_state_entries").where("expires_at", "is not", null).where("expires_at", "<=", now));
return Number(result.numAffectedRows ?? 0);
}
function openPluginStateDatabase(operation = "open", options = {}) {
const pathname = resolveOpenClawStateSqlitePath(options.env ?? process.env);
if (cachedDatabase && cachedDatabase.path === pathname && cachedDatabase.db.isOpen) return cachedDatabase;
if (cachedDatabase && !cachedDatabase.db.isOpen) cachedDatabase = null;
try {
const database = openOpenClawStateDatabase(options);
cachedDatabase = {
db: database.db,
path: database.path
};
return cachedDatabase;
} catch (error) {
throw wrapPluginStateError(error, operation, "PLUGIN_STATE_OPEN_FAILED", "Failed to open the plugin state database.", pathname);
}
}
function countRow(row) {
const raw = row?.count ?? 0;
return typeof raw === "bigint" ? Number(raw) : raw;
}
function envOptions(env) {
return env ? { env } : {};
}
function runWriteTransaction(operation, write, options = {}) {
const store = openPluginStateDatabase(operation, options);
return runOpenClawStateWriteTransaction(() => {
return write(store);
}, options);
}
function enforcePostRegisterLimits(params) {
const namespaceCount = countLivePluginStateNamespaceEntries(params.store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
now: params.now
});
if (namespaceCount > params.maxEntries) deleteOldestPluginStateNamespaceEntries(params.store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
protectedKey: params.protectedKey,
now: params.now,
limit: namespaceCount - params.maxEntries
});
const pluginCount = countLivePluginStateEntries(params.store.db, {
pluginId: params.pluginId,
now: params.now
});
const maxPluginEntries = resolveMaxPluginStateEntriesPerPlugin();
if (pluginCount <= maxPluginEntries) return;
deleteOldestPluginStateNamespaceEntries(params.store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
protectedKey: params.protectedKey,
now: params.now,
limit: pluginCount - maxPluginEntries
});
if (countLivePluginStateEntries(params.store.db, {
pluginId: params.pluginId,
now: params.now
}) > maxPluginEntries) throw createPluginStateError({
code: "PLUGIN_STATE_LIMIT_EXCEEDED",
operation: "register",
message: `Plugin state for ${params.pluginId} exceeds the ${maxPluginEntries} live row limit.`,
path: params.store.path
});
}
function resolveMaxPluginStateEntriesPerPlugin() {
return 5e4;
}
function pluginStateRegister(params) {
try {
runWriteTransaction("register", (store) => {
const now = Date.now();
const expiresAt = resolvePluginStateExpiresAtMs({
ttlMs: params.ttlMs,
now,
operation: "register",
path: store.path
});
deleteExpiredPluginStateNamespaceEntries(store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
now
});
upsertPluginStateEntry(store.db, bindPluginStateEntry({
pluginId: params.pluginId,
namespace: params.namespace,
key: params.key,
valueJson: params.valueJson,
createdAt: now,
expiresAt
}));
enforcePostRegisterLimits({
store,
pluginId: params.pluginId,
namespace: params.namespace,
maxEntries: params.maxEntries,
now,
protectedKey: params.key
});
}, envOptions(params.env));
} catch (error) {
throw wrapPluginStateError(error, "register", "PLUGIN_STATE_WRITE_FAILED", "Failed to register plugin state entry.");
}
}
function pluginStateRegisterIfAbsent(params) {
try {
return runWriteTransaction("register", (store) => {
const now = Date.now();
const expiresAt = resolvePluginStateExpiresAtMs({
ttlMs: params.ttlMs,
now,
operation: "register",
path: store.path
});
deleteExpiredPluginStateNamespaceEntries(store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
now
});
if (!insertPluginStateEntryIfAbsent(store.db, bindPluginStateEntry({
pluginId: params.pluginId,
namespace: params.namespace,
key: params.key,
valueJson: params.valueJson,
createdAt: now,
expiresAt
}))) return false;
enforcePostRegisterLimits({
store,
pluginId: params.pluginId,
namespace: params.namespace,
maxEntries: params.maxEntries,
now,
protectedKey: params.key
});
return true;
}, envOptions(params.env));
} catch (error) {
throw wrapPluginStateError(error, "register", "PLUGIN_STATE_WRITE_FAILED", "Failed to register plugin state entry.");
}
}
function pluginStateUpdate(params) {
try {
return runWriteTransaction("register", (store) => {
const now = Date.now();
deleteExpiredPluginStateNamespaceEntries(store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
now
});
const existing = selectPluginStateEntry(store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
key: params.key,
now
});
const next = params.updateValueJson(existing ? parseStoredJson(existing.value_json, "lookup") : void 0);
if (!next) return false;
const expiresAt = resolvePluginStateExpiresAtMs({
ttlMs: next.ttlMs,
now,
operation: "register",
path: store.path
});
upsertPluginStateEntry(store.db, bindPluginStateEntry({
pluginId: params.pluginId,
namespace: params.namespace,
key: params.key,
valueJson: next.valueJson,
createdAt: now,
expiresAt
}));
enforcePostRegisterLimits({
store,
pluginId: params.pluginId,
namespace: params.namespace,
maxEntries: params.maxEntries,
now,
protectedKey: params.key
});
return true;
}, envOptions(params.env));
} catch (error) {
throw wrapPluginStateError(error, "register", "PLUGIN_STATE_WRITE_FAILED", "Failed to update plugin state entry.");
}
}
function pluginStateLookup(params) {
try {
const { db } = openPluginStateDatabase("lookup", envOptions(params.env));
const row = selectPluginStateEntry(db, {
pluginId: params.pluginId,
namespace: params.namespace,
key: params.key,
now: Date.now()
});
return row ? parseStoredJson(row.value_json, "lookup") : void 0;
} catch (error) {
throw wrapPluginStateError(error, "lookup", "PLUGIN_STATE_READ_FAILED", "Failed to read plugin state entry.");
}
}
function pluginStateConsume(params) {
try {
return runWriteTransaction("consume", (store) => {
const row = selectPluginStateEntry(store.db, {
pluginId: params.pluginId,
namespace: params.namespace,
key: params.key,
now: Date.now()
});
if (!row) return;
deletePluginStateEntry(store.db, params);
return parseStoredJson(row.value_json, "consume");
}, envOptions(params.env));
} catch (error) {
throw wrapPluginStateError(error, "consume", "PLUGIN_STATE_READ_FAILED", "Failed to consume plugin state entry.");
}
}
function pluginStateDelete(params) {
try {
return runWriteTransaction("delete", ({ db }) => {
return deletePluginStateEntry(db, params) > 0;
}, envOptions(params.env));
} catch (error) {
throw wrapPluginStateError(error, "delete", "PLUGIN_STATE_WRITE_FAILED", "Failed to delete plugin state entry.");
}
}
function pluginStateEntries(params) {
try {
const { db } = openPluginStateDatabase("entries", envOptions(params.env));
return selectPluginStateEntries(db, {
pluginId: params.pluginId,
namespace: params.namespace,
now: Date.now()
}).map((row) => rowToEntry(row, "entries"));
} catch (error) {
throw wrapPluginStateError(error, "entries", "PLUGIN_STATE_READ_FAILED", "Failed to list plugin state entries.");
}
}
function pluginStateClear(params) {
try {
runWriteTransaction("clear", ({ db }) => {
executeSqliteQuerySync(db, getPluginStateKysely(db).deleteFrom("plugin_state_entries").where("plugin_id", "=", params.pluginId).where("namespace", "=", params.namespace));
}, envOptions(params.env));
} catch (error) {
throw wrapPluginStateError(error, "clear", "PLUGIN_STATE_WRITE_FAILED", "Failed to clear plugin state namespace.");
}
}
function sweepExpiredPluginStateEntries() {
try {
return runWriteTransaction("sweep", ({ db }) => sweepExpiredPluginStateEntriesFromDatabase(db, Date.now()));
} catch (error) {
throw wrapPluginStateError(error, "sweep", "PLUGIN_STATE_WRITE_FAILED", "Failed to sweep expired plugin state entries.");
}
}
function isPluginStateDatabaseOpen() {
return cachedDatabase?.db.isOpen === true;
}
function countPluginStateLiveEntries(pluginId) {
try {
const { db } = openPluginStateDatabase("entries");
return countLivePluginStateEntries(db, {
pluginId,
now: Date.now()
});
} catch (error) {
throw wrapPluginStateError(error, "entries", "PLUGIN_STATE_READ_FAILED", "Failed to count plugin state entries.");
}
}
function closePluginStateDatabase() {
cachedDatabase = null;
closeOpenClawStateDatabase();
}
const closePluginStateSqliteStore = closePluginStateDatabase;
//#endregion
//#region src/plugin-state/plugin-state-store.ts
const NAMESPACE_PATTERN = /^[a-z0-9][a-z0-9._-]*$/iu;
const MAX_NAMESPACE_BYTES = 128;
const MAX_KEY_BYTES = 512;
const MAX_JSON_DEPTH = 64;
const namespaceOptionSignatures = /* @__PURE__ */ new Map();
const textEncoder = new TextEncoder();
function invalidInput(message, operation = "register") {
return new PluginStateStoreError(message, {
code: "PLUGIN_STATE_INVALID_INPUT",
operation
});
}
function assertMaxBytes(label, value, max, operation = "register") {
if (textEncoder.encode(value).byteLength > max) throw invalidInput(`plugin state ${label} must be <= ${max} bytes`, operation);
}
function validateNamespace(value, operation = "open") {
const trimmed = value.trim();
if (!NAMESPACE_PATTERN.test(trimmed)) throw invalidInput(`plugin state namespace must be a safe path segment: ${value}`, operation);
assertMaxBytes("namespace", trimmed, MAX_NAMESPACE_BYTES, operation);
return trimmed;
}
function validateKey(value, operation = "register") {
const trimmed = value.trim();
if (!trimmed) throw invalidInput("plugin state entry key must not be empty", operation);
assertMaxBytes("entry key", trimmed, MAX_KEY_BYTES, operation);
return trimmed;
}
function validateMaxEntries(value) {
if (!Number.isInteger(value) || value < 1) throw invalidInput("plugin state maxEntries must be an integer >= 1", "open");
return value;
}
function validateOptionalTtlMs(value, operation = "register") {
if (value == null) return;
if (!Number.isSafeInteger(value) || value < 1) throw invalidInput("plugin state ttlMs must be a positive integer", operation);
return value;
}
function assertPlainJsonValue(value, seen, path, depth = 0) {
if (depth > MAX_JSON_DEPTH) throw new PluginStateStoreError(`plugin state value nesting exceeds maximum depth of ${MAX_JSON_DEPTH}`, {
code: "PLUGIN_STATE_LIMIT_EXCEEDED",
operation: "register"
});
if (value === null) return;
const valueType = typeof value;
if (valueType === "string" || valueType === "boolean") return;
if (valueType === "number") {
if (!Number.isFinite(value)) throw invalidInput(`plugin state value at ${path} must be a finite number`);
return;
}
if (valueType !== "object") throw invalidInput(`plugin state value at ${path} must be JSON-serializable`);
const objectValue = value;
if (seen.has(objectValue)) throw invalidInput(`plugin state value at ${path} must not contain circular references`);
seen.add(objectValue);
try {
if (Array.isArray(value)) {
for (let index = 0; index < value.length; index += 1) {
if (!(index in value)) throw invalidInput(`plugin state array at ${path} must not be sparse`);
assertPlainJsonValue(value[index], seen, `${path}[${index}]`, depth + 1);
}
return;
}
if (Object.getPrototypeOf(objectValue) !== Object.prototype) throw invalidInput(`plugin state object at ${path} must be a plain object`);
const descriptorEntries = Object.entries(Object.getOwnPropertyDescriptors(objectValue));
const enumerableKeys = Object.keys(objectValue);
if (Object.getOwnPropertySymbols(objectValue).length > 0) throw invalidInput(`plugin state object at ${path} must not use symbol keys`);
if (descriptorEntries.length !== enumerableKeys.length) throw invalidInput(`plugin state object at ${path} must not use non-enumerable properties`);
for (const [key, descriptor] of descriptorEntries) {
if (descriptor.get || descriptor.set || !("value" in descriptor)) throw invalidInput(`plugin state object at ${path}.${key} must use data properties`);
assertPlainJsonValue(descriptor.value, seen, `${path}.${key}`, depth + 1);
}
} finally {
seen.delete(objectValue);
}
}
function assertJsonSerializable(value) {
assertPlainJsonValue(value, /* @__PURE__ */ new WeakSet(), "value");
}
function assertValueSize(json) {
if (textEncoder.encode(json).byteLength > 65536) throw new PluginStateStoreError("plugin state value exceeds 64KB limit", {
code: "PLUGIN_STATE_LIMIT_EXCEEDED",
operation: "register"
});
}
function prepareRegisterParams(key, value, defaultTtlMs, opts) {
const normalizedKey = validateKey(key, "register");
assertJsonSerializable(value);
const json = JSON.stringify(value);
if (json === void 0) throw invalidInput("plugin state value must be JSON-serializable", "register");
assertValueSize(json);
const ttlMs = validateOptionalTtlMs(opts?.ttlMs, "register") ?? defaultTtlMs;
return {
key: normalizedKey,
valueJson: json,
...ttlMs != null ? { ttlMs } : {}
};
}
function assertConsistentOptions(pluginId, namespace, signature) {
const key = `${pluginId}\0${namespace}`;
const existing = namespaceOptionSignatures.get(key);
if (!existing) {
namespaceOptionSignatures.set(key, signature);
return;
}
if (existing.maxEntries !== signature.maxEntries || existing.defaultTtlMs !== signature.defaultTtlMs) throw invalidInput(`plugin state namespace ${namespace} for ${pluginId} was reopened with incompatible options`, "open");
}
function createKeyedStoreForPluginId(pluginId, options) {
const namespace = validateNamespace(options.namespace);
const maxEntries = validateMaxEntries(options.maxEntries);
const defaultTtlMs = validateOptionalTtlMs(options.defaultTtlMs);
const env = options.env;
assertConsistentOptions(pluginId, namespace, {
maxEntries,
defaultTtlMs
});
return {
async register(key, value, opts) {
const params = prepareRegisterParams(key, value, defaultTtlMs, opts);
pluginStateRegister({
pluginId,
namespace,
key: params.key,
valueJson: params.valueJson,
maxEntries,
...env ? { env } : {},
...params.ttlMs != null ? { ttlMs: params.ttlMs } : {}
});
},
async registerIfAbsent(key, value, opts) {
const params = prepareRegisterParams(key, value, defaultTtlMs, opts);
return pluginStateRegisterIfAbsent({
pluginId,
namespace,
key: params.key,
valueJson: params.valueJson,
maxEntries,
...env ? { env } : {},
...params.ttlMs != null ? { ttlMs: params.ttlMs } : {}
});
},
async update(key, updateValue, opts) {
const normalizedKey = validateKey(key, "register");
return pluginStateUpdate({
pluginId,
namespace,
key: normalizedKey,
maxEntries,
updateValueJson: (current) => {
const next = updateValue(current);
if (next === void 0) return;
const params = prepareRegisterParams(normalizedKey, next, defaultTtlMs, opts);
return {
valueJson: params.valueJson,
...params.ttlMs != null ? { ttlMs: params.ttlMs } : {}
};
},
...env ? { env } : {}
});
},
async lookup(key) {
return pluginStateLookup({
pluginId,
namespace,
key: validateKey(key, "lookup"),
...env ? { env } : {}
});
},
async consume(key) {
return pluginStateConsume({
pluginId,
namespace,
key: validateKey(key, "consume"),
...env ? { env } : {}
});
},
async delete(key) {
return pluginStateDelete({
pluginId,
namespace,
key: validateKey(key, "delete"),
...env ? { env } : {}
});
},
async entries() {
return pluginStateEntries({
pluginId,
namespace,
...env ? { env } : {}
});
},
async clear() {
pluginStateClear({
pluginId,
namespace,
...env ? { env } : {}
});
}
};
}
function createSyncKeyedStoreForPluginId(pluginId, options) {
const namespace = validateNamespace(options.namespace);
const maxEntries = validateMaxEntries(options.maxEntries);
const defaultTtlMs = validateOptionalTtlMs(options.defaultTtlMs);
const env = options.env;
assertConsistentOptions(pluginId, namespace, {
maxEntries,
defaultTtlMs
});
return {
register(key, value, opts) {
const params = prepareRegisterParams(key, value, defaultTtlMs, opts);
pluginStateRegister({
pluginId,
namespace,
key: params.key,
valueJson: params.valueJson,
maxEntries,
...env ? { env } : {},
...params.ttlMs != null ? { ttlMs: params.ttlMs } : {}
});
},
registerIfAbsent(key, value, opts) {
const params = prepareRegisterParams(key, value, defaultTtlMs, opts);
return pluginStateRegisterIfAbsent({
pluginId,
namespace,
key: params.key,
valueJson: params.valueJson,
maxEntries,
...env ? { env } : {},
...params.ttlMs != null ? { ttlMs: params.ttlMs } : {}
});
},
update(key, updateValue, opts) {
const normalizedKey = validateKey(key, "register");
return pluginStateUpdate({
pluginId,
namespace,
key: normalizedKey,
maxEntries,
updateValueJson: (current) => {
const next = updateValue(current);
if (next === void 0) return;
const params = prepareRegisterParams(normalizedKey, next, defaultTtlMs, opts);
return {
valueJson: params.valueJson,
...params.ttlMs != null ? { ttlMs: params.ttlMs } : {}
};
},
...env ? { env } : {}
});
},
lookup(key) {
return pluginStateLookup({
pluginId,
namespace,
key: validateKey(key, "lookup"),
...env ? { env } : {}
});
},
consume(key) {
return pluginStateConsume({
pluginId,
namespace,
key: validateKey(key, "consume"),
...env ? { env } : {}
});
},
delete(key) {
return pluginStateDelete({
pluginId,
namespace,
key: validateKey(key, "delete"),
...env ? { env } : {}
});
},
entries() {
return pluginStateEntries({
pluginId,
namespace,
...env ? { env } : {}
});
},
clear() {
pluginStateClear({
pluginId,
namespace,
...env ? { env } : {}
});
}
};
}
/** Opens an async plugin-state namespace for a non-core plugin id. */
function createPluginStateKeyedStore(pluginId, options) {
if (pluginId.startsWith("core:")) throw invalidInput("Plugin ids starting with 'core:' are reserved for core consumers.", "open");
return createKeyedStoreForPluginId(pluginId, options);
}
/** Opens a sync plugin-state namespace for a non-core plugin id. */
function createPluginStateSyncKeyedStore(pluginId, options) {
if (pluginId.startsWith("core:")) throw invalidInput("Plugin ids starting with 'core:' are reserved for core consumers.", "open");
return createSyncKeyedStoreForPluginId(pluginId, options);
}
/** Opens a sync plugin-state namespace for a trusted core owner id. */
function createCorePluginStateSyncKeyedStore(options) {
return createSyncKeyedStoreForPluginId(options.ownerId, options);
}
//#endregion
export { closePluginStateSqliteStore as a, sweepExpiredPluginStateEntries as c, MAX_PLUGIN_STATE_ENTRIES_PER_PLUGIN as i, createPluginStateKeyedStore as n, countPluginStateLiveEntries as o, createPluginStateSyncKeyedStore as r, isPluginStateDatabaseOpen as s, createCorePluginStateSyncKeyedStore as t };