pbvex
v0.5.1
Published
PBVex CLI and runtime authoring SDK
Downloads
218
Readme
pbvex
The PBVex CLI and TypeScript server-authoring package.
Install and initialize
npm install --global pbvex
npm install --save-dev pbvex
pbvex initKeep the global CLI and local pbvex dependency on the same version. The CLI
is global for direct command access; the local package provides the
pbvex/server, pbvex/values, and pbvex/component imports used by the app.
init creates pbvex/pbvex.config.ts, a schema, example functions, and
generated file placeholders. It minimally merges required scripts and
dependencies into an existing package.json, preserves an existing
tsconfig.json, and appends missing PBVex entries to .gitignore. It preflights
PBVex-owned scaffold paths and refuses to overwrite them; pbvex init --force
explicitly replaces only those managed scaffold files.
Commands
pbvex init: create a project scaffold.pbvex codegen: generatepbvex/_generated/{api,dataModel,server}.ts.pbvex migrations create <name> --table <table>: create a typed PBVex schema migration underpbvex/migrations/.pbvex migrations plan: compare the local candidate with the active deployment schema.pbvex migrations pocketbase create <name>: create a typed PocketBase migration underpbvex/pocketbaseMigrations/and generate matching PocketBase declarations.pbvex typecheck: regenerate types and runtsc --noEmit.pbvex build: write.pbvex/dist/artifact.jsonand build metadata.pbvex build --check: validate without writing deployment output.pbvex serve: run the backend bundled by@pbvex/server; the admin UI is disabled unless--admin-uiis passed.pbvex deploy: build, upload, and atomically activate a deployment.pbvex dev: for a loopback local target, start a persistent managed backend, perform the first deployment, then watchpbvex/**/*.ts, regenerate, and redeploy. Use--no-backendfor an externally managed server,--no-admin-uito omit the development dashboard, or--debugto include verbose PocketBase and SQL logs. PocketBase host migrations load at startup frompbvex/pocketbaseMigrations/;--pocketbaseMigrationsDiris an advanced explicit override.
pbvex init adds pbvex:dev, pbvex:serve, pbvex:deploy, and
pbvex:typecheck package scripts by default. Interactive runs prompt with yes
as the default; --no-scripts opts out.
PBVex and PocketBase migrations
First-class PBVex document migrations live in pbvex/migrations/*.ts and are
the default migration system for tables declared in pbvex/schema.ts:
pbvex migrations plan
pbvex migrations create add_account_status --table accountsThe generator scaffolds a typed defineMigration with object from/to
validators and required synchronous up/down handlers. Definitions target
one root PBVex table, are bundled into .pbvex/dist/artifact.json, and run
during atomic deployment activation. The handler context is pure and has no
database or side-effect APIs. Deployment rollback runs down in reverse order;
a failure in either direction leaves the current documents and active
deployment unchanged. Applied IDs are protected by checksums and schema hashes,
so never reuse or edit an applied migration ID.
Activation enforces fixed hard limits of 10,000 processed documents and 64 MiB
of encoded work and returns a structured warning at 80% utilization. There is
no force bypass or maintenance mode. pbvex migrations plan is structural
only: it reports schema changes and matching migration chains, not row/byte
estimates. Use --active-artifact <path> for a validated offline source.
Direct PocketBase host state uses the separate nested command
pbvex migrations pocketbase create <name> and
pbvex/pocketbaseMigrations/. Those JavaScript files run at backend startup,
are not bundled in the PBVex artifact, and are not reversed by PBVex deployment
rollback. Use host migrations for auth collections/rules, never for a table
owned by pbvex/schema.ts.
Configuration and credentials
pbvex/pbvex.config.ts is a JSON-like, side-effect-free module:
export default {
project: 'my-app',
defaultTarget: 'local',
targets: {
local: { url: 'http://127.0.0.1:8090', metadata: {} },
production: { url: 'https://app.example.com', metadata: {} },
},
};Deployment token resolution order is:
--token.PBVEX_<TARGET>_TOKEN.PBVEX_TOKEN..pbvex/credentials.jsonat<target>.token, then top-leveltoken.
For example:
{
"local": { "token": "..." },
"production": { "token": "..." }
}Deployment endpoints require a PocketBase superuser token. Application calls may be anonymous or carry an application auth-record token.
Authoring
import { mutation, query } from 'pbvex/server';
import { v } from 'pbvex/values';
export const list = query({
args: { channel: v.string() },
returns: v.array(v.string()),
handler: async (ctx, args) => {
const messages = await ctx.db
.query('messages')
.filter((q) => q.eq(q.field('channel'), args.channel))
.collect();
return messages.map((message) => message.body);
},
});
export const send = mutation({
args: { channel: v.string(), body: v.string() },
returns: v.id('messages'),
handler: async (ctx, args) => ctx.db.insert('messages', args),
});The package supports queries, mutations, actions, internal functions, HTTP actions, bounded outbound HTTP, database indexes and pagination, authentication, scheduling, storage with schema-declared image variants, and component definitions. Generated references distinguish public/internal visibility and whether arguments may be omitted.
Readable millisecond constants are available for one-shot scheduling:
import { DAY_MS, MINUTE_MS } from 'pbvex/server';
await ctx.scheduler.runAfter(5 * MINUTE_MS, internal.reminders.deliver, args);
await ctx.scheduler.runAfter(3 * DAY_MS, internal.trials.expire, args);Recurring jobs use PocketBase cron expressions in pbvex/crons.ts:
import { cronJobs } from 'pbvex/server';
import { internal } from './_generated/api';
const crons = cronJobs();
crons.cron('nightly-cleanup', '0 2 * * *', internal.maintenance.cleanup);
export default crons;Cron targets and arguments remain type-safe generated references. Each cron tick enqueues a durable PBVex scheduler job.
Component primitives are exported from pbvex/server for function modules and
from the dedicated pbvex/component subpath for tooling that only needs the
component definition types and builders.
Validators include v.string, v.number, v.float64, v.int64,
v.boolean, v.id, v.literal, v.object, v.array, v.record, v.union,
v.optional, v.defaulted, v.bytes, v.any, and v.null. v.delayed is a
construction-time helper and cannot be serialized into a deployable descriptor.
Imports and runtime boundary
Function modules may import:
pbvex/serverandpbvex/values;- relative TypeScript modules within the project.
Node built-ins, arbitrary npm packages, CommonJS require, dynamic imports,
and asset imports are rejected. Deployed functions execute inside the Go
binary's Goja sandbox, not a Node.js process.
Deployment artifact
.pbvex/dist/artifact.json is the exact DeploymentUploadRequest sent to
POST /api/pbvex/deployments:
{
"manifest": {
"protocolVersion": "v1",
"deploymentId": "...",
"functions": [],
"schema": { "tables": [] }
},
"bundle": "<base64 executable JavaScript>",
"sha256": "<lowercase SHA-256>",
"size": 1234
}After upload, the CLI calls
POST /api/pbvex/deployments/{id}/activate with { "atomic": true }.
