Skip to Content
Card SDKСправочник APIХранилище и настройки

Хранилище и настройки

Хранилище

У страницы карточки нет localStorage, indexedDB и cookies — в её песочнице нет источника (origin), к которому их можно привязать. Вместо них — card.storage: значения JSON, которые приложение атомарно хранит на диске и которые переживают перезагрузки, усыпление и перезапуски. Разрешение не нужно.

// This card on the canvas (instance scope). const draft = await card.storage.get('draft', '') // string, '' when missing await card.storage.set('draft', `${draft}\nmore`) await card.storage.set('runs', [{ at: Date.now(), failed: 3 }]) const runs = await card.storage.get<{ at: number; failed: number }[]>('runs') // undefined when missing await card.storage.delete('draft') const keys = await card.storage.keys('run:') // keys starting with a prefix const { bytes, quota } = await card.storage.usage() render(runs?.length, keys, bytes, quota) // Shared by every copy of this card, on every canvas (package scope). await card.storage.package.set('lastSync', Date.now()) card.storage.onChange(({ key, byInstance }) => { if (key === 'lastSync') render(`updated by card ${byInstance}`) })
МетодРезультат
get(key)Значение или undefined.
get(key, fallback)Значение или fallback. Результат типизирован по запасному значению.
set(key, value)Сохраняет любое значение JSON.
delete(key)
keys(prefix?)string[]
clear()Удаляет все ключи этой области.
usage(){ bytes, quota, keys }
onChange(handler)Другая копия этой карточки записала ключ пакета: { scope, key, byInstance }.

Те же методы есть у card.storage.package.

Лимиты: ключи до 256 символов, значения до 1 МБ, не больше 10 000 ключей; 5 МБ на карточку, 20 МБ на пакет. Превышение — QUOTA_EXCEEDED. Запись доходит до диска примерно за четверть секунды и сбрасывается при выходе из приложения.

Что с ним происходит: хранилище карточки удаляется вместе с карточкой. Хранилище пакета переживает удаление пакета, если пользователь не отметит Also delete its saved data and secrets. Обновления хранилище не трогают — держите сохранённые структуры читаемыми для новых версий (храните поле version, если можете их поменять).

Сохраняйтесь до выгрузки: карточку, скрытую какое-то время, усыпляют, и её страница выбрасывается. Записывайте то, что ещё в памяти, в card.lifecycle.onSuspend.

Настройки

Объявите поля в settings манифеста; приложение нарисует форму (из ⋯ → Settings… карточки или по вызову card.settings.open()), проверит её и сохранит значения. Ваша карточка их читает:

const command = card.settings.value<string>('command') ?? 'npm test' const all = card.settings.values // defaults filled in, secrets never included const hasKey = card.settings.hasSecret('apiKey') // true when the user saved one card.settings.onChange((snapshot) => { render(snapshot.values['command'], snapshot.secrets['apiKey']) }) // Change your own non-secret settings (a toggle in your UI, say). Validated like the form. await card.settings.set({ compact: true }) // Open the form on the card (only while it is visible). if (!hasKey) await card.settings.open() render(command, all)
ЧленЧто это
valuesТекущие значения, со значениями по умолчанию. Поддерживаются в актуальном виде.
secretsRecord<key, boolean>: какие секретные настройки заданы.
value(key)Одно значение, тип задаёте вы.
hasSecret(key)Задана ли секретная настройка.
get()Свежий SettingsSnapshot из приложения.
set(values)Меняет несекретные настройки; все копии карточки получают settings.changed. Неверные значения — INVALID_PARAMS. Не больше 60 в минуту.
open()Открывает форму настроек на карточке. NOT_VISIBLE, если карточки нет на экране.
onChange(handler)Пользователь сохранил форму, или set что-то поменял.

Области. У поля с "scope": "package" одно значение на все копии вашей карточки; остальные — свои у каждой карточки.

Секреты. Поле secret вводится только в собственном диалоге приложения — в форме настроек его строка показывает лишь «задан» или «не задан» и открывает этот диалог на всё окно, — и хранится приложением в зашифрованном виде. Карточка никогда не может его прочитать — ни через values, ни каким-либо методом. Чтобы им воспользоваться, вставьте {{secret:<key>}} в заголовок сетевого запроса; приложение подставит значение на выходе, и только для хостов в интернете, выданных вашей карточке (никогда для localhost). Не делайте внутри карточки собственное поле «вставьте ваш API-ключ»: тогда утечь ключ сможет уже по вашей вине, а пользователям сказано, что NeuroSquad никогда не спрашивает ключи внутри карточки.