Skip to main content

Storage Scoping

All installs of an extension share the extension's tables. Every row belongs to the account of the install that wrote it, and every read and write is limited to that account.

The instance scope​

instance is the only supported scope and the default. defineTable({...}) and defineTable({...}).storage("instance") mean the same thing:

// server/schema.ts
import { defineSchema, defineTable, v } from "@zaflun/lumio-sdk/server";

export default defineSchema({
points: defineTable({
user: v.string(),
score: v.number(),
}), // instance scope
});

.storage("overlay"), .storage("account") and .storage("global") are rejected at upload (422, INVALID_DATA_SCHEMA): no data is shared between accounts or overlays.

How scoping works​

Every table has a _account_id column. Lumio fills it from the install, never from your code:

  • queryRows / ctx.db.list only return rows of the install's account.
  • insertRow / ctx.db.insert set _account_id to the install's account.
  • get, patch and delete match _id and the account. A row of another account is not found, so another account's _id returns nothing and changes nothing.

You never filter by account yourself, and you cannot: _account_id is reserved.